hyena-0.5/0000777000175000001440000000000011453151002012573 5ustar00gabeusers00000000000000hyena-0.5/Hyena/0000777000175000001440000000000011453151002013637 5ustar00gabeusers00000000000000hyena-0.5/Hyena/Hyena/0000777000175000001440000000000011453151002014703 5ustar00gabeusers00000000000000hyena-0.5/Hyena/Hyena/UndoManager.cs0000644000175000001440000000772011377105342017447 0ustar00gabeusers00000000000000// // UndoManager.cs // // Author: // Aaron Bockover // // Copyright (C) 2007 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Collections.Generic; namespace Hyena { public class UndoManager { private Stack undo_stack = new Stack(); private Stack redo_stack = new Stack(); private int frozen_count; private bool try_merge; public event EventHandler UndoChanged; public void Undo() { lock(this) { UndoRedo(undo_stack, redo_stack, true); } } public void Redo() { lock(this) { UndoRedo(redo_stack, undo_stack, false); } } public void Clear() { lock(this) { frozen_count = 0; try_merge = false; undo_stack.Clear(); redo_stack.Clear(); OnUndoChanged(); } } public void AddUndoAction(IUndoAction action) { lock(this) { if(frozen_count != 0) { return; } if(try_merge && undo_stack.Count > 0) { IUndoAction top = undo_stack.Peek(); if(top.CanMerge(action)) { top.Merge(action); return; } } undo_stack.Push(action); redo_stack.Clear(); try_merge = true; OnUndoChanged(); } } protected virtual void OnUndoChanged() { EventHandler handler = UndoChanged; if(handler != null) { handler(this, EventArgs.Empty); } } private void UndoRedo(Stack pop_from, Stack push_to, bool is_undo) { if(pop_from.Count == 0) { return; } IUndoAction action = pop_from.Pop(); frozen_count++; if(is_undo) { action.Undo(); } else { action.Redo(); } frozen_count--; push_to.Push(action); try_merge = true; OnUndoChanged(); } public bool CanUndo { get { return undo_stack.Count > 0; } } public bool CanRedo { get { return redo_stack.Count > 0; } } public IUndoAction UndoAction { get { lock (this) { return CanUndo ? undo_stack.Peek () : null; } } } public IUndoAction RedoAction { get { lock (this) { return CanRedo ? redo_stack.Peek () : null; } } } } } hyena-0.5/Hyena/Hyena/Paths.cs0000644000175000001440000002101411436010324016305 0ustar00gabeusers00000000000000// // Paths.cs // // Author: // Aaron Bockover // Ruben Vermeersch // // Copyright (C) 2005-2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System.IO; using System; using System.Text; namespace Hyena { public class Paths { public static string GetTempFileName (string dir) { return GetTempFileName (dir, null); } public static string GetTempFileName (string dir, string extension) { return GetTempFileName (new DirectoryInfo (dir), extension); } public static string GetTempFileName (DirectoryInfo dir, string extension) { string path = null; if (dir == null || !dir.Exists) { throw new DirectoryNotFoundException (); } do { string guid = Guid.NewGuid ().ToString (); string file = extension == null ? guid : String.Format ("{0}.{1}", guid, extension); path = Path.Combine (dir.FullName, file); } while (File.Exists (path)); return path; } public static string Combine (string first, params string [] components) { if (String.IsNullOrEmpty (first)) { throw new ArgumentException ("First component must not be null or empty", "first"); } else if (components == null || components.Length < 1) { throw new ArgumentException ("One or more path components must be provided", "components"); } string result = first; foreach (string component in components) { result = Path.Combine (result, component); } return result; } public static string FindProgramInPath (string command) { foreach (string path in GetExecPaths ()) { string full_path = Path.Combine (path, command); try { FileInfo info = new FileInfo (full_path); // FIXME: System.IO is super lame, should check for 0755 if (info.Exists) { return full_path; } } catch { } } return null; } private static string [] GetExecPaths () { string path = Environment.GetEnvironmentVariable ("PATH"); if (String.IsNullOrEmpty (path)) { return new string [] { "/bin", "/usr/bin", "/usr/local/bin" }; } // this is super lame, should handle quoting/escaping return path.Split (':'); } public static string MakePathRelative (string path, string to) { if (String.IsNullOrEmpty (path) || String.IsNullOrEmpty (to)) { return null; } if (Path.IsPathRooted (path) ^ Path.IsPathRooted (to)) { // one path is absolute, one path is relative, impossible to compare return null; } if (path == to) { return String.Empty; } if (to[to.Length - 1] != Path.DirectorySeparatorChar) { to = to + Path.DirectorySeparatorChar; } if (path.StartsWith (to)) { return path.Substring (to.Length); } return BuildRelativePath (path, to); } private static string BuildRelativePath (string path, string to) { var toParts = to.Split (Path.DirectorySeparatorChar); var pathParts = path.Split (Path.DirectorySeparatorChar); var i = 0; while (i < toParts.Length && i < pathParts.Length && toParts [i] == pathParts [i]) { i++; } var relativePath = new StringBuilder (); for (int j = 0; j < toParts.Length - i - 1; j++) { relativePath.Append (".."); relativePath.Append (Path.DirectorySeparatorChar); } var required = new string [pathParts.Length - i]; for (int j = i; j < pathParts.Length; j++) { required [j - i] = pathParts [j]; } relativePath.Append (String.Join (Path.DirectorySeparatorChar.ToString (), required)); return relativePath.ToString (); } public static string ApplicationData { get; private set; } public static string ApplicationCache { get; private set; } private static string application_name = null; public static string ApplicationName { get { if (application_name == null) { throw new ApplicationException ("Paths.ApplicationName must be set first"); } return application_name; } set { application_name = value; InitializePaths (); } } // This can only happen after ApplicationName is set. private static void InitializePaths () { ApplicationCache = Path.Combine (XdgBaseDirectorySpec.GetUserDirectory ( "XDG_CACHE_HOME", ".cache"), ApplicationName); ApplicationData = Path.Combine (Environment.GetFolderPath ( Environment.SpecialFolder.ApplicationData), ApplicationName); if (!Directory.Exists (ApplicationData)) { Directory.CreateDirectory (ApplicationData); } } public static string ExtensionCacheRoot { get { return Path.Combine (ApplicationCache, "extensions"); } } public static string SystemTempDir { get { return "/tmp/"; } } public static string TempDir { get { string dir = Path.Combine (ApplicationCache, "temp"); if (File.Exists (dir)) { File.Delete (dir); } Directory.CreateDirectory (dir); return dir; } } private static string installed_application_prefix = null; public static string InstalledApplicationPrefix { get { if (installed_application_prefix == null) { installed_application_prefix = Path.GetDirectoryName ( System.Reflection.Assembly.GetExecutingAssembly ().Location); if (Directory.Exists (Paths.Combine (installed_application_prefix, "share", ApplicationName))) { return installed_application_prefix; } DirectoryInfo entry_directory = new DirectoryInfo (installed_application_prefix); if (entry_directory != null && entry_directory.Parent != null && entry_directory.Parent.Parent != null) { installed_application_prefix = entry_directory.Parent.Parent.FullName; } } return installed_application_prefix; } } public static string InstalledApplicationDataRoot { get { return Path.Combine (InstalledApplicationPrefix, "share"); } } public static string InstalledApplicationData { get { return Path.Combine (InstalledApplicationDataRoot, ApplicationName); } } public static string GetInstalledDataDirectory (string path) { return Path.Combine (InstalledApplicationData, path); } } } hyena-0.5/Hyena/Hyena/CryptoUtil.cs0000644000175000001440000000526011406252637017365 0ustar00gabeusers00000000000000// // CryptoUtil.cs // // Author: // Aaron Bockover // // Copyright (C) 2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.IO; using System.Text; using System.Text.RegularExpressions; using System.Security.Cryptography; namespace Hyena { public static class CryptoUtil { // A-Z is ignored on purpose private static Regex md5_regex = new Regex ("^[a-f0-9]{32}$", RegexOptions.Compiled); private static MD5 md5 = MD5.Create (); public static bool IsMd5Encoded (string text) { return text == null || text.Length != 32 ? false : md5_regex.IsMatch (text); } public static string Md5Encode (string text) { return Md5Encode (text, Encoding.ASCII); } public static string Md5Encode (string text, Encoding encoding) { if (String.IsNullOrEmpty (text)) { return String.Empty; } byte [] hash; lock (md5) { hash = md5.ComputeHash (encoding.GetBytes (text)); } return ToHex (hash); } public static string Md5EncodeStream (Stream stream) { byte [] hash; lock (md5) { hash = md5.ComputeHash (stream); } return ToHex (hash); } private static string ToHex (byte [] hash) { StringBuilder shash = new StringBuilder (); for (int i = 0; i < hash.Length; i++) { shash.Append (hash[i].ToString ("x2")); } return shash.ToString (); } } } hyena-0.5/Hyena/Hyena/Tests/0000777000175000001440000000000011453151002016005 5ustar00gabeusers00000000000000hyena-0.5/Hyena/Hyena/Tests/TestBase.cs0000644000175000001440000000671011377105342020061 0ustar00gabeusers00000000000000// // BansheeTests.cs // // Author: // Gabriel Burt // // Copyright (C) 2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // #if ENABLE_TESTS using System; using System.IO; using System.Collections.Generic; using System.Reflection; using System.Threading; using NUnit.Framework; using Hyena; namespace Hyena.Tests { public struct TransformPair { public F From; public T To; public TransformPair (F from, T to) { From = from; To = to; } public static TransformPair [] GetFrom (params object [] objects) { TransformPair [] pairs = new TransformPair [objects.Length / 2]; for (int i = 0; i < objects.Length; i += 2) { pairs[i/2] = new TransformPair ((F)objects[i], (T)objects[i+1]); } return pairs; } public override string ToString () { return From.ToString (); } } public delegate To Transform (F from); public abstract class TestBase { private static string bin_dir; public static string BinDir { get { return bin_dir ?? (bin_dir = Path.GetDirectoryName (Assembly.GetExecutingAssembly ().Location)); } } private static string tests_dir; public static string TestsDir { get { return tests_dir ?? (tests_dir = Path.Combine (Path.GetDirectoryName (BinDir), "tests")); } } public static void AssertForEach (IEnumerable objects, Action runner) { System.Text.StringBuilder sb = new System.Text.StringBuilder (); foreach (T o in objects) { try { runner (o); } catch (AssertionException e) { sb.AppendFormat ("Failed assertion on {0}: {1}\n", o, e.Message); } catch (Exception e) { sb.AppendFormat ("\nCaught exception on {0}: {1}\n", o, e.ToString ()); } } if (sb.Length > 0) Assert.Fail ("\n" + sb.ToString ()); } // Fails to compile, causes SIGABRT in gmcs; boo /*public static void AssertTransformsEach (IEnumerable> pairs, Transform transform) { AssertForEach (pairs, delegate (TransformPair pair) { Assert.AreEqual (pair.To, transform (pair.From)); }); }*/ } } #endif hyena-0.5/Hyena/Hyena/Tests/DateTimeUtilTests.cs0000644000175000001440000000557211377105342021731 0ustar00gabeusers00000000000000// // DateTimeUtilTests.cs // // Author: // Gabriel Burt // // Copyright (c) 2010 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #if ENABLE_TESTS using System; using NUnit.Framework; using Hyena; namespace Hyena.Tests { [TestFixture] public class DateTimeUtilTests { [Test] public void InvariantString () { // Tests are run in Chicago timezone, UTC -6 in the winter, -5 in the summer TestInv ("2010-02-18 02:41:00.000 -06:00", new DateTime (2010, 2, 18, 2, 41, 0, 0)); TestInv ("2010-02-18 02:41:50.123 -06:00", new DateTime (2010, 2, 18, 2, 41, 50, 123)); TestInv ("2010-10-18 02:01:00.000 -05:00", new DateTime (2010, 10, 18, 2, 1, 0, 0)); } private void TestInv (string inv_string, DateTime dt) { // Make sure we can generate the given string from the DateTime Assert.AreEqual (inv_string, DateTimeUtil.ToInvariantString (dt)); // And vice versa DateTime parsed_dt; if (DateTimeUtil.TryParseInvariant (inv_string, out parsed_dt)) Assert.AreEqual (dt, parsed_dt); else Assert.Fail (String.Format ("TryParseInvariant failed on {0}", inv_string)); } [Test] public void FromToSymmetry () { // ToTimeT only has precision to the second; so strip off the remainding ticks DateTime now = DateTime.Now; now = now.Subtract (TimeSpan.FromTicks (now.Ticks % TimeSpan.TicksPerSecond)); long time_t = DateTimeUtil.ToTimeT (now); DateTime now_t = DateTimeUtil.FromTimeT (time_t); Assert.AreEqual (DateTimeKind.Local, now.Kind); Assert.AreEqual (DateTimeKind.Local, now_t.Kind); Assert.AreEqual (now, now_t); } } } #endif hyena-0.5/Hyena/Hyena/Tests/CryptoUtilTests.cs0000644000175000001440000000572111406252637021514 0ustar00gabeusers00000000000000// // CryptoUtilTests.cs // // Author: // Aaron Bockover // // Copyright (C) 2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // #if ENABLE_TESTS using System; using System.IO; using NUnit.Framework; using Hyena; namespace Hyena.Tests { [TestFixture] public class CryptoUtilTests { [Test] public void Md5Encode () { Assert.AreEqual ("ae2b1fca515949e5d54fb22b8ed95575", CryptoUtil.Md5Encode ("testing")); Assert.AreEqual ("", CryptoUtil.Md5Encode (null)); Assert.AreEqual ("", CryptoUtil.Md5Encode ("")); } [Test] public void IsMd5Encoded () { Assert.IsTrue (CryptoUtil.IsMd5Encoded ("ae2b1fca515949e5d54fb22b8ed95575")); Assert.IsFalse (CryptoUtil.IsMd5Encoded ("abc233")); Assert.IsFalse (CryptoUtil.IsMd5Encoded ("lebowski")); Assert.IsFalse (CryptoUtil.IsMd5Encoded ("ae2b1fca515949e5g54fb22b8ed95575")); Assert.IsFalse (CryptoUtil.IsMd5Encoded (null)); Assert.IsFalse (CryptoUtil.IsMd5Encoded ("")); } [Test] public void Md5EncodeStream () { var file = Path.GetTempFileName (); var tw = new StreamWriter (file); tw.Write ("testing"); tw.Close (); var stream = new FileStream (file, FileMode.Open); Assert.AreEqual ("ae2b1fca515949e5d54fb22b8ed95575", CryptoUtil.Md5EncodeStream (stream)); stream.Close (); File.Delete (file); } /*[Test] public void Md5Performance () { int max = 10000; using (new Timer (String.Format ("Computed {0} MD5 hashes", max))) { for (int i = 0; i < max; i++) { CryptoUtil.Md5Encode ("LkaJSd Flkjdf234234lkj3WlkejewrVlkdf @343434 dsfjk 3497u34 l 2008 lkjdf"); } } }*/ } } #endif hyena-0.5/Hyena/Hyena/Tests/StringUtilTests.cs0000644000175000001440000003550311436010340021465 0ustar00gabeusers00000000000000// // StringUtilTests.cs // // Author: // Aaron Bockover // Gabriel Burt // // Copyright (C) 2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // #if ENABLE_TESTS using System; using System.IO; using System.Linq; using NUnit.Framework; using Hyena; namespace Hyena.Tests { [TestFixture] public class StringUtilTests { private class Map { public Map (string camel, string under) { Camel = camel; Under = under; } public string Camel; public string Under; } private Map [] u_to_c_maps = new Map [] { new Map ("Hello", "hello"), new Map ("HelloWorld", "hello_world"), new Map ("HelloWorld", "hello__world"), new Map ("HelloWorld", "hello___world"), new Map ("HelloWorld", "hello____world"), new Map ("HelloWorld", "_hello_world"), new Map ("HelloWorld", "__hello__world"), new Map ("HelloWorld", "___hello_world_"), new Map ("HelloWorldHowAreYou", "_hello_World_HOW_ARE__YOU__"), new Map (null, ""), new Map ("H", "h") }; [Test] public void UnderCaseToCamelCase () { foreach (Map map in u_to_c_maps) { Assert.AreEqual (map.Camel, StringUtil.UnderCaseToCamelCase (map.Under)); } } private Map [] c_to_u_maps = new Map [] { new Map ("Hello", "hello"), new Map ("HelloWorld", "hello_world"), new Map ("HiWorldHowAreYouDoingToday", "hi_world_how_are_you_doing_today"), new Map ("SRSLYHowAreYou", "srsly_how_are_you"), new Map ("OMGThisShitIsBananas", "omg_this_shit_is_bananas"), new Map ("KTHXBAI", "kthxbai"), new Map ("nereid.track_view_columns.MusicLibrarySource-Library/composer", "nereid.track_view_columns._music_library_source_-_library/composer"), new Map ("", null), new Map ("H", "h") }; [Test] public void CamelCaseToUnderCase () { foreach (Map map in c_to_u_maps) { Assert.AreEqual (map.Under, StringUtil.CamelCaseToUnderCase (map.Camel)); } } [Test] public void DoubleToTenthsPrecision () { // Note we are testing with locale = it_IT, hence the commas Assert.AreEqual ("15", StringUtil.DoubleToTenthsPrecision (15.0)); Assert.AreEqual ("15", StringUtil.DoubleToTenthsPrecision (15.0334)); Assert.AreEqual ("15,1", StringUtil.DoubleToTenthsPrecision (15.052)); Assert.AreEqual ("15,5", StringUtil.DoubleToTenthsPrecision (15.5234)); Assert.AreEqual ("15", StringUtil.DoubleToTenthsPrecision (14.9734)); Assert.AreEqual ("14,9", StringUtil.DoubleToTenthsPrecision (14.92)); Assert.AreEqual ("0,4", StringUtil.DoubleToTenthsPrecision (0.421)); Assert.AreEqual ("0", StringUtil.DoubleToTenthsPrecision (0.01)); Assert.AreEqual ("1.000,3", StringUtil.DoubleToTenthsPrecision (1000.32)); Assert.AreEqual ("9.233", StringUtil.DoubleToTenthsPrecision (9233)); } [Test] public void DoubleToPluralInt () { // This method helps us pluralize doubles. Probably a horrible i18n idea. Assert.AreEqual (0, StringUtil.DoubleToPluralInt (0)); Assert.AreEqual (1, StringUtil.DoubleToPluralInt (1)); Assert.AreEqual (2, StringUtil.DoubleToPluralInt (2)); Assert.AreEqual (1, StringUtil.DoubleToPluralInt (0.5)); Assert.AreEqual (2, StringUtil.DoubleToPluralInt (1.8)); Assert.AreEqual (22, StringUtil.DoubleToPluralInt (21.3)); } [Test] public void RemovesNewlines () { Assert.AreEqual ("", StringUtil.RemoveNewlines ("")); Assert.AreEqual (null, StringUtil.RemoveNewlines (null)); Assert.AreEqual ("foobar", StringUtil.RemoveNewlines (@"foo bar")); Assert.AreEqual ("foobar baz", StringUtil.RemoveNewlines ("foo\nbar \nbaz")); Assert.AreEqual ("haswindows newline andunix", StringUtil.RemoveNewlines ("has\nwindows\r\n newline \nandunix")); } [Test] public void RemovesHtml () { Assert.AreEqual ("", StringUtil.RemoveHtml ("")); Assert.AreEqual (null, StringUtil.RemoveHtml (null)); Assert.AreEqual ("foobar", StringUtil.RemoveHtml ("foobar")); Assert.AreEqual ("foobar", StringUtil.RemoveHtml ("foobar")); Assert.AreEqual ("foobar", StringUtil.RemoveHtml ("foobar")); Assert.AreEqual ("foobar", StringUtil.RemoveHtml ("foobar")); Assert.AreEqual ("foobazbar", StringUtil.RemoveHtml ("foobazbar")); Assert.AreEqual ("foobaz foo bar", StringUtil.RemoveHtml (@"foobaz foo< /a> bar")); } [Test] public void TestJoin () { var s = new string [] { "foo", "bar" }; Assert.AreEqual ("foo, bar", s.Join (", ")); Assert.AreEqual ("foobar", s.Join ("")); Assert.AreEqual ("foobar", s.Join (null)); Assert.AreEqual ("", new string [] {}.Join (", ")); s = new string [] { "foo", "bar", "baz" }; Assert.AreEqual ("foo -- bar -- baz", s.Join (" -- ")); } [Test] public void TestSubstringBetween () { Assert.AreEqual ("bar", "foobarbaz".SubstringBetween ("foo", "baz")); Assert.AreEqual ("barfoobam", "erefoobarfoobambazabc".SubstringBetween ("foo", "baz")); Assert.AreEqual (null, "foobar".SubstringBetween ("foo", "baz")); Assert.AreEqual (null, "bar".SubstringBetween ("foo", "baz")); Assert.AreEqual (null, "".SubstringBetween ("foo", "baz")); } } [TestFixture] public class SearchKeyTests { private void AssertSearchKey (string before, string after) { Assert.AreEqual (after, StringUtil.SearchKey (before)); } [Test] public void TestEmpty () { AssertSearchKey ("", ""); AssertSearchKey (null, null); } // Test that resulting search keys are in lower-case [Test] public void TestLowercase () { AssertSearchKey ("A", "a"); AssertSearchKey ("\u0104", "a"); } // Test that combining diacritics are removed from Latin characters. [Test] public void TestRemoveDiacritics () { AssertSearchKey ("\u00e9", "e"); AssertSearchKey ("e\u0301", "e"); AssertSearchKey ("\u014d", "o"); AssertSearchKey ("o\u0304", "o"); AssertSearchKey ("Español", "espanol"); AssertSearchKey ("30 años de la revolución iraní", "30 anos de la revolucion irani"); AssertSearchKey ("FRANCÉS", "frances"); // Polish letters AssertSearchKey ("ą", "a"); AssertSearchKey ("Ą", "a"); AssertSearchKey ("ć", "c"); AssertSearchKey ("Ć", "c"); AssertSearchKey ("ę", "e"); AssertSearchKey ("Ę", "e"); AssertSearchKey ("ł", "l"); AssertSearchKey ("Ł", "l"); AssertSearchKey ("ń", "n"); AssertSearchKey ("Ń", "n"); AssertSearchKey ("ó", "o"); AssertSearchKey ("Ó", "o"); AssertSearchKey ("ś", "s"); AssertSearchKey ("Ś", "s"); AssertSearchKey ("ź", "z"); AssertSearchKey ("Ź", "z"); AssertSearchKey ("ż", "z"); AssertSearchKey ("Ż", "z"); // Hiragana AssertSearchKey ("\u304c", "\u304b"); // Cyrillic AssertSearchKey ("\u0451", "\u0435"); AssertSearchKey ("\u0401", "\u0435"); AssertSearchKey ("\u0439", "\u0438"); AssertSearchKey ("\u0419", "\u0438"); } // Test that some non-Latin characters are converted to Latin counterparts. [Test] public void TestEquivalents () { AssertSearchKey ("\u00f8", "o"); AssertSearchKey ("\u0142", "l"); } // Test that some kinds of punctuation are removed. [Test] public void TestRemovePunctuation () { AssertSearchKey ("'", ""); AssertSearchKey ("\"", ""); AssertSearchKey ("!", ""); AssertSearchKey ("?", ""); AssertSearchKey ("/", ""); } [Test] // http://bugzilla.gnome.org/show_bug.cgi?id=573484 public void TestCollapseSpaces () { AssertSearchKey (" a \t b ", "a b"); AssertSearchKey ("100 % techno", "100 techno"); // Character in the set of special overrides AssertSearchKey ("a \u00f8", "a o"); // Invalid combining character AssertSearchKey ("a \u0301", "a"); } } [TestFixture] public class EscapeFilenameTests { private void AssertProduces (string input, string output) { Assert.AreEqual (output, StringUtil.EscapeFilename (input)); } private void AssertProducesSame (string input) { AssertProduces (input, input); } [Test] public void TestEmpty () { AssertProduces (null, ""); AssertProduces ("", ""); AssertProduces (" ", ""); AssertProduces (" ", ""); } [Test] public void TestNotChanged () { AssertProducesSame ("a"); AssertProducesSame ("aaa"); AssertProducesSame ("Foo Bar"); AssertProducesSame ("03-Nur geträumt"); AssertProducesSame ("你好"); AssertProducesSame ("nǐ hǎo"); } [Test] public void TestStripped () { AssertProduces ("Foo*bar", "Foo_bar"); AssertProduces ("", "_foo_bar_"); AssertProduces ("", "_"); AssertProduces ("Greetings! -* 你好?", "Greetings! -_ 你好_"); } } [TestFixture] public class SortKeyTests { private void AssertSortKey (string before, object after) { Assert.AreEqual (after, StringUtil.SortKey (before)); } [Test] public void TestNull () { AssertSortKey (null, null); } [Test] public void TestEmpty () { AssertSortKey ("", new byte[] {1, 1, 1, 1, 0}); } [Test] public void TestSortKey () { AssertSortKey ("a", new byte[] {14, 2, 1, 1, 1, 1, 0}); AssertSortKey ("A", new byte[] {14, 2, 1, 1, 1, 1, 0}); AssertSortKey ("\u0104", new byte[] {14, 2, 1, 27, 1, 1, 1, 0,}); } } [TestFixture] public class EscapePathTests { private readonly char dir_sep = Path.DirectorySeparatorChar; private void AssertProduces (string input, string output) { Assert.AreEqual (output, StringUtil.EscapePath (input)); } private void AssertProducesSame (string input) { AssertProduces (input, input); } [Test] public void TestEmpty () { AssertProduces (null, ""); AssertProduces ("", ""); AssertProduces (" ", ""); AssertProduces (" ", ""); } [Test] public void TestNotChanged () { AssertProducesSame ("a"); AssertProducesSame ("aaa"); AssertProducesSame ("Foo Bar"); AssertProducesSame ("03-Nur geträumt"); AssertProducesSame ("превед"); AssertProducesSame ("nǐ hǎo"); AssertProducesSame (String.Format ("a{0}b.ogg", dir_sep)); AssertProducesSame (String.Format ("foo{0}bar{0}01. baz.ogg", dir_sep)); AssertProducesSame (String.Format ("{0}foo*?:", dir_sep)); // rooted, shouldn't change } [Test] public void TestStripped () { AssertProduces ( String.Format ("foo*bar{0}ham:spam.ogg", dir_sep), String.Format ("foo_bar{0}ham_spam.ogg", dir_sep)); AssertProduces ( String.Format ("..lots..{0}o.f.{0}.dots.ogg.", dir_sep), String.Format ("lots{0}o.f{0}dots.ogg", dir_sep)); AssertProduces ( String.Format ("foo{0}..{0}bar.ogg", dir_sep), String.Format ("foo{0}bar.ogg", dir_sep)); AssertProduces ( String.Format (". foo{0}01. bar.ogg. ", dir_sep), String.Format ("foo{0}01. bar.ogg", dir_sep)); } } [TestFixture] public class SubstringCountTests { private void AssertCount (string haystack, string needle, uint expected) { Assert.AreEqual (expected, StringUtil.SubstringCount (haystack, needle)); } [Test] public void TestEmpty () { AssertCount ("", "a", 0); AssertCount ("a", "", 0); } [Test] public void TestNoMatches () { AssertCount ("a", "b", 0); AssertCount ("with needle in", "long needle", 0); } [Test] public void TestMatches () { AssertCount ("abbcbba", "a", 2); AssertCount ("abbcbba", "b", 4); AssertCount ("with needle in", "needle", 1); } } } #endif hyena-0.5/Hyena/Hyena/IUndoAction.cs0000644000175000001440000000256511377105342017425 0ustar00gabeusers00000000000000// // IUndoAction.cs // // Author: // Aaron Bockover // // Copyright (C) 2007-2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // namespace Hyena { public interface IUndoAction { void Undo (); void Redo (); void Merge (IUndoAction action); bool CanMerge (IUndoAction action); } } hyena-0.5/Hyena/Hyena/PlatformDetection.cs0000644000175000001440000000653011377105342020670 0ustar00gabeusers00000000000000// // PlatformUtil.cs // // Author: // Aaron Bockover // // Copyright 2010 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Runtime.InteropServices; namespace Hyena { public static class PlatformDetection { public static readonly bool IsMac; public static readonly bool IsWindows; public static readonly bool IsLinux; public static readonly bool IsUnix; public static readonly bool IsMeeGo; public static readonly string PosixSystemName; public static readonly string SystemName; [DllImport ("libc")] private static extern int uname (IntPtr utsname); static PlatformDetection () { // From http://www.mono-project.com/FAQ:_Technical int p = (int)Environment.OSVersion.Platform; IsUnix = p == 4 || p == 6 || p == 128; IsWindows = p < 4; if (IsWindows) { SystemName = "Windows"; return; } // uname expects a pointer to a utsname structure, but we are // tricky here - this structure's first field is the field we // care about (char sysname []); the size of the structure is // unknown, as it varies on all platforms. Darwin uses only // the five POSIX fields, each 256 bytes, so the total size is // total size is 5 * 256 = 1280 bytes. Arbitrarily using 8192. var utsname = IntPtr.Zero; try { utsname = Marshal.AllocHGlobal (8192); if (uname (utsname) == 0) { PosixSystemName = Marshal.PtrToStringAnsi (utsname); } } catch { } finally { if (utsname != IntPtr.Zero) { Marshal.FreeHGlobal (utsname); } } if (PosixSystemName == null) { if (IsUnix) { SystemName = "Unix"; } return; } switch (PosixSystemName) { case "Darwin": IsMac = true; break; case "Linux": IsLinux = true; break; } SystemName = PosixSystemName; IsMeeGo = System.IO.File.Exists ("/etc/meego-release"); } } } hyena-0.5/Hyena/Hyena/SafeUri.cs0000644000175000001440000001466711430346046016613 0ustar00gabeusers00000000000000/*************************************************************************** * SafeUri.cs * * Copyright (C) 2006 Novell, Inc. * Written by Aaron Bockover ****************************************************************************/ /* THIS FILE IS LICENSED UNDER THE MIT LICENSE AS OUTLINED IMMEDIATELY BELOW: * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ using System; using System.Runtime.InteropServices; namespace Hyena { public class SafeUri { private enum LocalPathCheck { NotPerformed, Yes, No } private static int MAX_SCHEME_LENGTH = 8; private string uri; private string local_path; private string scheme; private LocalPathCheck local_path_check = LocalPathCheck.NotPerformed; public SafeUri (string uri) { int scheme_delimit_index = uri.IndexOf ("://"); if (scheme_delimit_index > 0 && scheme_delimit_index <= MAX_SCHEME_LENGTH) { this.uri = uri; } else { this.uri = FilenameToUri (uri); } } public SafeUri (string uri, bool isUri) { if (isUri) { this.uri = uri; } else { this.uri = FilenameToUri (uri); } } public SafeUri (Uri uri) { this.uri = uri.AbsoluteUri; } public static string FilenameToUri (string localPath) { // TODO: replace with managed conversion to avoid marshalling IntPtr path_ptr = GLib.Marshaller.StringToPtrGStrdup (localPath); #if WIN32 IntPtr uri_ptr = g_filename_to_uri_utf8 (path_ptr, IntPtr.Zero, IntPtr.Zero); #else IntPtr uri_ptr = g_filename_to_uri (path_ptr, IntPtr.Zero, IntPtr.Zero); #endif GLib.Marshaller.Free (path_ptr); if (uri_ptr == IntPtr.Zero) { throw new ApplicationException ("Filename path must be absolute"); } string uri = GLib.Marshaller.Utf8PtrToString (uri_ptr); GLib.Marshaller.Free (uri_ptr); return uri; } public static string UriToFilename (string uri) { // TODO: replace with managed conversion to avoid marshalling IntPtr uri_ptr = GLib.Marshaller.StringToPtrGStrdup (uri); #if WIN32 IntPtr path_ptr = g_filename_from_uri_utf8 (uri_ptr, IntPtr.Zero, IntPtr.Zero); #else IntPtr path_ptr = g_filename_from_uri (uri_ptr, IntPtr.Zero, IntPtr.Zero); #endif GLib.Marshaller.Free (uri_ptr); if (path_ptr == IntPtr.Zero) { throw new ApplicationException ("URI could not be converted to local file location"); } string path = GLib.Marshaller.Utf8PtrToString (path_ptr); GLib.Marshaller.Free (path_ptr); return path; } public static string UriToFilename (SafeUri uri) { return UriToFilename (uri.AbsoluteUri); } public override string ToString () { return AbsoluteUri; } public static implicit operator string (SafeUri s) { return s.ToString (); } public override bool Equals (object o) { SafeUri s = o as SafeUri; if (s != null) { return s.AbsoluteUri == AbsoluteUri; } return false; } public override int GetHashCode () { return AbsoluteUri.GetHashCode (); } public string AbsoluteUri { get { return uri; } } public bool IsLocalPath { get { if (local_path_check == LocalPathCheck.NotPerformed) { if (IsFile) { local_path_check = LocalPathCheck.Yes; return true; } else { local_path_check = LocalPathCheck.No; return false; } } return local_path_check == LocalPathCheck.Yes; } } public string AbsolutePath { get { if (local_path == null && IsLocalPath) { local_path = UriToFilename (uri); } return local_path; } } public string LocalPath { get { return AbsolutePath; } } public string Scheme { get { if (scheme == null) { scheme = uri.Substring (0, uri.IndexOf ("://")); } return scheme; } } public bool IsFile { get { return Scheme == System.Uri.UriSchemeFile; } } #if WIN32 [DllImport ("libglib-2.0-0.dll")] private static extern IntPtr g_filename_to_uri_utf8 (IntPtr filename, IntPtr hostname, IntPtr error); [DllImport ("libglib-2.0-0.dll")] private static extern IntPtr g_filename_from_uri_utf8 (IntPtr uri, IntPtr hostname, IntPtr error); #else [DllImport ("libglib-2.0-0.dll")] private static extern IntPtr g_filename_to_uri (IntPtr filename, IntPtr hostname, IntPtr error); [DllImport ("libglib-2.0-0.dll")] private static extern IntPtr g_filename_from_uri (IntPtr uri, IntPtr hostname, IntPtr error); #endif } } hyena-0.5/Hyena/Hyena/StringUtil.cs0000644000175000001440000003205411436010340017336 0ustar00gabeusers00000000000000// // StringUtil.cs // // Author: // Aaron Bockover // // Copyright (C) 2006-2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Collections.Generic; using System.IO; using System.Text; using System.Globalization; using System.Text.RegularExpressions; namespace Hyena { public static class StringUtil { private static CompareOptions compare_options = CompareOptions.IgnoreCase | CompareOptions.IgnoreNonSpace | CompareOptions.IgnoreKanaType | CompareOptions.IgnoreWidth; public static int RelaxedIndexOf (string haystack, string needle) { return CultureInfo.CurrentCulture.CompareInfo.IndexOf (haystack, needle, compare_options); } public static int RelaxedCompare (string a, string b) { if (a == null && b == null) { return 0; } else if (a != null && b == null) { return 1; } else if (a == null && b != null) { return -1; } int a_offset = a.StartsWith ("the ") ? 4 : 0; int b_offset = b.StartsWith ("the ") ? 4 : 0; return CultureInfo.CurrentCulture.CompareInfo.Compare (a, a_offset, a.Length - a_offset, b, b_offset, b.Length - b_offset, compare_options); } public static string CamelCaseToUnderCase (string s) { return CamelCaseToUnderCase (s, '_'); } private static Regex camelcase = new Regex ("([A-Z]{1}[a-z]+)", RegexOptions.Compiled); public static string CamelCaseToUnderCase (string s, char underscore) { if (String.IsNullOrEmpty (s)) { return null; } StringBuilder undercase = new StringBuilder (); string [] tokens = camelcase.Split (s); for (int i = 0; i < tokens.Length; i++) { if (tokens[i] == String.Empty) { continue; } undercase.Append (tokens[i].ToLower (System.Globalization.CultureInfo.InvariantCulture)); if (i < tokens.Length - 2) { undercase.Append (underscore); } } return undercase.ToString (); } public static string UnderCaseToCamelCase (string s) { if (String.IsNullOrEmpty (s)) { return null; } StringBuilder builder = new StringBuilder (); for (int i = 0, n = s.Length, b = -1; i < n; i++) { if (b < 0 && s[i] != '_') { builder.Append (Char.ToUpper (s[i])); b = i; } else if (s[i] == '_' && i + 1 < n && s[i + 1] != '_') { if (builder.Length > 0 && Char.IsUpper (builder[builder.Length - 1])) { builder.Append (Char.ToLower (s[i + 1])); } else { builder.Append (Char.ToUpper (s[i + 1])); } i++; b = i; } else if (s[i] != '_') { builder.Append (Char.ToLower (s[i])); b = i; } } return builder.ToString (); } public static string RemoveNewlines (string input) { if (input != null) { return input.Replace ("\r\n", String.Empty).Replace ("\n", String.Empty); } return null; } private static Regex tags = new Regex ("<[^>]+>", RegexOptions.Compiled | RegexOptions.Multiline); public static string RemoveHtml (string input) { if (input == null) { return input; } return tags.Replace (input, String.Empty); } public static string DoubleToTenthsPrecision (double num) { return DoubleToTenthsPrecision (num, false); } public static string DoubleToTenthsPrecision (double num, bool always_decimal) { return DoubleToTenthsPrecision (num, always_decimal, NumberFormatInfo.CurrentInfo); } public static string DoubleToTenthsPrecision (double num, bool always_decimal, IFormatProvider provider) { num = Math.Round (num, 1, MidpointRounding.ToEven); return String.Format (provider, !always_decimal && num == (int)num ? "{0:N0}" : "{0:N1}", num); } // This method helps us pluralize doubles. Probably a horrible i18n idea. public static int DoubleToPluralInt (double num) { if (num == (int)num) return (int)num; else return (int)num + 1; } // A mapping of non-Latin characters to be considered the same as // a Latin equivalent. private static Dictionary BuildSpecialCases () { Dictionary dict = new Dictionary (); dict['\u00f8'] = 'o'; dict['\u0142'] = 'l'; return dict; } private static Dictionary searchkey_special_cases = BuildSpecialCases (); // Removes accents from Latin characters, and some kinds of punctuation. public static string SearchKey (string val) { if (String.IsNullOrEmpty (val)) { return val; } val = val.ToLower (); StringBuilder sb = new StringBuilder (); UnicodeCategory category; bool previous_was_letter = false; bool got_space = false; // Normalizing to KD splits into (base, combining) so we can check for letters // and then strip off any NonSpacingMarks following them foreach (char orig_c in val.TrimStart ().Normalize (NormalizationForm.FormKD)) { // Check for a special case *before* whitespace. This way, if // a special case is ever added that maps to ' ' or '\t', it // won't cause a run of whitespace in the result. char c = orig_c; if (searchkey_special_cases.ContainsKey (c)) { c = searchkey_special_cases[c]; } if (c == ' ' || c == '\t') { got_space = true; continue; } category = Char.GetUnicodeCategory (c); if (category == UnicodeCategory.OtherPunctuation) { // Skip punctuation } else if (!(previous_was_letter && category == UnicodeCategory.NonSpacingMark)) { if (got_space) { sb.Append (" "); got_space = false; } sb.Append (c); } // Can ignore A-Z because we've already lowercased the char previous_was_letter = Char.IsLetter (c); } string result = sb.ToString (); try { result = result.Normalize (NormalizationForm.FormKC); } catch { // FIXME: work-around, see http://bugzilla.gnome.org/show_bug.cgi?id=590478 } return result; } private static Regex invalid_path_regex = BuildInvalidPathRegex (); private static Regex BuildInvalidPathRegex () { char [] invalid_path_characters = new char [] { // Control characters: there's no reason to ever have one of these in a track name anyway, // and they're invalid in all Windows filesystems. '\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07', '\x08', '\x09', '\x0A', '\x0B', '\x0C', '\x0D', '\x0E', '\x0F', '\x10', '\x11', '\x12', '\x13', '\x14', '\x15', '\x16', '\x17', '\x18', '\x19', '\x1A', '\x1B', '\x1C', '\x1D', '\x1E', '\x1F', // Invalid in FAT32 / NTFS: " \ / : * | ? < > // Invalid in HFS : // Invalid in ext3 / '"', '\\', '/', ':', '*', '|', '?', '<', '>' }; string regex_str = "["; for (int i = 0; i < invalid_path_characters.Length; i++) { regex_str += "\\" + invalid_path_characters[i]; } regex_str += "]+"; return new Regex (regex_str, RegexOptions.Compiled); } private static CompareInfo culture_compare_info = CultureInfo.CurrentCulture.CompareInfo; public static byte[] SortKey (string orig) { if (orig == null) { return null; } return culture_compare_info.GetSortKey (orig, CompareOptions.IgnoreCase).KeyData; } private static readonly char[] escape_path_trim_chars = new char[] {'.', '\x20'}; public static string EscapeFilename (string input) { if (input == null) return ""; // Remove leading and trailing dots and spaces. input = input.Trim (escape_path_trim_chars); return invalid_path_regex.Replace (input, "_"); } public static string EscapePath (string input) { if (input == null) return ""; // This method should be called before the full path is constructed. if (Path.IsPathRooted (input)) { return input; } StringBuilder builder = new StringBuilder (); foreach (string name in input.Split (Path.DirectorySeparatorChar)) { // Escape the directory or the file name. string escaped = EscapeFilename (name); // Skip empty names. if (escaped.Length > 0) { builder.Append (escaped); builder.Append (Path.DirectorySeparatorChar); } } // Chop off the last character. if (builder.Length > 0) { builder.Length--; } return builder.ToString (); } public static string MaybeFallback (string input, string fallback) { string trimmed = input == null ? null : input.Trim (); return String.IsNullOrEmpty (trimmed) ? fallback : trimmed; } public static uint SubstringCount (string haystack, string needle) { if (String.IsNullOrEmpty (haystack) || String.IsNullOrEmpty (needle)) { return 0; } int position = 0; uint count = 0; while (true) { int index = haystack.IndexOf (needle, position); if (index < 0) { return count; } count++; position = index + 1; } } public static string SubstringBetween (this string input, string start, string end) { int s = input.IndexOf (start); if (s == -1) return null; s += start.Length; int l = Math.Min (input.Length - 1, input.IndexOf (end, s)) - s; if (l > 0 && s + l < input.Length) { return input.Substring (s, l); } else { return null; } } private static readonly char[] escaped_like_chars = new char[] {'\\', '%', '_'}; public static string EscapeLike (string s) { if (s.IndexOfAny (escaped_like_chars) != -1) { return s.Replace (@"\", @"\\").Replace ("%", @"\%").Replace ("_", @"\_"); } return s; } public static string Join (this IEnumerable strings, string sep) { var sb = new StringBuilder (); foreach (var str in strings) { sb.Append (str); sb.Append (sep); } if (sb.Length > 0 && sep != null) { sb.Length -= sep.Length; } return sb.ToString (); } } } hyena-0.5/Hyena/Hyena/EventArgs.cs0000644000175000001440000000402011377105342017133 0ustar00gabeusers00000000000000// // EventArgs.cs // // Author: // Alexander Kojevnikov // // Copyright (C) 2009-2010 Alexander Kojevnikov // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; namespace Hyena { public class EventArgs : System.EventArgs { private readonly T value; public EventArgs (T value) { this.value = value; } public T Value { get { return value; } } } public static class EventExtensions { public static void SafeInvoke (this T @event, params object[] args) where T : class { var multicast = @event as MulticastDelegate; if (multicast != null) { foreach (var handler in multicast.GetInvocationList ()) { try { handler.DynamicInvoke (args); } catch (Exception e) { Log.Exception (e); } } } } } } hyena-0.5/Hyena/Hyena/ThreadAssist.cs0000644000175000001440000000773711377105342017655 0ustar00gabeusers00000000000000// // ThreadAssist.cs // // Author: // Aaron Bockover // Gabriel Burt // // Copyright (C) 2005-2009 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Threading; namespace Hyena { public static class ThreadAssist { private static Thread main_thread; public static Thread MainThread { get { return main_thread; } } public static Action ProxyToMainHandler { get; set; } public static void InitializeMainThread () { main_thread = Thread.CurrentThread; main_thread.Name = "Main Thread"; } public static bool InMainThread { get { if (main_thread == null) { throw new ApplicationException ("ThreadAssist.InitializeMainThread must be called first"); } return main_thread.Equals (Thread.CurrentThread); } } public static void AssertNotInMainThread () { if (ApplicationContext.Debugging && InMainThread) { Hyena.Log.Warning ("In GUI thread, will probably block it", System.Environment.StackTrace); } } public static void AssertInMainThread () { if (ApplicationContext.Debugging && !InMainThread) { Hyena.Log.Warning ("Not in main thread!", System.Environment.StackTrace); } } public static void BlockingProxyToMain (InvokeHandler handler) { if (!InMainThread) { var reset_event = new System.Threading.ManualResetEvent (false); ProxyToMainHandler (delegate { try { handler (); } finally { reset_event.Set (); } }); reset_event.WaitOne (); } else { handler (); } } public static void ProxyToMain (InvokeHandler handler) { if (!InMainThread) { ProxyToMainHandler (handler); } else { handler (); } } public static void SpawnFromMain (ThreadStart threadedMethod) { if (InMainThread) { Spawn (threadedMethod, true); } else { threadedMethod (); } } public static Thread Spawn (ThreadStart threadedMethod, bool autoStart) { Thread thread = new Thread (threadedMethod); thread.Name = String.Format ("Spawned: {0}", threadedMethod); thread.IsBackground = true; if (autoStart) { thread.Start (); } return thread; } public static Thread Spawn (ThreadStart threadedMethod) { return Spawn (threadedMethod, true); } } } hyena-0.5/Hyena/Hyena/Timer.cs0000644000175000001440000000361011377105342016321 0ustar00gabeusers00000000000000// // Timer.cs // // Author: // Aaron Bockover // // Copyright (C) 2007 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; namespace Hyena { public class Timer : IDisposable { private DateTime start; private string label; public Timer (string format, params object [] vals) : this (String.Format (format, vals)) { } public Timer (string label) { this.label = label; start = DateTime.Now; } public TimeSpan ElapsedTime { get { return DateTime.Now - start; } } public void WriteElapsed (string message) { Console.Error.WriteLine ("{0} {1} {2}", label, message, ElapsedTime); } public void Dispose () { WriteElapsed ("timer stopped:"); } } } hyena-0.5/Hyena/Hyena/ApplicationContext.cs0000644000175000001440000000763511414712057021063 0ustar00gabeusers00000000000000// // ApplicationContext.cs // // Author: // Aaron Bockover // // Copyright (C) 2007 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Text; using System.Runtime.InteropServices; using Hyena.CommandLine; namespace Hyena { public delegate void InvokeHandler (); public static class ApplicationContext { public static readonly DateTime StartedAt = DateTime.Now; static ApplicationContext () { Log.Debugging = Debugging; } private static CommandLineParser command_line = new CommandLineParser (); public static CommandLineParser CommandLine { set { command_line = value; } get { return command_line; } } public static string ApplicationName { get; set; } private static Layout command_line_layout; public static Layout CommandLineLayout { get { return command_line_layout; } set { command_line_layout = value; } } private static bool? debugging = null; public static bool Debugging { get { if (debugging == null) { debugging = CommandLine.Contains ("debug"); debugging |= CommandLine.Contains ("debug-sql"); debugging |= EnvironmentIsSet ("BANSHEE_DEBUG"); } return debugging.Value; } } public static bool EnvironmentIsSet (string env) { return !String.IsNullOrEmpty (Environment.GetEnvironmentVariable (env)); } public static System.Globalization.CultureInfo InternalCultureInfo { get { return System.Globalization.CultureInfo.InvariantCulture; } } [DllImport ("libc")] // Linux private static extern int prctl (int option, byte [] arg2, IntPtr arg3, IntPtr arg4, IntPtr arg5); [DllImport ("libc")] // BSD private static extern void setproctitle (byte [] fmt, byte [] str_arg); private static void SetProcessName (string name) { if (Environment.OSVersion.Platform != PlatformID.Unix) { return; } try { if (prctl (15 /* PR_SET_NAME */, Encoding.ASCII.GetBytes (name + "\0"), IntPtr.Zero, IntPtr.Zero, IntPtr.Zero) != 0) { throw new ApplicationException ("Error setting process name: " + Mono.Unix.Native.Stdlib.GetLastError ()); } } catch (EntryPointNotFoundException) { setproctitle (Encoding.ASCII.GetBytes ("%s\0"), Encoding.ASCII.GetBytes (name + "\0")); } } public static void TrySetProcessName (string name) { try { SetProcessName (name); } catch { } } } } hyena-0.5/Hyena/Hyena/Log.cs0000644000175000001440000002715611377105342015775 0ustar00gabeusers00000000000000// // Log.cs // // Author: // Aaron Bockover // // Copyright (C) 2005-2007 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Text; using System.Collections.Generic; using System.Threading; namespace Hyena { public delegate void LogNotifyHandler (LogNotifyArgs args); public class LogNotifyArgs : EventArgs { private LogEntry entry; public LogNotifyArgs (LogEntry entry) { this.entry = entry; } public LogEntry Entry { get { return entry; } } } public enum LogEntryType { Debug, Warning, Error, Information } public class LogEntry { private LogEntryType type; private string message; private string details; private DateTime timestamp; internal LogEntry (LogEntryType type, string message, string details) { this.type = type; this.message = message; this.details = details; this.timestamp = DateTime.Now; } public LogEntryType Type { get { return type; } } public string Message { get { return message; } } public string Details { get { return details; } } public DateTime TimeStamp { get { return timestamp; } } } public static class Log { public static event LogNotifyHandler Notify; private static Dictionary timers = new Dictionary (); private static uint next_timer_id = 1; private static bool debugging = false; public static bool Debugging { get { return debugging; } set { debugging = value; } } public static void Commit (LogEntryType type, string message, string details, bool showUser) { if (type == LogEntryType.Debug && !Debugging) { return; } if (type != LogEntryType.Information || (type == LogEntryType.Information && !showUser)) { switch (type) { case LogEntryType.Error: ConsoleCrayon.ForegroundColor = ConsoleColor.Red; break; case LogEntryType.Warning: ConsoleCrayon.ForegroundColor = ConsoleColor.DarkYellow; break; case LogEntryType.Information: ConsoleCrayon.ForegroundColor = ConsoleColor.Green; break; case LogEntryType.Debug: ConsoleCrayon.ForegroundColor = ConsoleColor.Blue; break; } var thread_name = String.Empty; if (Debugging) { var thread = Thread.CurrentThread; thread_name = String.Format ("{0} ", thread.ManagedThreadId); } Console.Write ("[{5}{0} {1:00}:{2:00}:{3:00}.{4:000}]", TypeString (type), DateTime.Now.Hour, DateTime.Now.Minute, DateTime.Now.Second, DateTime.Now.Millisecond, thread_name); ConsoleCrayon.ResetColor (); if (details != null) { Console.WriteLine (" {0} - {1}", message, details); } else { Console.WriteLine (" {0}", message); } } if (showUser) { OnNotify (new LogEntry (type, message, details)); } } private static string TypeString (LogEntryType type) { switch (type) { case LogEntryType.Debug: return "Debug"; case LogEntryType.Warning: return "Warn "; case LogEntryType.Error: return "Error"; case LogEntryType.Information: return "Info "; } return null; } private static void OnNotify (LogEntry entry) { LogNotifyHandler handler = Notify; if (handler != null) { handler (new LogNotifyArgs (entry)); } } #region Timer Methods public static uint DebugTimerStart (string message) { return TimerStart (message, false); } public static uint InformationTimerStart (string message) { return TimerStart (message, true); } private static uint TimerStart (string message, bool isInfo) { if (!Debugging && !isInfo) { return 0; } if (isInfo) { Information (message); } else { Debug (message); } return TimerStart (isInfo); } public static uint DebugTimerStart () { return TimerStart (false); } public static uint InformationTimerStart () { return TimerStart (true); } private static uint TimerStart (bool isInfo) { if (!Debugging && !isInfo) { return 0; } uint timer_id = next_timer_id++; timers.Add (timer_id, DateTime.Now); return timer_id; } public static void DebugTimerPrint (uint id) { if (!Debugging) { return; } TimerPrint (id, "Operation duration: {0}", false); } public static void DebugTimerPrint (uint id, string message) { if (!Debugging) { return; } TimerPrint (id, message, false); } public static void InformationTimerPrint (uint id) { TimerPrint (id, "Operation duration: {0}", true); } public static void InformationTimerPrint (uint id, string message) { TimerPrint (id, message, true); } private static void TimerPrint (uint id, string message, bool isInfo) { if (!Debugging && !isInfo) { return; } DateTime finish = DateTime.Now; if (!timers.ContainsKey (id)) { return; } TimeSpan duration = finish - timers[id]; string d_message; if (duration.TotalSeconds < 60) { d_message = duration.TotalSeconds.ToString (); } else { d_message = duration.ToString (); } if (isInfo) { InformationFormat (message, d_message); } else { DebugFormat (message, d_message); } } #endregion #region Public Debug Methods public static void Debug (string message, string details) { if (Debugging) { Commit (LogEntryType.Debug, message, details, false); } } public static void Debug (string message) { if (Debugging) { Debug (message, null); } } public static void DebugFormat (string format, params object [] args) { if (Debugging) { Debug (String.Format (format, args)); } } #endregion #region Public Information Methods public static void Information (string message) { Information (message, null); } public static void Information (string message, string details) { Information (message, details, false); } public static void Information (string message, string details, bool showUser) { Commit (LogEntryType.Information, message, details, showUser); } public static void Information (string message, bool showUser) { Information (message, null, showUser); } public static void InformationFormat (string format, params object [] args) { Information (String.Format (format, args)); } #endregion #region Public Warning Methods public static void Warning (string message) { Warning (message, null); } public static void Warning (string message, string details) { Warning (message, details, false); } public static void Warning (string message, string details, bool showUser) { Commit (LogEntryType.Warning, message, details, showUser); } public static void Warning (string message, bool showUser) { Warning (message, null, showUser); } public static void WarningFormat (string format, params object [] args) { Warning (String.Format (format, args)); } #endregion #region Public Error Methods public static void Error (string message) { Error (message, null); } public static void Error (string message, string details) { Error (message, details, false); } public static void Error (string message, string details, bool showUser) { Commit (LogEntryType.Error, message, details, showUser); } public static void Error (string message, bool showUser) { Error (message, null, showUser); } public static void ErrorFormat (string format, params object [] args) { Error (String.Format (format, args)); } #endregion #region Public Exception Methods public static void DebugException (Exception e) { if (Debugging) { Exception (e); } } public static void Exception (Exception e) { Exception (null, e); } public static void Exception (string message, Exception e) { Stack exception_chain = new Stack (); StringBuilder builder = new StringBuilder (); while (e != null) { exception_chain.Push (e); e = e.InnerException; } while (exception_chain.Count > 0) { e = exception_chain.Pop (); builder.AppendFormat ("{0}: {1} (in `{2}')", e.GetType (), e.Message, e.Source).AppendLine (); builder.Append (e.StackTrace); if (exception_chain.Count > 0) { builder.AppendLine (); } } // FIXME: We should save these to an actual log file Log.Warning (message ?? "Caught an exception", builder.ToString (), false); } #endregion } } hyena-0.5/Hyena/Hyena/XdgBaseDirectorySpec.cs0000644000175000001440000000725511377105342021267 0ustar00gabeusers00000000000000// // XdgBaseDirectorySpec.cs // // Author: // Aaron Bockover // // Copyright (C) 2006-2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.IO; namespace Hyena { public static class XdgBaseDirectorySpec { public static string GetUserDirectory (string key, string fallback) { string home_dir = Environment.GetFolderPath (Environment.SpecialFolder.Personal); string config_dir = Environment.GetFolderPath (Environment.SpecialFolder.ApplicationData); string env_path = Environment.GetEnvironmentVariable (key); if (!String.IsNullOrEmpty (env_path)) { return env_path; } string user_dirs_path = Path.Combine (config_dir, "user-dirs.dirs"); if (!File.Exists (user_dirs_path)) { return Path.Combine (home_dir, fallback); } try { using (StreamReader reader = new StreamReader (user_dirs_path)) { string line; while ((line = reader.ReadLine ()) != null) { line = line.Trim (); int delim_index = line.IndexOf ('='); if (delim_index > 8 && line.Substring (0, delim_index) == key) { string path = line.Substring (delim_index + 1).Trim ('"'); bool relative = false; if (path.StartsWith ("$HOME/")) { relative = true; path = path.Substring (6); } else if (path.StartsWith ("~")) { relative = true; path = path.Substring (1); } else if (!path.StartsWith ("/")) { relative = true; } return relative ? Path.Combine (home_dir, path) : path; } } } } catch (FileNotFoundException) { } return Path.Combine (home_dir, fallback); } public static string GetXdgDirectoryUnderHome (string key, string fallback) { string xdg_dir = XdgBaseDirectorySpec.GetUserDirectory (key, fallback); string home_dir = Environment.GetFolderPath (Environment.SpecialFolder.Personal); if (xdg_dir == null || xdg_dir == home_dir || !xdg_dir.StartsWith (home_dir)) { xdg_dir = Path.Combine (home_dir, fallback); } return xdg_dir; } } } hyena-0.5/Hyena/Hyena/DateTimeUtil.cs0000644000175000001440000000637711377105342017610 0ustar00gabeusers00000000000000// // Utilities.cs // // Author: // Aaron Bockover // // Copyright (C) 2007 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Globalization; namespace Hyena { public class DateTimeUtil { // FIXME I don't think having a local-unix-epoch makes any sense, I think we should be using // all UTC values. Depending on the time of year in daylight savings timezones, the // local-seconds-since-epoch value will differ, which will cause errors, no? public static readonly DateTime LocalUnixEpoch = new DateTime (1970, 1, 1).ToLocalTime (); public static DateTime ToDateTime (long time) { return FromTimeT (time); } public static long FromDateTime (DateTime time) { return ToTimeT (time); } private static long super_ugly_min_hack = -15768000000; // 500 yrs before epoch...ewww public static DateTime FromTimeT (long time) { return (time <= super_ugly_min_hack) ? DateTime.MinValue : LocalUnixEpoch.AddSeconds (time); } public static long ToTimeT (DateTime time) { return (long)time.Subtract (LocalUnixEpoch).TotalSeconds; } public static string FormatDuration (long time) { return FormatDuration (TimeSpan.FromSeconds (time)); } public static string FormatDuration (TimeSpan time) { return FormatDuration (time.Hours, time.Minutes, time.Seconds); } public static string FormatDuration (int hours, int minutes, int seconds) { return (hours > 0 ? String.Format ("{0}:{1:00}:{2:00}", hours, minutes, seconds) : String.Format ("{0}:{1:00}", minutes, seconds)); } const string INVARIANT_FMT = "yyyy-MM-dd HH:mm:ss.fff zzz"; public static string ToInvariantString (DateTime dt) { return dt.ToString (INVARIANT_FMT, CultureInfo.InvariantCulture); } public static bool TryParseInvariant (string str, out DateTime dt) { return DateTime.TryParseExact (str, INVARIANT_FMT, CultureInfo.InvariantCulture, DateTimeStyles.None, out dt); } } }hyena-0.5/Hyena/Hyena/Delegates.cs0000644000175000001440000000234411377105342017141 0ustar00gabeusers00000000000000// // Delegates.cs // // Author: // Aaron Bockover // // Copyright (C) 2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // namespace Hyena { public delegate void Action (); } hyena-0.5/Hyena/Hyena/ConsoleCrayon.cs0000644000175000001440000002036011377105342020020 0ustar00gabeusers00000000000000// // ConsoleCrayon.cs // // Author: // Aaron Bockover // // Copyright (C) 2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; namespace Hyena { public static class ConsoleCrayon { #region Public API private static ConsoleColor foreground_color; public static ConsoleColor ForegroundColor { get { return foreground_color; } set { foreground_color = value; SetColor (foreground_color, true); } } private static ConsoleColor background_color; public static ConsoleColor BackgroundColor { get { return background_color; } set { background_color = value; SetColor (background_color, false); } } public static void ResetColor () { if (XtermColors) { Console.Write (GetAnsiResetControlCode ()); } else if (Environment.OSVersion.Platform != PlatformID.Unix && !RuntimeIsMono) { Console.ResetColor (); } } private static void SetColor (ConsoleColor color, bool isForeground) { if (color < ConsoleColor.Black || color > ConsoleColor.White) { throw new ArgumentOutOfRangeException ("color", "Not a ConsoleColor value."); } if (XtermColors) { Console.Write (GetAnsiColorControlCode (color, isForeground)); } else if (Environment.OSVersion.Platform != PlatformID.Unix && !RuntimeIsMono) { if (isForeground) { Console.ForegroundColor = color; } else { Console.BackgroundColor = color; } } } #endregion #region Ansi/VT Code Calculation // Modified from Mono's System.TermInfoDriver // License: MIT/X11 // Authors: Gonzalo Paniagua Javier // (C) 2005-2006 Novell, Inc private static int TranslateColor (ConsoleColor desired, out bool light) { light = false; switch (desired) { // Dark colors case ConsoleColor.Black: return 0; case ConsoleColor.DarkRed: return 1; case ConsoleColor.DarkGreen: return 2; case ConsoleColor.DarkYellow: return 3; case ConsoleColor.DarkBlue: return 4; case ConsoleColor.DarkMagenta: return 5; case ConsoleColor.DarkCyan: return 6; case ConsoleColor.Gray: return 7; // Light colors case ConsoleColor.DarkGray: light = true; return 0; case ConsoleColor.Red: light = true; return 1; case ConsoleColor.Green: light = true; return 2; case ConsoleColor.Yellow: light = true; return 3; case ConsoleColor.Blue: light = true; return 4; case ConsoleColor.Magenta: light = true; return 5; case ConsoleColor.Cyan: light = true; return 6; case ConsoleColor.White: default: light = true; return 7; } } private static string GetAnsiColorControlCode (ConsoleColor color, bool isForeground) { // lighter fg colours are 90 -> 97 rather than 30 -> 37 // lighter bg colours are 100 -> 107 rather than 40 -> 47 bool light; int code = TranslateColor (color, out light) + (isForeground ? 30 : 40) + (light ? 60 : 0); return String.Format ("\x001b[{0}m", code); } private static string GetAnsiResetControlCode () { return "\x001b[0m"; } #endregion #region xterm Detection private static bool? xterm_colors = null; public static bool XtermColors { get { if (xterm_colors == null) { DetectXtermColors (); } return xterm_colors.Value; } } [System.Runtime.InteropServices.DllImport ("libc", EntryPoint="isatty")] private extern static int _isatty (int fd); private static bool isatty (int fd) { try { return _isatty (fd) == 1; } catch { return false; } } private static void DetectXtermColors () { bool _xterm_colors = false; switch (Environment.GetEnvironmentVariable ("TERM")) { case "xterm": case "rxvt": case "rxvt-unicode": if (Environment.GetEnvironmentVariable ("COLORTERM") != null) { _xterm_colors = true; } break; case "xterm-color": _xterm_colors = true; break; } xterm_colors = _xterm_colors && isatty (1) && isatty (2); } #endregion #region Runtime Detection private static bool? runtime_is_mono; public static bool RuntimeIsMono { get { if (runtime_is_mono == null) { runtime_is_mono = Type.GetType ("System.MonoType") != null; } return runtime_is_mono.Value; } } #endregion #region Tests public static void Test () { TestSelf (); Console.WriteLine (); TestAnsi (); Console.WriteLine (); TestRuntime (); } private static void TestSelf () { Console.WriteLine ("==SELF TEST=="); foreach (ConsoleColor color in Enum.GetValues (typeof (ConsoleColor))) { ForegroundColor = color; Console.Write (color); ResetColor (); Console.Write (" :: "); BackgroundColor = color; Console.Write (color); ResetColor (); Console.WriteLine (); } } private static void TestAnsi () { Console.WriteLine ("==ANSI TEST=="); foreach (ConsoleColor color in Enum.GetValues (typeof (ConsoleColor))) { string color_code_fg = GetAnsiColorControlCode (color, true); string color_code_bg = GetAnsiColorControlCode (color, false); Console.Write ("{0}{1}: {2}{3} :: {4}{1}: {5}{3}", color_code_fg, color, color_code_fg.Substring (2), GetAnsiResetControlCode (), color_code_bg, color_code_bg.Substring (2)); Console.WriteLine (); } } private static void TestRuntime () { Console.WriteLine ("==RUNTIME TEST=="); foreach (ConsoleColor color in Enum.GetValues (typeof (ConsoleColor))) { Console.ForegroundColor = color; Console.Write (color); Console.ResetColor (); Console.Write (" :: "); Console.BackgroundColor = color; Console.Write (color); Console.ResetColor (); Console.WriteLine (); } } #endregion } } hyena-0.5/Hyena/Makefile.in0000644000175000001440000004237611453150777015736 0ustar00gabeusers00000000000000# Makefile.in generated by automake 1.10.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(top_srcdir)/build/build.environment.mk \ $(top_srcdir)/build/build.mk \ $(top_srcdir)/build/build.rules.mk @ENABLE_TESTS_TRUE@am__append_1 = " $(NUNIT_LIBS)" subdir = Hyena ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/build/m4/shamrock/expansions.m4 \ $(top_srcdir)/build/m4/shamrock/mono.m4 \ $(top_srcdir)/build/m4/shamrock/programs.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = am__installdirs = "$(DESTDIR)$(moduledir)" moduleSCRIPT_INSTALL = $(INSTALL_SCRIPT) SCRIPTS = $(module_SCRIPTS) DIST_SOURCES = DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ GLIBSHARP_CFLAGS = @GLIBSHARP_CFLAGS@ GLIBSHARP_LIBS = @GLIBSHARP_LIBS@ GTKSHARP_A11Y_CFLAGS = @GTKSHARP_A11Y_CFLAGS@ GTKSHARP_A11Y_LIBS = @GTKSHARP_A11Y_LIBS@ GTKSHARP_CFLAGS = @GTKSHARP_CFLAGS@ GTKSHARP_LIBS = @GTKSHARP_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MCS = @MCS@ MKDIR_P = @MKDIR_P@ MONO = @MONO@ MONO_MODULE_CFLAGS = @MONO_MODULE_CFLAGS@ MONO_MODULE_LIBS = @MONO_MODULE_LIBS@ NUNIT_CFLAGS = @NUNIT_CFLAGS@ NUNIT_LIBS = @NUNIT_LIBS@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ am__leading_dot = @am__leading_dot@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ expanded_bindir = @expanded_bindir@ expanded_datadir = @expanded_datadir@ expanded_libdir = @expanded_libdir@ host_alias = @host_alias@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ ASSEMBLY = Hyena TARGET = library LINK = -r:Mono.Posix -r:System -r:System.Core $(GLIBSHARP_LIBS) \ $(am__append_1) SOURCES = \ Hyena.Collections/CollectionExtensions.cs \ Hyena.Collections/IntervalHeap.cs \ Hyena.Collections/IStackProvider.cs \ Hyena.Collections/LruCache.cs \ Hyena.Collections/QueuePipeline.cs \ Hyena.Collections/QueuePipelineElement.cs \ Hyena.Collections/RangeCollection.cs \ Hyena.Collections/Selection.cs \ Hyena.Collections/SelectionProxy.cs \ Hyena.Collections/Tests/IntervalHeapTests.cs \ Hyena.Collections/Tests/QueuePipelineTests.cs \ Hyena.Collections/Tests/RangeCollectionTests.cs \ Hyena.Collections/WriteLineElement.cs \ Hyena.CommandLine/CommandLineParser.cs \ Hyena.CommandLine/Layout.cs \ Hyena.CommandLine/LayoutGroup.cs \ Hyena.CommandLine/LayoutOption.cs \ Hyena.Data/ArrayModelCache.cs \ Hyena.Data/BaseListModel.cs \ Hyena.Data/ColumnDescription.cs \ Hyena.Data/DictionaryModelCache.cs \ Hyena.Data/ICacheableItem.cs \ Hyena.Data/ICacheableModel.cs \ Hyena.Data/ICareAboutView.cs \ Hyena.Data/IFilterable.cs \ Hyena.Data/IListModel.cs \ Hyena.Data/IPropertyStoreExpose.cs \ Hyena.Data/ISelectable.cs \ Hyena.Data/ISortable.cs \ Hyena.Data/ISortableColumn.cs \ Hyena.Data/MemoryListModel.cs \ Hyena.Data/ModelCache.cs \ Hyena.Data/ModelSelection.cs \ Hyena.Data/PropertyStore.cs \ Hyena.Data/SortType.cs \ Hyena.Downloader/Buffer.cs \ Hyena.Downloader/DownloadManager.cs \ Hyena.Downloader/DownloadManagerJob.cs \ Hyena.Downloader/HttpDownloader.cs \ Hyena.Downloader/HttpDownloaderState.cs \ Hyena.Downloader/HttpFileDownloader.cs \ Hyena.Downloader/HttpStringDownloader.cs \ Hyena.Downloader/Tests/HttpTestServer.cs \ Hyena.Downloader/Tests/Tests.cs \ Hyena.Jobs/Job.cs \ Hyena.Jobs/JobExtensions.cs \ Hyena.Jobs/PriorityHints.cs \ Hyena.Jobs/Resource.cs \ Hyena.Jobs/Scheduler.cs \ Hyena.Jobs/SimpleAsyncJob.cs \ Hyena.Jobs/Tests/SchedulerTests.cs \ Hyena.Json/Deserializer.cs \ Hyena.Json/IJsonCollection.cs \ Hyena.Json/JsonArray.cs \ Hyena.Json/JsonObject.cs \ Hyena.Json/Serializer.cs \ Hyena.Json/Tests/DeserializerTests.cs \ Hyena.Json/Tests/SerializerTests.cs \ Hyena.Json/Tests/TokenizerTests.cs \ Hyena.Json/Token.cs \ Hyena.Json/Tokenizer.cs \ Hyena.Json/TokenType.cs \ Hyena.Query/AliasedObjectSet.cs \ Hyena.Query/DateQueryValue.cs \ Hyena.Query/EnumQueryValue.cs \ Hyena.Query/ExactStringQueryValue.cs \ Hyena.Query/ExactUriStringQueryValue.cs \ Hyena.Query/FileSizeQueryValue.cs \ Hyena.Query/IntegerKeyedObjectQueryValue.cs \ Hyena.Query/IntegerQueryValue.cs \ Hyena.Query/NullQueryValue.cs \ Hyena.Query/QueryField.cs \ Hyena.Query/QueryFieldSet.cs \ Hyena.Query/QueryLimit.cs \ Hyena.Query/QueryListNode.cs \ Hyena.Query/QueryNode.cs \ Hyena.Query/QueryOperator.cs \ Hyena.Query/QueryOrder.cs \ Hyena.Query/QueryParser.cs \ Hyena.Query/QueryTermNode.cs \ Hyena.Query/QueryToken.cs \ Hyena.Query/QueryValue.cs \ Hyena.Query/RelativeTimeSpanQueryValue.cs \ Hyena.Query/StringQueryValue.cs \ Hyena.Query/Tests/QueryTests.cs \ Hyena.Query/TimeSpanQueryValue.cs \ Hyena.Query/UserQueryParser.cs \ Hyena.Query/XmlQueryParser.cs \ Hyena.SExpEngine/ArithmeticFunctionSet.cs \ Hyena.SExpEngine/CastFunctionSet.cs \ Hyena.SExpEngine/CompareFunctionSet.cs \ Hyena.SExpEngine/ControlFunctionSet.cs \ Hyena.SExpEngine/Evaluator.cs \ Hyena.SExpEngine/EvaluatorBase.cs \ Hyena.SExpEngine/FunctionFunctionSet.cs \ Hyena.SExpEngine/FunctionNode.cs \ Hyena.SExpEngine/FunctionSet.cs \ Hyena.SExpEngine/ListFunctionSet.cs \ Hyena.SExpEngine/Literals.cs \ Hyena.SExpEngine/LogicFunctionSet.cs \ Hyena.SExpEngine/Parser.cs \ Hyena.SExpEngine/StringFunctionSet.cs \ Hyena.SExpEngine/TreeNode.cs \ Hyena.SExpEngine/UtilityFunctionSet.cs \ Hyena/ApplicationContext.cs \ Hyena/ConsoleCrayon.cs \ Hyena/CryptoUtil.cs \ Hyena/DateTimeUtil.cs \ Hyena/Delegates.cs \ Hyena/EventArgs.cs \ Hyena/IUndoAction.cs \ Hyena/Log.cs \ Hyena/Paths.cs \ Hyena/PlatformDetection.cs \ Hyena/SafeUri.cs \ Hyena/StringUtil.cs \ Hyena/Tests/CryptoUtilTests.cs \ Hyena/Tests/DateTimeUtilTests.cs \ Hyena/Tests/StringUtilTests.cs \ Hyena/Tests/TestBase.cs \ Hyena/ThreadAssist.cs \ Hyena/Timer.cs \ Hyena/UndoManager.cs \ Hyena/XdgBaseDirectorySpec.cs \ System.Web/Helpers.cs \ System.Web/HttpUtility.cs # Initializers MONO_BASE_PATH = MONO_ADDINS_PATH = # Install Paths DEFAULT_INSTALL_DIR = $(pkglibdir) DIR_BIN = $(top_builddir)/bin # Cute hack to replace a space with something colon := : empty := space := $(empty) $(empty) UNIQUE_FILTER_PIPE = tr [:space:] \\n | sort | uniq BUILD_DATA_DIR = $(top_builddir)/bin/share/$(PACKAGE) SOURCES_BUILD = $(addprefix $(srcdir)/, $(SOURCES)) RESOURCES_EXPANDED = $(addprefix $(srcdir)/, $(RESOURCES)) RESOURCES_BUILD = $(foreach resource, $(RESOURCES_EXPANDED), \ -resource:$(resource),$(notdir $(resource))) INSTALL_ICONS = $(top_srcdir)/build/private-icon-theme-installer "$(mkinstalldirs)" "$(INSTALL_DATA)" THEME_ICONS_SOURCE = $(wildcard $(srcdir)/ThemeIcons/*/*/*.png) $(wildcard $(srcdir)/ThemeIcons/scalable/*/*.svg) THEME_ICONS_RELATIVE = $(subst $(srcdir)/ThemeIcons/, , $(THEME_ICONS_SOURCE)) ASSEMBLY_EXTENSION = $(strip $(patsubst library, dll, $(TARGET))) ASSEMBLY_FILE = $(top_builddir)/bin/$(ASSEMBLY).$(ASSEMBLY_EXTENSION) INSTALL_DIR_RESOLVED = $(firstword $(subst , $(DEFAULT_INSTALL_DIR), $(INSTALL_DIR))) @ENABLE_TESTS_TRUE@ENABLE_TESTS_FLAG = "-define:ENABLE_TESTS" @ENABLE_ATK_TRUE@ENABLE_ATK_FLAG = "-define:ENABLE_ATK" FILTERED_LINK = $(shell echo "$(LINK)" | $(UNIQUE_FILTER_PIPE)) DEP_LINK = $(shell echo "$(LINK)" | $(UNIQUE_FILTER_PIPE) | sed s,-r:,,g | grep '$(top_builddir)/bin/') OUTPUT_FILES = \ $(ASSEMBLY_FILE) \ $(ASSEMBLY_FILE).mdb moduledir = $(INSTALL_DIR_RESOLVED) module_SCRIPTS = $(OUTPUT_FILES) Hyena.dll.config EXTRA_DIST = $(SOURCES_BUILD) $(RESOURCES_EXPANDED) \ $(THEME_ICONS_SOURCE) Hyena.dll.config CLEANFILES = $(OUTPUT_FILES) DISTCLEANFILES = *.pidb MAINTAINERCLEANFILES = Makefile.in all: all-am .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/build/build.mk $(top_srcdir)/build/build.environment.mk $(top_srcdir)/build/build.rules.mk $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Hyena/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --foreign Hyena/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh install-moduleSCRIPTS: $(module_SCRIPTS) @$(NORMAL_INSTALL) test -z "$(moduledir)" || $(MKDIR_P) "$(DESTDIR)$(moduledir)" @list='$(module_SCRIPTS)'; for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ if test -f $$d$$p; then \ f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \ echo " $(moduleSCRIPT_INSTALL) '$$d$$p' '$(DESTDIR)$(moduledir)/$$f'"; \ $(moduleSCRIPT_INSTALL) "$$d$$p" "$(DESTDIR)$(moduledir)/$$f"; \ else :; fi; \ done uninstall-moduleSCRIPTS: @$(NORMAL_UNINSTALL) @list='$(module_SCRIPTS)'; for p in $$list; do \ f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \ echo " rm -f '$(DESTDIR)$(moduledir)/$$f'"; \ rm -f "$(DESTDIR)$(moduledir)/$$f"; \ done tags: TAGS TAGS: ctags: CTAGS CTAGS: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(SCRIPTS) installdirs: for dir in "$(DESTDIR)$(moduledir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) clean: clean-am clean-am: clean-generic mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am info: info-am info-am: install-data-am: install-data-local install-moduleSCRIPTS install-dvi: install-dvi-am install-exec-am: install-html: install-html-am install-info: install-info-am install-man: install-pdf: install-pdf-am install-ps: install-ps-am installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-local uninstall-moduleSCRIPTS .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic distclean \ distclean-generic distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am \ install-data-local install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-moduleSCRIPTS install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ pdf-am ps ps-am uninstall uninstall-am uninstall-local \ uninstall-moduleSCRIPTS dnl SOURCES_BUILD += $(top_srcdir)/src/AssemblyInfo.cs all: $(ASSEMBLY_FILE) theme-icons run: @pushd $(top_builddir); \ make run; \ popd; test: @pushd $(top_builddir)/tests; \ make $(ASSEMBLY); \ popd; build-debug: @echo $(DEP_LINK) $(ASSEMBLY_FILE).mdb: $(ASSEMBLY_FILE) $(ASSEMBLY_FILE): $(SOURCES_BUILD) $(RESOURCES_EXPANDED) $(DEP_LINK) @mkdir -p $(top_builddir)/bin @if [ ! "x$(ENABLE_RELEASE)" = "xyes" ]; then \ $(top_srcdir)/build/dll-map-makefile-verifier $(srcdir)/Makefile.am $(srcdir)/$(notdir $@.config) && \ $(MONO) $(top_builddir)/build/dll-map-verifier.exe $(srcdir)/$(notdir $@.config) -iwinmm -ilibbanshee -ilibbnpx11 -ilibc -ilibc.so.6 -iintl -ilibmtp.dll -ilibigemacintegration.dylib -iCFRelease $(SOURCES_BUILD); \ fi; $(MCS) \ $(GMCS_FLAGS) \ $(ASSEMBLY_BUILD_FLAGS) \ -nowarn:0278 -nowarn:0078 $$warn \ -define:HAVE_GTK_2_10 -define:NET_2_0 \ -debug -target:$(TARGET) -out:$@ \ $(BUILD_DEFINES) $(ENABLE_TESTS_FLAG) $(ENABLE_ATK_FLAG) \ $(FILTERED_LINK) $(RESOURCES_BUILD) $(SOURCES_BUILD) @if [ -e $(srcdir)/$(notdir $@.config) ]; then \ cp $(srcdir)/$(notdir $@.config) $(top_builddir)/bin; \ fi; @if [ ! -z "$(EXTRA_BUNDLE)" ]; then \ cp $(EXTRA_BUNDLE) $(top_builddir)/bin; \ fi; theme-icons: $(THEME_ICONS_SOURCE) @$(INSTALL_ICONS) -il "$(BUILD_DATA_DIR)" "$(srcdir)" $(THEME_ICONS_RELATIVE) install-data-local: $(THEME_ICONS_SOURCE) @$(INSTALL_ICONS) -i "$(DESTDIR)$(pkgdatadir)" "$(srcdir)" $(THEME_ICONS_RELATIVE) uninstall-local: $(THEME_ICONS_SOURCE) @$(INSTALL_ICONS) -u "$(DESTDIR)$(pkgdatadir)" "$(srcdir)" $(THEME_ICONS_RELATIVE) # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: hyena-0.5/Hyena/Hyena.Jobs/0000777000175000001440000000000011453151001015576 5ustar00gabeusers00000000000000hyena-0.5/Hyena/Hyena.Jobs/JobExtensions.cs0000644000175000001440000000460411377105342020733 0ustar00gabeusers00000000000000// // JobExtensions.cs // // Author: // Gabriel Burt // // Copyright (C) 2009 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Linq; using System.Collections.Generic; namespace Hyena.Jobs { public static class JobExtensions { internal static IEnumerable Without (this IEnumerable source, PriorityHints hints) where T : Job { return source.Where (j => !j.Has (hints)); } internal static IEnumerable With (this IEnumerable source, PriorityHints hints) where T : Job { return source.Where (j => j.Has (hints)); } internal static IEnumerable SharingResourceWith (this IEnumerable source, Job job) where T : Job { return source.Where (j => j.Resources.Intersect (job.Resources).Any ()); } public static void ForEach (this IEnumerable source, Action func) { foreach (T item in source) func (item); } public static bool Has (this T job, PriorityHints hints) where T : Job { return (job.PriorityHints & hints) == hints; } // Useful.. /*public static bool Include (this Enum source, Enum flags) { return ((int)source & (int)flags) == (int)flags; }*/ } } hyena-0.5/Hyena/Hyena.Jobs/Job.cs0000644000175000001440000001775111436010340016647 0ustar00gabeusers00000000000000// // Job.cs // // Author: // Gabriel Burt // // Copyright (C) 2009 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Linq; using System.Threading; using System.Collections.Generic; using System.Collections.ObjectModel; namespace Hyena.Jobs { public enum JobState { None, Scheduled, Running, Paused, Cancelled, Completed }; public class Job { public event EventHandler Updated; public event EventHandler Finished; public event EventHandler CancelRequested; private int update_freeze_ref; private JobState state = JobState.None; private ManualResetEvent pause_event; private DateTime created_at = DateTime.Now; private TimeSpan run_time = TimeSpan.Zero; private Object sync = new Object (); public bool IsCancelRequested { get; private set; } #region Internal Properties internal bool IsScheduled { get { return state == JobState.Scheduled; } } internal bool IsRunning { get { return state == JobState.Running; } } internal bool IsPaused { get { return state == JobState.Paused; } } public bool IsFinished { get { lock (sync) { return state == JobState.Cancelled || state == JobState.Completed; } } } internal DateTime CreatedAt { get { return created_at; } } internal TimeSpan RunTime { get { return run_time; } } #endregion #region Scheduler Methods internal void Start () { Log.Debug ("Starting", Title); lock (sync) { if (state != JobState.Scheduled && state != JobState.Paused) { Log.DebugFormat ("Job {0} in {1} state is not runnable", Title, state); return; } State = JobState.Running; if (pause_event != null) { pause_event.Set (); } RunJob (); } } internal void Cancel () { lock (sync) { if (!IsFinished) { IsCancelRequested = true; State = JobState.Cancelled; EventHandler handler = CancelRequested; if (handler != null) { handler (this, EventArgs.Empty); } } } Log.Debug ("Canceled", Title); } internal void Preempt () { Log.Debug ("Preempting", Title); Pause (false); } internal bool Pause () { Log.Debug ("Pausing ", Title); return Pause (true); } private bool Pause (bool unschedule) { lock (sync) { if (IsFinished) { Log.DebugFormat ("Job {0} in {1} state is not pausable", Title, state); return false; } State = unschedule ? JobState.Paused : JobState.Scheduled; if (pause_event != null) { pause_event.Reset (); } } return true; } #endregion private string title; private string status; private string [] icon_names; private double progress; #region Public Properties public string Title { get { return title; } set { title = value; OnUpdated (); } } public string Status { get { return status; } set { status = value; OnUpdated (); } } public double Progress { get { return progress; } set { progress = Math.Max (0.0, Math.Min (1.0, value)); OnUpdated (); } } public string [] IconNames { get { return icon_names; } set { if (value != null) { icon_names = value; OnUpdated (); } } } public bool IsBackground { get; set; } public bool CanCancel { get; set; } public string CancelMessage { get; set; } public bool DelayShow { get; set; } public PriorityHints PriorityHints { get; set; } // Causes runtime method-not-found error in mono 2.0.1 //public IEnumerable Resources { get; protected set; } internal Resource [] Resources; public JobState State { get { return state; } internal set { state = value; OnUpdated (); } } public void SetResources (params Resource [] resources) { Resources = resources; } #endregion #region Constructor public Job () : this (null, PriorityHints.None) { } public Job (string title, PriorityHints hints, params Resource [] resources) { Title = title; PriorityHints = hints; Resources = resources; } #endregion #region Abstract Methods protected virtual void RunJob () { } #endregion #region Protected Methods public void Update (string title, string status, double progress) { Title = title; Status = status; Progress = progress; } protected void FreezeUpdate () { System.Threading.Interlocked.Increment (ref update_freeze_ref); } protected void ThawUpdate (bool raiseUpdate) { System.Threading.Interlocked.Decrement (ref update_freeze_ref); if (raiseUpdate) { OnUpdated (); } } protected void OnUpdated () { if (update_freeze_ref != 0) { return; } EventHandler handler = Updated; if (handler != null) { handler (this, EventArgs.Empty); } } public void YieldToScheduler () { if (IsPaused || IsScheduled) { if (pause_event == null) { pause_event = new ManualResetEvent (false); } pause_event.WaitOne (); } } protected void OnFinished () { Log.Debug ("Finished", Title); pause_event = null; if (state != JobState.Cancelled) { State = JobState.Completed; } EventHandler handler = Finished; if (handler != null) { handler (this, EventArgs.Empty); } } #endregion internal bool HasScheduler { get; set; } } } hyena-0.5/Hyena/Hyena.Jobs/Tests/0000777000175000001440000000000011453151001016700 5ustar00gabeusers00000000000000hyena-0.5/Hyena/Hyena.Jobs/Tests/SchedulerTests.cs0000644000175000001440000001624211377105342022205 0ustar00gabeusers00000000000000// // SchedulerTests.cs // // Author: // Gabriel Burt // // Copyright (C) 2009 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // #if ENABLE_TESTS using System; using System.Linq; using System.Threading; using NUnit.Framework; using Hyena; namespace Hyena.Jobs { [TestFixture] public class SchedulerTests { private Scheduler scheduler; [SetUp] public void Setup () { //Log.Debugging = true; TestJob.job_count = 0; Log.Debug ("New job scheduler test"); } [TearDown] public void TearDown () { if (scheduler != null) { // Ensure the scheduler's jobs are all finished, otherwise // their job threads will be killed, throwing an exception while (scheduler.JobCount > 0); } //Log.Debugging = false; } [Test] public void TestSimultaneousSpeedJobs () { scheduler = new Scheduler (); scheduler.Add (new TestJob (200, PriorityHints.SpeedSensitive, Resource.Cpu, Resource.Disk)); scheduler.Add (new TestJob (200, PriorityHints.SpeedSensitive, Resource.Cpu, Resource.Disk)); scheduler.Add (new TestJob (200, PriorityHints.None, Resource.Cpu, Resource.Disk)); // Test that two SpeedSensitive jobs with the same Resources will run simultaneously AssertJobsRunning (2); // but that the third that isn't SpeedSensitive won't run until they are both done while (scheduler.JobCount > 1); Assert.AreEqual (PriorityHints.None, scheduler.Jobs.First ().PriorityHints); } [Test] public void TestOneNonSpeedJobPerResource () { // Test that two SpeedSensitive jobs with the same Resources will run simultaneously scheduler = new Scheduler (); scheduler.Add (new TestJob (200, PriorityHints.None, Resource.Cpu, Resource.Disk)); scheduler.Add (new TestJob (200, PriorityHints.None, Resource.Cpu, Resource.Disk)); AssertJobsRunning (1); } [Test] public void TestSpeedJobPreemptsNonSpeedJobs () { scheduler = new Scheduler (); TestJob a = new TestJob (200, PriorityHints.None, Resource.Cpu); TestJob b = new TestJob (200, PriorityHints.None, Resource.Disk); TestJob c = new TestJob (200, PriorityHints.LongRunning, Resource.Database); scheduler.Add (a); scheduler.Add (b); scheduler.Add (c); // Test that three jobs got started AssertJobsRunning (3); scheduler.Add (new TestJob (200, PriorityHints.SpeedSensitive, Resource.Cpu, Resource.Disk)); // Make sure the SpeedSensitive jobs has caused the Cpu and Disk jobs to be paused AssertJobsRunning (2); Assert.AreEqual (true, a.IsScheduled); Assert.AreEqual (true, b.IsScheduled); Assert.AreEqual (true, c.IsRunning); } /*[Test] public void TestManyJobs () { var timer = System.Diagnostics.Stopwatch.StartNew (); scheduler = new Scheduler ("TestManyJobs"); // First add some long running jobs for (int i = 0; i < 100; i++) { scheduler.Add (new TestJob (20, PriorityHints.LongRunning, Resource.Cpu)); } // Then add some normal jobs that will prempt them for (int i = 0; i < 100; i++) { scheduler.Add (new TestJob (10, PriorityHints.None, Resource.Cpu)); } // Then add some SpeedSensitive jobs that will prempt all of them for (int i = 0; i < 100; i++) { scheduler.Add (new TestJob (5, PriorityHints.SpeedSensitive, Resource.Cpu)); } while (scheduler.Jobs.Count > 0); Log.DebugFormat ("Took {0} to schedule and process all jobs", timer.Elapsed); //scheduler.StopAll (); }*/ /*[Test] public void TestCannotDisposeWhileDatalossJobsScheduled () { scheduler = new Scheduler (); TestJob loss_job; scheduler.Add (new TestJob (200, PriorityHints.SpeedSensitive, Resource.Cpu)); scheduler.Add (loss_job = new TestJob (200, PriorityHints.DataLossIfStopped, Resource.Cpu)); AssertJobsRunning (1); Assert.AreEqual (false, scheduler.JobInfo[loss_job].IsRunning); try { //scheduler.StopAll (); Assert.Fail ("Cannot stop with dataloss job scheduled"); } catch { } } public void TestCannotDisposeWhileDatalossJobsRunning () { scheduler = new Scheduler (); scheduler.Add (new TestJob (200, PriorityHints.DataLossIfStopped, Resource.Cpu)); AssertJobsRunning (1); try { //scheduler.StopAll (); Assert.Fail ("Cannot stop with dataloss job running"); } catch { } }*/ private void AssertJobsRunning (int count) { Assert.AreEqual (count, scheduler.Jobs.Count (j => j.IsRunning)); } private class TestJob : SimpleAsyncJob { internal static int job_count; int iteration; int sleep_time; public TestJob (int sleep_time, PriorityHints hints, params Resource [] resources) : base (String.Format ("{0} ( {1}, {2})", job_count++, hints, resources.Aggregate ("", (a, b) => a += b.Id + " ")), hints, resources) { this.sleep_time = sleep_time; } protected override void Run () { for (int i = 0; !IsCancelRequested && i < 2; i++) { YieldToScheduler (); Hyena.Log.DebugFormat ("{0} iteration {1}", Title, iteration++); System.Threading.Thread.Sleep (sleep_time); } OnFinished (); } } } } #endif hyena-0.5/Hyena/Hyena.Jobs/Scheduler.cs0000644000175000001440000001524611377105342020063 0ustar00gabeusers00000000000000// // Scheduler.cs // // Author: // Gabriel Burt // // Copyright (C) 2009 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Linq; using System.Threading; using System.Collections.Generic; using System.Collections.ObjectModel; using Hyena; namespace Hyena.Jobs { public class Scheduler { private List jobs; public event Action JobAdded; public event Action JobRemoved; public IEnumerable Jobs { get; private set; } public int JobCount { get { lock (jobs) { return jobs.Count; } } } public bool HasAnyDataLossJobs { get { lock (jobs) { return jobs.With (PriorityHints.DataLossIfStopped).Any (); } } } public Scheduler () { jobs = new List (); Jobs = new ReadOnlyCollection (jobs); } public void Add (Job job) { lock (jobs) { lock (job) { if (jobs.Contains (job) || job.HasScheduler) { throw new ArgumentException ("Job not schedulable", "job"); } job.HasScheduler = true; } jobs.Add (job); job.State = JobState.Scheduled; job.Finished += OnJobFinished; if (CanStart (job)) { StartJob (job); } } Action handler = JobAdded; if (handler != null) { handler (job); } } public void Cancel (Job job) { lock (jobs) { if (jobs.Contains (job)) { // Cancel will call OnJobFinished which will call Schedule job.Cancel (); } } } public void Pause (Job job) { lock (jobs) { if (jobs.Contains (job)) { if (job.Pause ()) { // See if any scheduled jobs can now be started Schedule (); } } } } public void Resume (Job job) { lock (jobs) { if (jobs.Contains (job) && CanStartJob (job, true)) { StartJob (job); } } } public void CancelAll (bool evenDataLossJobs) { lock (jobs) { List jobs_copy = new List (jobs); foreach (var job in jobs_copy) { if (evenDataLossJobs || !job.Has (PriorityHints.DataLossIfStopped)) { job.Cancel (); } } } } private void OnJobFinished (object o, EventArgs args) { Job job = o as Job; lock (jobs) { jobs.Remove (job); } Action handler = JobRemoved; if (handler != null) { handler (job); } Schedule (); } private void Schedule () { lock (jobs) { // First try to start any non-LongRunning jobs jobs.Without (PriorityHints.LongRunning) .Where (CanStart) .ForEach (StartJob); // Then start any LongRunning ones jobs.With (PriorityHints.LongRunning) .Where (CanStart) .ForEach (StartJob); } } #region Job Query helpers private bool IsRunning (Job job) { return job.IsRunning; } private bool CanStart (Job job) { return CanStartJob (job, false); } private bool CanStartJob (Job job, bool pausedJob) { if (!job.IsScheduled && !(pausedJob && job.IsPaused)) return false; if (job.Has (PriorityHints.SpeedSensitive)) return true; // Run only one non-SpeedSensitive job that uses a given Resource if (job.Has (PriorityHints.LongRunning)) return jobs.Where (IsRunning) .SharingResourceWith (job) .Any () == false; // With the exception that non-LongRunning jobs will preempt LongRunning ones return jobs.Where (IsRunning) .Without (PriorityHints.LongRunning) .SharingResourceWith (job) .Any () == false; } private void StartJob (Job job) { ConflictingJobs (job).ForEach (PreemptJob); job.Start (); } private void PreemptJob (Job job) { job.Preempt (); } private IEnumerable ConflictingJobs (Job job) { if (job.Has (PriorityHints.SpeedSensitive)) { // Preempt non-SpeedSensitive jobs that use the same Resource(s) return jobs.Where (IsRunning) .Without (PriorityHints.SpeedSensitive) .SharingResourceWith (job); } else if (!job.Has (PriorityHints.LongRunning)) { // Preempt any LongRunning jobs that use the same Resource(s) return jobs.Where (IsRunning) .With (PriorityHints.LongRunning) .SharingResourceWith (job); } return Enumerable.Empty (); } #endregion } } hyena-0.5/Hyena/Hyena.Jobs/SimpleAsyncJob.cs0000644000175000001440000000463711377105342021031 0ustar00gabeusers00000000000000// // SimpleAsyncJob.cs // // Author: // Gabriel Burt // // Copyright (C) 2009 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Linq; using System.Threading; using System.Collections.Generic; using System.Collections.ObjectModel; namespace Hyena.Jobs { public abstract class SimpleAsyncJob : Job { private Thread thread; public SimpleAsyncJob () { } public SimpleAsyncJob (string name, PriorityHints hints, params Resource [] resources) : base (name, hints, resources) { } protected override void RunJob () { if (thread == null) { thread = new Thread (InnerStart); thread.Name = String.Format ("Hyena.Jobs.JobRunner ({0})", Title); thread.Priority = this.Has (PriorityHints.SpeedSensitive) ? ThreadPriority.Normal : ThreadPriority.Lowest; thread.Start (); } } protected void AbortThread () { if (thread != null) { thread.Abort (); } } private void InnerStart () { try { Run (); } catch (ThreadAbortException) { } catch (Exception e) { Log.Exception (e); } } protected abstract void Run (); } } hyena-0.5/Hyena/Hyena.Jobs/PriorityHints.cs0000644000175000001440000000255511377105342020773 0ustar00gabeusers00000000000000// // PriorityHints.cs // // Author: // Gabriel Burt // // Copyright (C) 2009 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; namespace Hyena.Jobs { [Flags] public enum PriorityHints { None = 0, DataLossIfStopped = 1, SpeedSensitive = 2, LongRunning = 4 } } hyena-0.5/Hyena/Hyena.Jobs/Resource.cs0000644000175000001440000000322011377105342017721 0ustar00gabeusers00000000000000// // Resource.cs // // Author: // Gabriel Burt // // Copyright (C) 2009 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; namespace Hyena.Jobs { public class Resource { // Convenience Resources for programs to use public static readonly Resource Cpu = new Resource { Id = "cpu", Name = "CPU" }; public static readonly Resource Disk = new Resource { Id = "disk", Name = "Disk" }; public static readonly Resource Database = new Resource { Id = "db", Name = "Database" }; public string Id { get; set; } public string Name { get; set; } } } hyena-0.5/Hyena/Hyena.CommandLine/0000777000175000001440000000000011453151001017067 5ustar00gabeusers00000000000000hyena-0.5/Hyena/Hyena.CommandLine/LayoutOption.cs0000644000175000001440000000316711377105342022103 0ustar00gabeusers00000000000000// // LayoutOption.cs // // Author: // Aaron Bockover // // Copyright (C) 2007 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // namespace Hyena.CommandLine { public class LayoutOption { private string name; private string description; public LayoutOption (string name, string description) { this.name = name; this.description = description; } public string Name { get { return name; } } public string Description { get { return description; } } } } hyena-0.5/Hyena/Hyena.CommandLine/LayoutGroup.cs0000644000175000001440000000646211377105342021730 0ustar00gabeusers00000000000000// // LayoutGroup.cs // // Author: // Aaron Bockover // // Copyright (C) 2007 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Collections.Generic; namespace Hyena.CommandLine { public class LayoutGroup : IEnumerable { private List options; private string id; private string title; public LayoutGroup (string id, string title, List options) { this.id = id; this.title = title; this.options = options; } public LayoutGroup (string id, string title, params LayoutOption [] options) : this (id, title, new List (options)) { } public IEnumerator GetEnumerator () { return options.GetEnumerator (); } System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator () { return GetEnumerator (); } public void Add (LayoutOption option) { options.Add (option); } public void Add (string name, string description) { options.Add (new LayoutOption (name, description)); } public void Remove (LayoutOption option) { options.Remove (option); } public void Remove (string optionName) { LayoutOption option = FindOption (optionName); if (option != null) { options.Remove (option); } } private LayoutOption FindOption (string name) { foreach (LayoutOption option in options) { if (option.Name == name) { return option; } } return null; } public LayoutOption this[int index] { get { return options[index]; } set { options[index] = value; } } public int Count { get { return options.Count; } } public string Id { get { return id; } } public string Title { get { return title; } } public IList Options { get { return options; } } } } hyena-0.5/Hyena/Hyena.CommandLine/Layout.cs0000644000175000001440000001414511377105342020710 0ustar00gabeusers00000000000000// // Layout.cs // // Author: // Aaron Bockover // // Copyright (C) 2007 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Text; using System.Collections.Generic; namespace Hyena.CommandLine { public class Layout { private List groups; public Layout (List groups) { this.groups = groups; } public Layout (params LayoutGroup [] groups) : this (new List (groups)) { } private int TerminalWidth { get { return Console.WindowWidth <= 0 ? 80 : Console.WindowWidth; } } public string ToString (params string [] groupIds) { return ToString (GroupIdsToGroups (groupIds)); } public override string ToString () { return ToString (groups); } public string ToString (IEnumerable groups) { StringBuilder builder = new StringBuilder (); int min_spacing = 6; int group_index = 0; int group_count = 0; int max_option_length = 0; int max_description_length = 0; int description_alignment = 0; foreach (LayoutGroup group in groups) { foreach (LayoutOption option in group) { if (option.Name.Length > max_option_length) { max_option_length = option.Name.Length; } } } max_description_length = TerminalWidth - max_option_length - min_spacing - 4; description_alignment = max_option_length + min_spacing + 4; IEnumerator enumerator = groups.GetEnumerator (); while (enumerator.MoveNext ()) { group_count++; } foreach (LayoutGroup group in groups) { if (group.Id != "default") { builder.Append (group.Title); builder.AppendLine (); builder.AppendLine (); } for (int i = 0, n = group.Count; i < n; i++) { int spacing = (max_option_length - group[i].Name.Length) + min_spacing; builder.AppendFormat (" --{0}{2}{1}", group[i].Name, WrapAlign (group[i].Description, max_description_length, description_alignment, i == n - 1), String.Empty.PadRight (spacing)); builder.AppendLine (); } if (group_index++ < group_count - 1) { builder.AppendLine (); } } return builder.ToString (); } public string LayoutLine (string str) { return WrapAlign (str, TerminalWidth, 0, true); } private static string WrapAlign (string str, int width, int align, bool last) { StringBuilder builder = new StringBuilder (); bool did_wrap = false; for (int i = 0, b = 0; i < str.Length; i++, b++) { if (str[i] == ' ') { int word_length = 0; for (int j = i + 1; j < str.Length && str[j] != ' '; word_length++, j++); if (b + word_length >= width) { builder.AppendLine (); builder.Append (String.Empty.PadRight (align)); b = 0; did_wrap = true; continue; } } builder.Append (str[i]); } if (did_wrap && !last) { builder.AppendLine (); } return builder.ToString (); } public void Add (LayoutGroup group) { groups.Add (group); } public void Remove (LayoutGroup group) { groups.Remove (group); } public void Remove (string groupId) { LayoutGroup group = FindGroup (groupId); if (group != null) { groups.Remove (group); } } private LayoutGroup FindGroup (string id) { foreach (LayoutGroup group in groups) { if (group.Id == id) { return group; } } return null; } private IEnumerable GroupIdsToGroups (string [] groupIds) { foreach (string group_id in groupIds) { LayoutGroup group = FindGroup (group_id); if (group != null) { yield return group; } } } public static LayoutOption Option (string name, string description) { return new LayoutOption (name, description); } public static LayoutGroup Group (string id, string title, params LayoutOption [] options) { return new LayoutGroup (id, title, options); } } } hyena-0.5/Hyena/Hyena.CommandLine/CommandLineParser.cs0000644000175000001440000001330511377105342022773 0ustar00gabeusers00000000000000// // CommandLineParser.cs // // Author: // Aaron Bockover // // Copyright (C) 2007 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Collections.Generic; using System.Collections.ObjectModel; namespace Hyena.CommandLine { public class CommandLineParser { private struct Argument { public int Order; public string Value; public Argument (int order, string value) { Order = order; Value = value; } } private int generation; private int sorted_args_generation; private int offset; private string [] arguments; private KeyValuePair [] sorted_args; private Dictionary parsed_arguments = new Dictionary (); private List file_list = new List (); public CommandLineParser () : this (Environment.GetCommandLineArgs (), 1) { } public CommandLineParser (string [] arguments, int offset) { this.arguments = arguments; this.offset = offset; Parse (); } private void Parse () { for (int i = offset; i < arguments.Length; i++) { if (!IsOption (arguments[i])) { file_list.Add (arguments[i]); continue; } string name = OptionName (arguments[i]); string value = String.Empty; int eq_offset = name.IndexOf ('='); if (eq_offset > 1) { value = name.Substring (eq_offset + 1); name = name.Substring (0, eq_offset); } if (parsed_arguments.ContainsKey (name)) { parsed_arguments[name] = new Argument (i, value); } else { parsed_arguments.Add (name, new Argument (i, value)); } } } private bool IsOption (string argument) { return argument.Length > 2 && argument.Substring (0, 2) == "--"; } private string OptionName (string argument) { return argument.Substring (2); } public bool Contains (string name) { return parsed_arguments.ContainsKey (name); } public bool ContainsStart (string start) { foreach (string argument in parsed_arguments.Keys) { if (argument.StartsWith (start)) { return true; } } return false; } public string this[string name] { get { return Contains (name) ? parsed_arguments[name].Value : String.Empty; } set { Argument arg = parsed_arguments[name]; arg.Value = value; parsed_arguments[name] = arg; generation++; } } public IEnumerable> Arguments { get { if (sorted_args == null || sorted_args_generation != generation) { sorted_args = new KeyValuePair[parsed_arguments.Count]; int i = 0; foreach (KeyValuePair arg in parsed_arguments) { sorted_args[i++] = arg; } Array.Sort (sorted_args, delegate (KeyValuePair a, KeyValuePair b) { return a.Value.Order.CompareTo (b.Value.Order); }); sorted_args_generation = generation; } foreach (KeyValuePair arg in sorted_args) { yield return new KeyValuePair (arg.Key, arg.Value.Value); } } } public ReadOnlyCollection Files { get { return new ReadOnlyCollection (file_list); } } public override string ToString () { System.Text.StringBuilder builder = new System.Text.StringBuilder (); builder.Append ("Parsed Arguments\n"); foreach (KeyValuePair argument in parsed_arguments) { builder.AppendFormat (" {0} = [{1}]\n", argument.Key, argument.Value.Value); } builder.Append ("\nFile List\n"); foreach (string file in file_list) { builder.AppendFormat ("{0}\n", file); } return builder.ToString (); } } } hyena-0.5/Hyena/Makefile.am0000644000175000001440000001052011452674367015714 0ustar00gabeusers00000000000000ASSEMBLY = Hyena TARGET = library LINK = -r:Mono.Posix -r:System -r:System.Core $(GLIBSHARP_LIBS) SOURCES = \ Hyena.Collections/CollectionExtensions.cs \ Hyena.Collections/IntervalHeap.cs \ Hyena.Collections/IStackProvider.cs \ Hyena.Collections/LruCache.cs \ Hyena.Collections/QueuePipeline.cs \ Hyena.Collections/QueuePipelineElement.cs \ Hyena.Collections/RangeCollection.cs \ Hyena.Collections/Selection.cs \ Hyena.Collections/SelectionProxy.cs \ Hyena.Collections/Tests/IntervalHeapTests.cs \ Hyena.Collections/Tests/QueuePipelineTests.cs \ Hyena.Collections/Tests/RangeCollectionTests.cs \ Hyena.Collections/WriteLineElement.cs \ Hyena.CommandLine/CommandLineParser.cs \ Hyena.CommandLine/Layout.cs \ Hyena.CommandLine/LayoutGroup.cs \ Hyena.CommandLine/LayoutOption.cs \ Hyena.Data/ArrayModelCache.cs \ Hyena.Data/BaseListModel.cs \ Hyena.Data/ColumnDescription.cs \ Hyena.Data/DictionaryModelCache.cs \ Hyena.Data/ICacheableItem.cs \ Hyena.Data/ICacheableModel.cs \ Hyena.Data/ICareAboutView.cs \ Hyena.Data/IFilterable.cs \ Hyena.Data/IListModel.cs \ Hyena.Data/IPropertyStoreExpose.cs \ Hyena.Data/ISelectable.cs \ Hyena.Data/ISortable.cs \ Hyena.Data/ISortableColumn.cs \ Hyena.Data/MemoryListModel.cs \ Hyena.Data/ModelCache.cs \ Hyena.Data/ModelSelection.cs \ Hyena.Data/PropertyStore.cs \ Hyena.Data/SortType.cs \ Hyena.Downloader/Buffer.cs \ Hyena.Downloader/DownloadManager.cs \ Hyena.Downloader/DownloadManagerJob.cs \ Hyena.Downloader/HttpDownloader.cs \ Hyena.Downloader/HttpDownloaderState.cs \ Hyena.Downloader/HttpFileDownloader.cs \ Hyena.Downloader/HttpStringDownloader.cs \ Hyena.Downloader/Tests/HttpTestServer.cs \ Hyena.Downloader/Tests/Tests.cs \ Hyena.Jobs/Job.cs \ Hyena.Jobs/JobExtensions.cs \ Hyena.Jobs/PriorityHints.cs \ Hyena.Jobs/Resource.cs \ Hyena.Jobs/Scheduler.cs \ Hyena.Jobs/SimpleAsyncJob.cs \ Hyena.Jobs/Tests/SchedulerTests.cs \ Hyena.Json/Deserializer.cs \ Hyena.Json/IJsonCollection.cs \ Hyena.Json/JsonArray.cs \ Hyena.Json/JsonObject.cs \ Hyena.Json/Serializer.cs \ Hyena.Json/Tests/DeserializerTests.cs \ Hyena.Json/Tests/SerializerTests.cs \ Hyena.Json/Tests/TokenizerTests.cs \ Hyena.Json/Token.cs \ Hyena.Json/Tokenizer.cs \ Hyena.Json/TokenType.cs \ Hyena.Query/AliasedObjectSet.cs \ Hyena.Query/DateQueryValue.cs \ Hyena.Query/EnumQueryValue.cs \ Hyena.Query/ExactStringQueryValue.cs \ Hyena.Query/ExactUriStringQueryValue.cs \ Hyena.Query/FileSizeQueryValue.cs \ Hyena.Query/IntegerKeyedObjectQueryValue.cs \ Hyena.Query/IntegerQueryValue.cs \ Hyena.Query/NullQueryValue.cs \ Hyena.Query/QueryField.cs \ Hyena.Query/QueryFieldSet.cs \ Hyena.Query/QueryLimit.cs \ Hyena.Query/QueryListNode.cs \ Hyena.Query/QueryNode.cs \ Hyena.Query/QueryOperator.cs \ Hyena.Query/QueryOrder.cs \ Hyena.Query/QueryParser.cs \ Hyena.Query/QueryTermNode.cs \ Hyena.Query/QueryToken.cs \ Hyena.Query/QueryValue.cs \ Hyena.Query/RelativeTimeSpanQueryValue.cs \ Hyena.Query/StringQueryValue.cs \ Hyena.Query/Tests/QueryTests.cs \ Hyena.Query/TimeSpanQueryValue.cs \ Hyena.Query/UserQueryParser.cs \ Hyena.Query/XmlQueryParser.cs \ Hyena.SExpEngine/ArithmeticFunctionSet.cs \ Hyena.SExpEngine/CastFunctionSet.cs \ Hyena.SExpEngine/CompareFunctionSet.cs \ Hyena.SExpEngine/ControlFunctionSet.cs \ Hyena.SExpEngine/Evaluator.cs \ Hyena.SExpEngine/EvaluatorBase.cs \ Hyena.SExpEngine/FunctionFunctionSet.cs \ Hyena.SExpEngine/FunctionNode.cs \ Hyena.SExpEngine/FunctionSet.cs \ Hyena.SExpEngine/ListFunctionSet.cs \ Hyena.SExpEngine/Literals.cs \ Hyena.SExpEngine/LogicFunctionSet.cs \ Hyena.SExpEngine/Parser.cs \ Hyena.SExpEngine/StringFunctionSet.cs \ Hyena.SExpEngine/TreeNode.cs \ Hyena.SExpEngine/UtilityFunctionSet.cs \ Hyena/ApplicationContext.cs \ Hyena/ConsoleCrayon.cs \ Hyena/CryptoUtil.cs \ Hyena/DateTimeUtil.cs \ Hyena/Delegates.cs \ Hyena/EventArgs.cs \ Hyena/IUndoAction.cs \ Hyena/Log.cs \ Hyena/Paths.cs \ Hyena/PlatformDetection.cs \ Hyena/SafeUri.cs \ Hyena/StringUtil.cs \ Hyena/Tests/CryptoUtilTests.cs \ Hyena/Tests/DateTimeUtilTests.cs \ Hyena/Tests/StringUtilTests.cs \ Hyena/Tests/TestBase.cs \ Hyena/ThreadAssist.cs \ Hyena/Timer.cs \ Hyena/UndoManager.cs \ Hyena/XdgBaseDirectorySpec.cs \ System.Web/Helpers.cs \ System.Web/HttpUtility.cs include $(top_srcdir)/build/build.mk EXTRA_DIST += Hyena.dll.config module_SCRIPTS += Hyena.dll.config hyena-0.5/Hyena/Hyena.Query/0000777000175000001440000000000011453151002016007 5ustar00gabeusers00000000000000hyena-0.5/Hyena/Hyena.Query/QueryOperator.cs0000644000175000001440000000504011377105342021165 0ustar00gabeusers00000000000000// // QueryOperator.cs // // Author: // Aaron Bockover // Gabriel Burt // // Copyright (C) 2007-2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Xml; using System.Text; using System.Collections.Generic; namespace Hyena.Query { public class Operator : IAliasedObject { public string name; public string Name { get { return name; } } public string label; public string Label { get { return label ?? Name; } set { label = value; } } private string [] aliases; public string [] Aliases { get { return aliases; } } public string PrimaryAlias { get { return aliases [0]; } } private string sql_format; public string SqlFormat { get { return sql_format; } } // FIXME get rid of this private bool is_not; public bool IsNot { get { return is_not; } } internal Operator (string name, string label, string sql_format, params string [] userOps) : this (name, label, sql_format, false, userOps) { } internal Operator (string name, string label, string sql_format, bool is_not, params string [] userOps) { this.name = name; this.label = label; this.sql_format = sql_format; this.aliases = userOps; this.is_not = is_not; } } } hyena-0.5/Hyena/Hyena.Query/FileSizeQueryValue.cs0000644000175000001440000001144311377105342022105 0ustar00gabeusers00000000000000// // FileSizeQueryValue.cs // // Authors: // Gabriel Burt // Aaron Bockover // // Copyright (C) 2007-2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Xml; using System.Text; using Hyena; namespace Hyena.Query { public enum FileSizeFactor : long { None = 1, KB = 1024, MB = 1048576, GB = 1073741824, TB = 1099511627776, PB = 1125899906842624 } public class FileSizeQueryValue : IntegerQueryValue { private FileSizeFactor factor = FileSizeFactor.None; public FileSizeFactor Factor { get { return factor; } } public FileSizeQueryValue () { } public FileSizeQueryValue (long bytes) { value = bytes; IsEmpty = false; DetermineFactor (); } public double FactoredValue { get { return (double)value / (double)factor; } } public override void ParseUserQuery (string input) { if (input.Length > 1 && (input[input.Length - 1] == 'b' || input[input.Length - 1] == 'B')) { input = input.Substring (0, input.Length - 1); } double double_value; IsEmpty = !Double.TryParse (input, out double_value); if (IsEmpty && input.Length > 1) { IsEmpty = !Double.TryParse (input.Substring (0, input.Length - 1), out double_value); } if (!IsEmpty) { switch (input[input.Length - 1]) { case 'k': case 'K': factor = FileSizeFactor.KB; break; case 'm': case 'M': factor = FileSizeFactor.MB; break; case 'g': case 'G': factor = FileSizeFactor.GB; break; case 't': case 'T': factor = FileSizeFactor.TB; break; case 'p': case 'P': factor = FileSizeFactor.PB; break; default : factor = FileSizeFactor.None; break; } value = (long)((double)factor * double_value); } } public override void ParseXml (XmlElement node) { base.ParseUserQuery (node.InnerText); if (node.HasAttribute ("factor")) { this.factor = (FileSizeFactor) Enum.Parse (typeof(FileSizeFactor), node.GetAttribute ("factor")); } else { DetermineFactor (); } } public override void AppendXml (XmlElement node) { base.AppendXml (node); node.SetAttribute ("factor", factor.ToString ()); } public void SetValue (double value, FileSizeFactor factor) { this.value = (long)(value * (double)factor); this.factor = factor; IsEmpty = false; } protected void DetermineFactor () { if (!IsEmpty && value != 0) { foreach (FileSizeFactor factor in Enum.GetValues (typeof(FileSizeFactor))) { if (value >= (double)factor) { this.factor = factor; } } } } public override string ToUserQuery () { return ToUserQuery (false); } public string ToUserQuery (bool always_decimal) { if (factor != FileSizeFactor.None) { return String.Format ("{0} {1}", IntValue == 0 ? "0" : StringUtil.DoubleToTenthsPrecision (((double)IntValue / (double)factor), always_decimal), factor.ToString () ); } else { return base.ToUserQuery (); } } } } hyena-0.5/Hyena/Hyena.Query/StringQueryValue.cs0000644000175000001440000000731511377105342021644 0ustar00gabeusers00000000000000// // StringQueryValue.cs // // Authors: // Gabriel Burt // // Copyright (C) 2007-2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Xml; using System.Text; using Mono.Unix; using Hyena; namespace Hyena.Query { public class StringQueryValue : QueryValue { private const string ESCAPE_CLAUSE = " ESCAPE '\\'"; public static readonly Operator Contains = new Operator ("contains", Catalog.GetString ("contains"), "LIKE '%{0}%'" + ESCAPE_CLAUSE, ":"); public static readonly Operator DoesNotContain = new Operator ("doesNotContain", Catalog.GetString ("doesn't contain"), "NOT LIKE '%{0}%'" + ESCAPE_CLAUSE, true, "!:"); public static readonly Operator Equal = new Operator ("equals", Catalog.GetString ("is"), "= '{0}'", "=="); public static readonly Operator NotEqual = new Operator ("notEqual", Catalog.GetString ("is not"), "!= '{0}'", true, "!="); public static readonly Operator StartsWith = new Operator ("startsWith", Catalog.GetString ("starts with"), "LIKE '{0}%'" + ESCAPE_CLAUSE, "="); public static readonly Operator EndsWith = new Operator ("endsWith", Catalog.GetString ("ends with"), "LIKE '%{0}'" + ESCAPE_CLAUSE, ":="); protected string value; public override string XmlElementName { get { return "string"; } } public override object Value { get { return value; } } protected static AliasedObjectSet operators = new AliasedObjectSet (Contains, DoesNotContain, Equal, NotEqual, StartsWith, EndsWith); public override AliasedObjectSet OperatorSet { get { return operators; } } public override void ParseUserQuery (string input) { value = input; IsEmpty = String.IsNullOrEmpty (value); } public override void ParseXml (XmlElement node) { value = node.InnerText; IsEmpty = String.IsNullOrEmpty (value); } public override void LoadString (string str) { ParseUserQuery (str); } public override string ToSql (Operator op) { return String.IsNullOrEmpty (value) ? null : EscapeString (op, Hyena.StringUtil.SearchKey (value)); } protected static string EscapeString (Operator op, string orig) { orig = orig.Replace ("'", "''"); if (op == Contains || op == DoesNotContain || op == StartsWith || op == EndsWith) { return StringUtil.EscapeLike (orig); } return orig; } } } hyena-0.5/Hyena/Hyena.Query/IntegerKeyedObjectQueryValue.cs0000644000175000001440000000341211377105342024076 0ustar00gabeusers00000000000000// // IntegerKeyedObjectQueryValue.cs // // Authors: // Scott Peterson // // Copyright (C) 2008 Scott Peterson // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; namespace Hyena.Query { public abstract class IntegerKeyedObjectQueryValue : IntegerQueryValue where T : class { private T object_value; public override void SetValue (long value) { object_value = null; base.SetValue (value); } public T ObjectValue { get { if (object_value == null) { object_value = Resolve (); } return object_value; } } protected abstract T Resolve (); } } hyena-0.5/Hyena/Hyena.Query/UserQueryParser.cs0000644000175000001440000002120611377105342021467 0ustar00gabeusers00000000000000// // UserQueryParser.cs // // Author: // Aaron Bockover // Gabriel Burt // // Copyright (C) 2007-2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.IO; using System.Text; namespace Hyena.Query { public class UserQueryParser : QueryParser { private QueryListNode current_parent; private char peek; private int current_column; private int current_line; private int token_start_column; private int token_start_line; private bool eos_consumed; private QueryListNode root; private QueryFieldSet field_set; public static QueryNode Parse (string input, QueryFieldSet fieldSet) { return new UserQueryParser (input).BuildTree (fieldSet); } public UserQueryParser () : base () {} public UserQueryParser (string inputQuery) : base (inputQuery) {} public UserQueryParser (Stream stream) : base (stream) {} public UserQueryParser (StreamReader reader) : base (reader) {} public override QueryNode BuildTree (QueryFieldSet fieldSet) { field_set = fieldSet; root = current_parent = new QueryListNode (Keyword.And); bool last_was_term = false; while (true) { QueryToken token = Scan (); if (token.ID == TokenID.Unknown) { break; } token.Column = token_start_column; token.Line = token_start_line; // If we have two terms in a row, put an AND between them if (last_was_term && token.ID == TokenID.Term) ParseToken (new QueryToken (TokenID.And)); ParseToken (token); last_was_term = token.ID == TokenID.Term; } return root.Trim (); } private void DepthPush () { current_parent = new QueryListNode (Keyword.And, current_parent); } private void DepthPop () { // Avoid trying to pop more than is possible if (current_parent.Parent != null) current_parent = current_parent.Parent; } private void NodePush (QueryNode node) { if (current_parent == null && node is QueryListNode) { root = current_parent = node as QueryListNode; return; } if (current_parent.Keyword == Keyword.Not && current_parent.ChildCount == 1) DepthPop (); current_parent.AddChild (node); // If the node is a list, it's our new parent QueryListNode list = node as QueryListNode; if (list != null) { current_parent = list; } } private void ParseToken (QueryToken token) { switch (token.ID) { case TokenID.OpenParen: DepthPush (); break; case TokenID.CloseParen: DepthPop (); break; case TokenID.Not: NodePush (new QueryListNode (Keyword.Not)); break; case TokenID.Or: case TokenID.And: // Only push a node if the current_parent is not the same as this token if (current_parent.Keyword == Keyword.Not || current_parent.Keyword == (token.ID == TokenID.Or ? Keyword.And : Keyword.Or)) { QueryListNode list = new QueryListNode (token.ID == TokenID.Or ? Keyword.Or : Keyword.And); QueryListNode p = current_parent.Parent; if (p != null) { current_parent.Parent.RemoveChild (current_parent); } if (current_parent.Keyword == Keyword.Not || current_parent.ChildCount > 1) { list.AddChild (current_parent); } else { list.TakeChildren (current_parent); } current_parent = p; NodePush (list); } break; case TokenID.Term: NodePush (QueryTermNode.ParseUserQuery (field_set, token.Term)); break; } } private QueryToken Scan () { if (reader.EndOfStream) { if (eos_consumed) return new QueryToken (TokenID.Unknown); else eos_consumed = true; } for (; ; ReadChar ()) { if (Char.IsWhiteSpace (peek) && peek != '\n') { continue; } else if (peek == '\n') { current_line++; current_column = 0; } else { break; } } token_start_column = current_column; token_start_line = current_line; if (peek == '(') { ReadChar (); return new QueryToken (TokenID.OpenParen); } else if (peek == ')') { ReadChar (); return new QueryToken (TokenID.CloseParen); } else if (peek == '-') { ReadChar (); return new QueryToken (TokenID.Not); } else if (peek == '|' || peek == ',') { ReadChar (); return new QueryToken (TokenID.Or); } else { string token = ScanString (); if (reader.EndOfStream) eos_consumed = true; switch (token) { case "or": case "OR": return new QueryToken (TokenID.Or); case "NOT": return new QueryToken (TokenID.Not); default: return new QueryToken (token); } } } // TODO: Allow white space before/after term operators private bool IsStringTerminationChar (char ch) { return Char.IsWhiteSpace (ch) || ch == '(' || ch == ')' || ch == '|' || ch == ','; } private string ScanString () { StringBuilder buffer = new StringBuilder (); bool in_string = false; while (true) { if (!in_string && IsStringTerminationChar (peek)) { break; } else if (peek == '"') { in_string = !in_string; } else { buffer.Append (peek); if (reader.EndOfStream) { break; } } ReadChar (); if (reader.EndOfStream) { if (!IsStringTerminationChar (peek) && peek != '"') { buffer.Append (peek); } break; } } return buffer.ToString (); } public override void Reset () { peek = ' '; current_column = 0; current_line = 0; token_start_column = 0; token_start_line = 0; } private void ReadChar () { if (peek == Char.MinValue) { return; } peek = (char)reader.Read (); current_column++; } } } hyena-0.5/Hyena/Hyena.Query/QueryField.cs0000644000175000001440000001445311377105342020425 0ustar00gabeusers00000000000000// // QueryField.cs // // Authors: // Gabriel Burt // Aaron Bockover // // Copyright (C) 2007-2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Text; using System.Collections.Generic; namespace Hyena.Query { public class QueryField : IAliasedObject { private bool no_custom_format; private bool column_lowered; private Type [] value_types; public Type [] ValueTypes { get { return value_types; } } private string name; public string Name { get { return name; } set { name = value; } } private string property_name; public string PropertyName { get { return property_name; } set { property_name = value; } } private string label; public string Label { get { return label; } set { label = value; } } private string short_label; public string ShortLabel { get { return short_label ?? label; } set { short_label = value; } } private string [] aliases; public string [] Aliases { get { return aliases; } } public string PrimaryAlias { get { return aliases[0]; } } private string column; public string Column { get { return column; } } private bool is_default; public bool IsDefault { get { return is_default; } } public QueryField (string name, string propertyName, string label, string column, params string [] aliases) : this (name, propertyName, label, column, false, aliases) { } public QueryField (string name, string propertyName, string label, string column, bool isDefault, params string [] aliases) : this (name, propertyName, label, column, new Type [] {typeof(StringQueryValue)}, isDefault, aliases) { } public QueryField (string name, string propertyName, string label, string column, Type valueType, params string [] aliases) : this (name, propertyName, label, column, new Type [] {valueType}, false, aliases) { } public QueryField (string name, string propertyName, string label, string column, Type [] valueTypes, params string [] aliases) : this (name, propertyName, label, column, valueTypes, false, aliases) { } public QueryField (string name, string propertyName, string label, string column, Type [] valueTypes, bool isDefault, params string [] aliases) { this.name = name; this.property_name = propertyName; this.label = label; this.column = column; this.value_types = valueTypes; this.is_default = isDefault; this.aliases = aliases; this.no_custom_format = (Column.IndexOf ("{0}") == -1 && Column.IndexOf ("{1}") == -1); this.column_lowered = (Column.IndexOf ("Lowered") != -1); if (!no_custom_format) { // Ensure we have parens around any custom 'columns' that may be an OR of two columns this.column = String.Format ("({0})", this.column); } foreach (Type value_type in valueTypes) { QueryValue.AddValueType (value_type); } } public IEnumerable CreateQueryValues () { foreach (Type type in ValueTypes) { yield return Activator.CreateInstance (type) as QueryValue; } } public string ToTermString (string op, string value) { return ToTermString (PrimaryAlias, op, value); } public string ToSql (Operator op, QueryValue qv) { string value = qv.ToSql (op) ?? String.Empty; if (op == null) op = qv.OperatorSet.First; StringBuilder sb = new StringBuilder (); if (no_custom_format) { string column_with_key = Column; if (qv is StringQueryValue && !(column_lowered || qv is ExactStringQueryValue)) { column_with_key = String.Format ("HYENA_SEARCH_KEY({0})", Column); } sb.AppendFormat ("{0} {1}", column_with_key, String.Format (op.SqlFormat, value)); if (op.IsNot) { return String.Format ("({0} OR {1} IS NULL)", sb.ToString (), Column); } else { return String.Format ("({0} AND {1} IS NOT NULL)", sb.ToString (), Column); } } else { sb.AppendFormat ( Column, String.Format (op.SqlFormat, value), value, op.IsNot ? "NOT" : null ); } return sb.ToString (); } public static string ToTermString (string alias, string op, string value) { value = String.Format ( "{1}{0}{1}", value, value.IndexOf (" ") == -1 ? String.Empty : "\"" ); return String.IsNullOrEmpty (alias) ? value : String.Format ("{0}{1}{2}", alias, op, value); } } } hyena-0.5/Hyena/Hyena.Query/AliasedObjectSet.cs0000644000175000001440000000707611377105342021524 0ustar00gabeusers00000000000000// // AliasedObjectSet.cs // // Authors: // Gabriel Burt // Aaron Bockover // // Copyright (C) 2007-2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Text; using System.Collections; using System.Collections.Generic; namespace Hyena.Query { public interface IAliasedObject { string Name { get; } string [] Aliases { get; } } public class AliasedObjectSet : IEnumerable where T : IAliasedObject { protected Dictionary map = new Dictionary (); protected List aliases = new List (); protected T [] objects; public AliasedObjectSet (params T [] objects) { this.objects = objects; foreach (T obj in objects) { map [obj.Name.ToLower ()] = obj; foreach (string alias in obj.Aliases) { if (!String.IsNullOrEmpty (alias) && alias.IndexOf (" ") == -1) { foreach (string sub_alias in alias.Split(',')) { string lower_alias = sub_alias.ToLower (); map [lower_alias] = obj; if (!aliases.Contains (lower_alias)) { aliases.Add (lower_alias); } } } } } aliases.Sort (SortByLongest); } private int SortByLongest (string a, string b) { return b.Length.CompareTo (a.Length); } public string FindAlias (string input) { input = input.ToLower (); foreach (string alias in aliases) { if (input.StartsWith (alias)) { return alias; } } return null; } public T [] Objects { get { return objects; } } public T First { get { return objects [0]; } } public IEnumerator GetEnumerator () { foreach (T o in objects) { yield return o; } } IEnumerator IEnumerable.GetEnumerator () { return GetEnumerator (); } public T this [string alias] { get { if (!String.IsNullOrEmpty (alias) && map.ContainsKey (alias.ToLower ())) return map[alias.ToLower ()]; return default(T); } } } } hyena-0.5/Hyena/Hyena.Query/Tests/0000777000175000001440000000000011453151002017111 5ustar00gabeusers00000000000000hyena-0.5/Hyena/Hyena.Query/Tests/QueryTests.cs0000644000175000001440000002337411377105342021610 0ustar00gabeusers00000000000000// // QueryTests.cs // // Author: // Gabriel Burt // // Copyright (C) 2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // #if ENABLE_TESTS using System; using System.Reflection; using NUnit.Framework; using Hyena.Query; namespace Hyena.Query.Tests { [TestFixture] public class QueryTests : Hyena.Tests.TestBase { private static QueryField ArtistField = new QueryField ( "artist", "ArtistName", "Artist", "CoreArtists.NameLowered", true, "by", "artist", "artists" ); private static QueryField AlbumField = new QueryField ( "album", "AlbumTitle", "Album", "CoreAlbums.TitleLowered", true, "on", "album", "from", "albumtitle" ); private static QueryField PlayCountField = new QueryField ( "playcount", "PlayCount", "Play Count", "CoreTracks.PlayCount", typeof(IntegerQueryValue), "plays", "playcount", "numberofplays", "listens" ); private static QueryField DurationField = new QueryField ( "duration", "Duration", "Duration", "CoreTracks.Duration", typeof(TimeSpanQueryValue), "duration", "length", "time" ); private static QueryField MimeTypeField = new QueryField ( "mimetype", "MimeType", "Mime Type", "CoreTracks.MimeType {0} OR CoreTracks.Uri {0}", typeof(ExactStringQueryValue), "type", "mimetype", "format", "ext", "mime" ); private static QueryField UriField = new QueryField ( "uri", "Uri", "File Location", "CoreTracks.Uri", typeof(ExactUriStringQueryValue), "uri", "path", "file", "location" ); private static QueryFieldSet FieldSet = new QueryFieldSet ( ArtistField, AlbumField, PlayCountField, MimeTypeField, DurationField ); [Test] public void QueryValueSql () { QueryValue qv; qv = new DateQueryValue (); qv.ParseUserQuery ("2007-03-9"); Assert.AreEqual (new DateTime (2007, 3, 9), qv.Value); Assert.AreEqual ("2007-03-09", qv.ToUserQuery ()); Assert.AreEqual ("1173420000", qv.ToSql ()); qv = new StringQueryValue (); qv.ParseUserQuery ("foo 'bar'"); Assert.AreEqual ("foo 'bar'", qv.Value); Assert.AreEqual ("foo 'bar'", qv.ToUserQuery ()); Assert.AreEqual ("foo bar", qv.ToSql ()); qv = new StringQueryValue (); qv.ParseUserQuery ("Foo Baño"); Assert.AreEqual ("Foo Baño", qv.Value); Assert.AreEqual ("Foo Baño", qv.ToUserQuery ()); Assert.AreEqual ("foo bano", qv.ToSql ()); qv = new ExactStringQueryValue (); qv.ParseUserQuery ("foo 'bar'"); Assert.AreEqual ("foo 'bar'", qv.Value); Assert.AreEqual ("foo 'bar'", qv.ToUserQuery ()); Assert.AreEqual ("foo ''bar''", qv.ToSql ()); qv = new IntegerQueryValue (); qv.ParseUserQuery ("22"); Assert.AreEqual (22, qv.Value); Assert.AreEqual ("22", qv.ToUserQuery ()); Assert.AreEqual ("22", qv.ToSql ()); qv = new FileSizeQueryValue (); qv.ParseUserQuery ("2048 KB"); Assert.AreEqual (2097152, qv.Value); Assert.AreEqual ("2.048 KB", qv.ToUserQuery ()); Assert.AreEqual ("2097152", qv.ToSql ()); // TODO this will break once an it_IT translation for "days ago" etc is committed qv = new RelativeTimeSpanQueryValue (); qv.ParseUserQuery ("2 days ago"); Assert.AreEqual (-172800, qv.Value); Assert.AreEqual ("2 days ago", qv.ToUserQuery ()); // TODO this will break once an it_IT translation for "minutes" etc is committed qv = new TimeSpanQueryValue (); qv.ParseUserQuery ("4 minutes"); Assert.AreEqual (240, qv.Value); Assert.AreEqual ("4 minutes", qv.ToUserQuery ()); Assert.AreEqual ("240000", qv.ToSql ()); } [Test] public void QueryParsing () { string [] tests = new string [] { "foo", "foo bar", "foo -bar", "-foo -bar", "-(foo bar)", "-(foo or bar)", "-(foo (-bar or baz))", "-(foo (-bar or -baz))", "by:foo", "-by:foo", "-by!=foo", "duration>\"2 minutes\"", "plays>3", "-plays>3", "by:baz -on:bar", "by:baz -on:bar", "by:baz (plays>3 or plays<2)", "by:on", // bgo#601065 "on:by", }; AssertForEach (tests, UserQueryParsesAndGenerates); } [Test] public void CustomFormatParenthesisBugFixed () { QueryValue val = new StringQueryValue (); val.ParseUserQuery ("mp3"); Assert.AreEqual ( "(CoreTracks.MimeType LIKE '%mp3%' ESCAPE '\\' OR CoreTracks.Uri LIKE '%mp3%' ESCAPE '\\')", MimeTypeField.ToSql (StringQueryValue.Contains, val) ); } [Test] public void EscapeSingleQuotes () { QueryValue val = new StringQueryValue (); val.ParseUserQuery ("Kelli O'Hara"); Assert.AreEqual ( "(CoreArtists.NameLowered LIKE '%kelli ohara%' ESCAPE '\\' AND CoreArtists.NameLowered IS NOT NULL)", ArtistField.ToSql (StringQueryValue.Contains, val) ); } [Test] // http://bugzilla.gnome.org/show_bug.cgi?id=570312 public void EscapeSqliteWildcards1 () { QueryValue val = new StringQueryValue (); val.ParseUserQuery ("100% Techno"); Assert.AreEqual ( "(CoreAlbums.TitleLowered LIKE '%100 techno%' ESCAPE '\\' AND CoreAlbums.TitleLowered IS NOT NULL)", AlbumField.ToSql (StringQueryValue.Contains, val) ); } [Test] // http://bugzilla.gnome.org/show_bug.cgi?id=570312 public void EscapeSqliteWildcards2 () { QueryValue val = new StringQueryValue (); val.ParseUserQuery ("-_-"); Assert.AreEqual ( "(CoreAlbums.TitleLowered LIKE '%-\\_-%' ESCAPE '\\' AND CoreAlbums.TitleLowered IS NOT NULL)", AlbumField.ToSql (StringQueryValue.Contains, val) ); } [Test] // http://bugzilla.gnome.org/show_bug.cgi?id=570312 public void EscapeSqliteWildcards3 () { QueryValue val = new StringQueryValue (); val.ParseUserQuery ("Metallic/\\"); Assert.AreEqual ( "(CoreAlbums.TitleLowered LIKE '%metallic%' ESCAPE '\\' AND CoreAlbums.TitleLowered IS NOT NULL)", AlbumField.ToSql (StringQueryValue.Contains, val) ); } [Test] // http://bugzilla.gnome.org/show_bug.cgi?id=570312 public void EscapeSqliteWildcards4Real () { QueryValue val = new ExactStringQueryValue (); val.ParseUserQuery ("/\\_%`'"); Assert.AreEqual ( "(CoreTracks.MimeType LIKE '%/\\\\\\_\\%`''%' ESCAPE '\\' OR CoreTracks.Uri LIKE '%/\\\\\\_\\%`''%' ESCAPE '\\')", MimeTypeField.ToSql (StringQueryValue.Contains, val) ); } [Test] // http://bugzilla.gnome.org/show_bug.cgi?id=612152 public void EscapeUri () { QueryValue val = new ExactUriStringQueryValue (); val.ParseUserQuery ("space 3quotes`'\"underscore_percentage%slash/backslash\\"); Assert.AreEqual ( @"(CoreTracks.Uri LIKE '%space\%203quotes\%60''\%22underscore\_percentage\%25slash/backslash\%5C%' ESCAPE '\' AND CoreTracks.Uri IS NOT NULL)", UriField.ToSql (StringQueryValue.Contains, val) ); } [Test] // Test behavior issues described in // http://bugzilla.gnome.org/show_bug.cgi?id=547078 public void ParenthesesInQuotes () { string query = "artist==\"foo (disc 2)\""; QueryNode query_tree = UserQueryParser.Parse (query, FieldSet); Assert.IsNotNull (query_tree, "Query should parse"); Assert.AreEqual ("by==\"foo (disc 2)\"", query_tree.ToUserQuery ()); } private static void UserQueryParsesAndGenerates (string query) { QueryNode node = UserQueryParser.Parse (query, FieldSet); if (query == null || query.Trim () == String.Empty) { Assert.AreEqual (node, null); return; } Assert.AreEqual (query, node.ToUserQuery ()); } } } #endif hyena-0.5/Hyena/Hyena.Query/RelativeTimeSpanQueryValue.cs0000644000175000001440000000733511377105342023614 0ustar00gabeusers00000000000000// // RelativeTimeSpanQueryValue.cs // // Authors: // Gabriel Burt // // Copyright (C) 2007-2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Collections.Generic; using System.Xml; using System.Text; using System.Text.RegularExpressions; using Mono.Unix; using Hyena; namespace Hyena.Query { public class RelativeTimeSpanQueryValue : TimeSpanQueryValue { // The SQL operators in these Operators are reversed from normal on purpose public static new readonly Operator GreaterThan = new Operator ("greaterThan", Catalog.GetString ("more than"), "< {0}", true, ">"); public static new readonly Operator LessThan = new Operator ("lessThan", Catalog.GetString ("less than"), "> {0}", "<"); public static new readonly Operator GreaterThanEqual = new Operator ("greaterThanEquals", Catalog.GetString ("at least"), "<= {0}", true, ">="); public static new readonly Operator LessThanEqual = new Operator ("lessThanEquals", Catalog.GetString ("at most"), ">= {0}", "<="); protected static new AliasedObjectSet operators = new AliasedObjectSet (GreaterThan, LessThan, GreaterThanEqual, LessThanEqual); public override AliasedObjectSet OperatorSet { get { return operators; } } public static RelativeTimeSpanQueryValue RelativeToNow (DateTime since) { RelativeTimeSpanQueryValue qv = new RelativeTimeSpanQueryValue (); qv.SetRelativeValue ((since - DateTime.Now).TotalSeconds, TimeFactor.Second); qv.DetermineFactor (); return qv; } public override string XmlElementName { get { return "date"; } } public override double Offset { get { return -offset; } } public override void SetUserRelativeValue (double offset, TimeFactor factor) { SetRelativeValue (-offset, factor); } public override void AppendXml (XmlElement node) { base.AppendXml (node); node.SetAttribute ("type", "rel"); } public override string ToSql (Operator op) { return DateTimeUtil.FromDateTime (DateTime.Now + TimeSpan.FromSeconds ((double) offset)).ToString (System.Globalization.CultureInfo.InvariantCulture); } protected override string FactorString (TimeFactor factor, double count, bool translate) { string result = base.FactorString (factor, count, translate); return (result == null) ? null : String.Format ( translate ? Catalog.GetString ("{0} ago") : "{0} ago", result); } } } hyena-0.5/Hyena/Hyena.Query/XmlQueryParser.cs0000644000175000001440000001041711377105342021313 0ustar00gabeusers00000000000000// // XmlQueryParser.cs // // Author: // Gabriel Burt // // Copyright (C) 2007-2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.IO; using System.Text; using System.Xml; namespace Hyena.Query { public class XmlQueryParser : QueryParser { private string str; private QueryFieldSet field_set; public static QueryNode Parse (string input, QueryFieldSet fieldSet) { return new XmlQueryParser (input).BuildTree (fieldSet); } public XmlQueryParser () : base () {} public XmlQueryParser (string str) { this.str = str; } public override QueryNode BuildTree (QueryFieldSet fieldSet) { field_set = fieldSet; XmlDocument doc = new XmlDocument (); try { doc.LoadXml (str); XmlElement request = doc.FirstChild as XmlElement; if (request == null || request.Name != "request") throw new Exception ("Invalid request"); XmlElement query = request.FirstChild as XmlElement; if (query == null || query.Name != "query" || query.GetAttribute ("banshee-version") != "1") throw new Exception ("Invalid query"); QueryNode node = Parse (query.FirstChild as XmlElement, null); return (node != null) ? node.Trim () : null; } catch (Exception) { } return null; } private QueryNode Parse (XmlElement node, QueryListNode parent) { if (node == null) return null; QueryListNode list = null; //Console.WriteLine ("Parsing node: {0}", node.Name); switch (node.Name.ToLower ()) { case "and": list = new QueryListNode (Keyword.And); break; case "or": list = new QueryListNode (Keyword.Or); break; case "not": list = new QueryListNode (Keyword.Not); break; default: QueryTermNode term = new QueryTermNode (); // Get the field (if any) that this term applies to if (node["field"] != null) term.Field = field_set [node["field"].GetAttribute ("name")]; // Get the value term.Value = QueryValue.CreateFromXml (node, term.Field); // Get the operator from the term's name term.Operator = term.Value.OperatorSet [node.Name]; if (parent != null) { parent.AddChild (term); } return term; } if (list != null) { if (parent != null) parent.AddChild (list); // Recursively parse the children of a QueryListNode foreach (XmlNode child in node.ChildNodes) { Parse (child as XmlElement, list); } } return list; } public override void Reset () { } } } hyena-0.5/Hyena/Hyena.Query/QueryValue.cs0000644000175000001440000001117611377105342020455 0ustar00gabeusers00000000000000// // QueryValue.cs // // Authors: // Gabriel Burt // // Copyright (C) 2007-2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Collections.Generic; using System.Xml; using System.Text; using Hyena; namespace Hyena.Query { public abstract class QueryValue { private static List subtypes = new List (); public static void AddValueType (Type type) { if (!subtypes.Contains (type)) { subtypes.Add (type); } } public static QueryValue CreateFromUserQuery (string input, QueryField field) { if (field == null) { QueryValue val = new StringQueryValue (); val.ParseUserQuery (input); return val; } else { foreach (QueryValue val in field.CreateQueryValues ()) { val.ParseUserQuery (input); if (!val.IsEmpty) { return val; } } } return null; } public static QueryValue CreateFromStringValue (string input, QueryField field) { if (field == null) { QueryValue val = new StringQueryValue (); val.LoadString (input); return val; } else { foreach (QueryValue val in field.CreateQueryValues ()) { val.LoadString (input); if (!val.IsEmpty) { return val; } } } return null; } public static QueryValue CreateFromXml (XmlElement parent, QueryField field) { if (field != null) { foreach (QueryValue val in field.CreateQueryValues ()) { if (CreateFromXml (val, parent)) { return val; } } return null; } else { foreach (Type subtype in subtypes) { QueryValue val = Activator.CreateInstance (subtype) as QueryValue; if (CreateFromXml (val, parent)) { return val; } } } return null; } private static bool CreateFromXml (QueryValue val, XmlElement parent) { XmlElement val_node = parent[val.XmlElementName]; if (val_node != null) { val.ParseXml (val_node); return !val.IsEmpty; } return false; } private bool is_empty = true; public bool IsEmpty { get { return is_empty; } protected set { is_empty = value; } } public abstract object Value { get; } public abstract string XmlElementName { get; } public abstract AliasedObjectSet OperatorSet { get; } public abstract void LoadString (string input); public abstract void ParseXml (XmlElement node); public virtual void AppendXml (XmlElement node) { node.InnerText = Value.ToString (); } public abstract void ParseUserQuery (string input); public virtual string ToUserQuery () { return Value.ToString (); } public override string ToString () { return Value.ToString (); } public string ToSql () { return ToSql (null); } public abstract string ToSql (Operator op); } } hyena-0.5/Hyena/Hyena.Query/QueryNode.cs0000644000175000001440000001617111377105342020266 0ustar00gabeusers00000000000000// // QueryNode.cs // // Author: // Aaron Bockover // Gabriel Burt // // Copyright (C) 2007-2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Collections.Generic; using System.Xml; using System.IO; using System.Text; namespace Hyena.Query { public enum QueryNodeSearchMethod { DepthFirst, BreadthFirst } public abstract class QueryNode { private QueryListNode parent; private int source_column; private int source_line; public QueryNode() { } public QueryNode(QueryListNode parent) { Parent = parent; Parent.AddChild(this); } protected void PrintIndent(int depth) { Console.Write(String.Empty.PadLeft(depth * 2, ' ')); } public void Dump() { Dump(0); } internal virtual void Dump(int depth) { PrintIndent(depth); Console.WriteLine(this); } public abstract QueryNode Trim (); public string ToUserQuery () { StringBuilder sb = new StringBuilder (); AppendUserQuery (sb); return sb.ToString (); } public abstract void AppendUserQuery (StringBuilder sb); public string ToXml (QueryFieldSet fieldSet) { return ToXml (fieldSet, false); } public virtual string ToXml (QueryFieldSet fieldSet, bool pretty) { XmlDocument doc = new XmlDocument (); XmlElement request = doc.CreateElement ("request"); doc.AppendChild (request); XmlElement query = doc.CreateElement ("query"); query.SetAttribute ("banshee-version", "1"); request.AppendChild (query); AppendXml (doc, query, fieldSet); if (!pretty) { return doc.OuterXml; } using (StringWriter sw = new StringWriter ()) { using (XmlTextWriter xtw = new XmlTextWriter (sw)) { xtw.Formatting = System.Xml.Formatting.Indented; xtw.Indentation = 2; doc.WriteTo (xtw); return sw.ToString (); } } } public IEnumerable SearchForValues () where T : QueryValue { return SearchForValues (QueryNodeSearchMethod.DepthFirst); } public IEnumerable SearchForValues (QueryNodeSearchMethod method) where T : QueryValue { if (method == QueryNodeSearchMethod.DepthFirst) { return SearchForValuesByDepth (this); } else { return SearchForValuesByBreadth (); } } private static IEnumerable SearchForValuesByDepth (QueryNode node) where T : QueryValue { QueryListNode list = node as QueryListNode; if (list != null) { foreach (QueryNode child in list.Children) { foreach (T item in SearchForValuesByDepth (child)) { yield return item; } } } else { QueryTermNode term = node as QueryTermNode; if (term != null) { T value = term.Value as T; if (value != null) { yield return value; } } } } private IEnumerable SearchForValuesByBreadth () where T : QueryValue { Queue queue = new Queue (); queue.Enqueue (this); do { QueryNode node = queue.Dequeue (); QueryListNode list = node as QueryListNode; if (list != null) { foreach (QueryNode child in list.Children) { queue.Enqueue (child); } } else { QueryTermNode term = node as QueryTermNode; if (term != null) { T value = term.Value as T; if (value != null) { yield return value; } } } } while (queue.Count > 0); } public IEnumerable GetFields () { foreach (QueryTermNode term in GetTerms ()) yield return term.Field; } public IEnumerable GetTerms () { Queue queue = new Queue (); queue.Enqueue (this); do { QueryNode node = queue.Dequeue (); QueryListNode list = node as QueryListNode; if (list != null) { foreach (QueryNode child in list.Children) { queue.Enqueue (child); } } else { QueryTermNode term = node as QueryTermNode; if (term != null) { yield return term; } } } while (queue.Count > 0); } public override string ToString () { return ToUserQuery (); } public abstract void AppendXml (XmlDocument doc, XmlNode parent, QueryFieldSet fieldSet); public virtual string ToSql (QueryFieldSet fieldSet) { StringBuilder sb = new StringBuilder (); AppendSql (sb, fieldSet); return sb.ToString (); } public abstract void AppendSql (StringBuilder sb, QueryFieldSet fieldSet); public QueryListNode Parent { get { return parent; } set { parent = value; } } public int SourceColumn { get { return source_column; } set { source_column = value; } } public int SourceLine { get { return source_line; } set { source_line = value; } } } } hyena-0.5/Hyena/Hyena.Query/QueryFieldSet.cs0000644000175000001440000000306711377105342021100 0ustar00gabeusers00000000000000// // QueryFieldSet.cs // // Authors: // Gabriel Burt // Aaron Bockover // // Copyright (C) 2007-2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Text; using System.Collections.Generic; namespace Hyena.Query { public class QueryFieldSet : AliasedObjectSet { public QueryFieldSet (params QueryField [] fields) : base (fields) { } public QueryField [] Fields { get { return Objects; } } } } hyena-0.5/Hyena/Hyena.Query/TimeSpanQueryValue.cs0000644000175000001440000002050611377105342022113 0ustar00gabeusers00000000000000// // TimeSpanQueryValue.cs // // Authors: // Gabriel Burt // // Copyright (C) 2007-2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Collections.Generic; using System.Globalization; using System.Xml; using System.Text; using System.Text.RegularExpressions; using Mono.Unix; using Hyena; namespace Hyena.Query { public enum TimeFactor { Second = 1, Minute = 60, Hour = 3600, Day = 3600*24, Week = 3600*24*7, Month = 3600*24*30, Year = 3600*24*365 } public class TimeSpanQueryValue : IntegerQueryValue { /*public static readonly Operator Equal = new Operator ("equals", "= {0}", "==", "=", ":"); public static readonly Operator NotEqual = new Operator ("notEqual", "!= {0}", true, "!=", "!:"); public static readonly Operator LessThanEqual = new Operator ("lessThanEquals", "<= {0}", "<="); public static readonly Operator GreaterThanEqual = new Operator ("greaterThanEquals", ">= {0}", ">="); public static readonly Operator LessThan = new Operator ("lessThan", "< {0}", "<"); public static readonly Operator GreaterThan = new Operator ("greaterThan", "> {0}", ">");*/ protected double offset = 0; protected TimeFactor factor = TimeFactor.Second; public override string XmlElementName { get { return "timespan"; } } //protected static AliasedObjectSet operators = new AliasedObjectSet (Equal, NotEqual, LessThan, GreaterThan, LessThanEqual, GreaterThanEqual); protected static AliasedObjectSet ops = new AliasedObjectSet (LessThan, GreaterThan, LessThanEqual, GreaterThanEqual); public override AliasedObjectSet OperatorSet { get { return operators; } } public override object Value { get { return offset; } } public virtual double Offset { get { return offset; } } public TimeFactor Factor { get { return factor; } } public double FactoredValue { get { return Offset / (double) factor; } } // FIXME replace period in following with culture-dependent character private static Regex number_regex = new Regex ("\\d+(\\.\\d+)?", RegexOptions.Compiled); public override void ParseUserQuery (string input) { Match match = number_regex.Match (input); if (match != Match.Empty && match.Groups.Count > 0) { double val; try { val = Convert.ToDouble (match.Groups[0].Captures[0].Value); } catch (FormatException) { val = Convert.ToDouble (match.Groups[0].Captures[0].Value, NumberFormatInfo.InvariantInfo); } foreach (TimeFactor factor in Enum.GetValues (typeof(TimeFactor))) { if (input == FactorString (factor, val, true) || input == FactorString (factor, val, false)) { SetUserRelativeValue (val, factor); return; } } } IsEmpty = true; } public override string ToUserQuery () { return FactorString (factor, FactoredValue, true); } public virtual void SetUserRelativeValue (double offset, TimeFactor factor) { SetRelativeValue (offset, factor); } public void SetRelativeValue (double offset, TimeFactor factor) { this.factor = factor; this.offset = (long) (offset * (double)factor); IsEmpty = false; } public override void LoadString (string val) { try { SetRelativeValue (Convert.ToDouble (val), TimeFactor.Second); DetermineFactor (); } catch { IsEmpty = true; } } protected void DetermineFactor () { double val = Math.Abs (offset); foreach (TimeFactor factor in Enum.GetValues (typeof(TimeFactor))) { if (val >= (double) factor) { this.factor = factor; } } } public override void ParseXml (XmlElement node) { try { LoadString (node.InnerText); if (node.HasAttribute ("factor")) { this.factor = (TimeFactor) Enum.Parse (typeof(TimeFactor), node.GetAttribute ("factor")); } } catch { IsEmpty = true; } } public override void AppendXml (XmlElement node) { base.AppendXml (node); node.SetAttribute ("factor", factor.ToString ()); } public override string ToSql (Operator op) { return Convert.ToString (offset * 1000, System.Globalization.CultureInfo.InvariantCulture); } protected virtual string FactorString (TimeFactor factor, double count, bool translate) { string result = null; int plural_count = StringUtil.DoubleToPluralInt (count); if (translate) { switch (factor) { case TimeFactor.Second: result = Catalog.GetPluralString ("{0} second", "{0} seconds", plural_count); break; case TimeFactor.Minute: result = Catalog.GetPluralString ("{0} minute", "{0} minutes", plural_count); break; case TimeFactor.Hour: result = Catalog.GetPluralString ("{0} hour", "{0} hours", plural_count); break; case TimeFactor.Day: result = Catalog.GetPluralString ("{0} day", "{0} days", plural_count); break; case TimeFactor.Week: result = Catalog.GetPluralString ("{0} week", "{0} weeks", plural_count); break; case TimeFactor.Month: result = Catalog.GetPluralString ("{0} month", "{0} months", plural_count); break; case TimeFactor.Year: result = Catalog.GetPluralString ("{0} year", "{0} years", plural_count); break; default: return null; } } else { switch (factor) { case TimeFactor.Second: result = plural_count == 1 ? "{0} second" : "{0} seconds"; break; case TimeFactor.Minute: result = plural_count == 1 ? "{0} minute" : "{0} minutes"; break; case TimeFactor.Hour: result = plural_count == 1 ? "{0} hour" : "{0} hours"; break; case TimeFactor.Day: result = plural_count == 1 ? "{0} day" : "{0} days"; break; case TimeFactor.Week: result = plural_count == 1 ? "{0} week" : "{0} weeks"; break; case TimeFactor.Month: result = plural_count == 1 ? "{0} month" : "{0} months"; break; case TimeFactor.Year: result = plural_count == 1 ? "{0} year" : "{0} years"; break; default: return null; } } return String.Format (result, StringUtil.DoubleToTenthsPrecision ( count, false, translate ? NumberFormatInfo.CurrentInfo : NumberFormatInfo.InvariantInfo)); } } }hyena-0.5/Hyena/Hyena.Query/EnumQueryValue.cs0000644000175000001440000000706711377105342021306 0ustar00gabeusers00000000000000// // EnumQueryValue.cs // // Author: // Alexander Kojevnikov // // Copyright (C) 2009 Alexander Kojevnikov // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Collections.Generic; using System.Linq; using System.Xml; using System.Text; using Mono.Unix; using Hyena; namespace Hyena.Query { public abstract class EnumQueryValue : QueryValue { public static readonly Operator Equal = new Operator ("equals", Catalog.GetString ("is"), "= {0}", "=", "==", ":"); public static readonly Operator NotEqual = new Operator ("notEqual", Catalog.GetString ("is not"), "!= {0}", true, "!=", "!:"); protected int value; public abstract IEnumerable Items { get; } public override string XmlElementName { get { return "int"; } } public override object Value { get { return value; } } public void SetValue (int value) { this.value = value; IsEmpty = false; } protected static AliasedObjectSet operators = new AliasedObjectSet (Equal, NotEqual); public override AliasedObjectSet OperatorSet { get { return operators; } } public override void ParseUserQuery (string input) { foreach (var item in Items) { if (input == item.ID.ToString () || input == item.Name || item.Aliases.Contains (input)) { value = item.ID; IsEmpty = false; break; } } } public override void ParseXml (XmlElement node) { IsEmpty = !Int32.TryParse (node.InnerText, out value); } public override void LoadString (string str) { ParseUserQuery (str); } public override string ToSql (Operator op) { return Convert.ToString (value, System.Globalization.CultureInfo.InvariantCulture); } } public sealed class EnumQueryValueItem : IAliasedObject { public int ID { get; private set; } public string Name { get; private set; } public string DisplayName { get; private set; } public string[] Aliases { get; private set; } public EnumQueryValueItem (int id, string name, string display_name, params string[] aliases) { ID = id; Name = name; DisplayName = display_name; Aliases = aliases; } } } hyena-0.5/Hyena/Hyena.Query/QueryListNode.cs0000644000175000001440000001644311377105342021124 0ustar00gabeusers00000000000000// // QueryListNode.cs // // Author: // Aaron Bockover // Gabriel Burt // // Copyright (C) 2007-2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Xml; using System.Text; using System.Collections.Generic; namespace Hyena.Query { public enum Keyword { Not, Or, And } public class QueryListNode : QueryNode { private List children = new List(); private Keyword keyword; public QueryListNode(Keyword keyword) : base() { this.keyword = keyword; } public QueryListNode(Keyword keyword, QueryListNode parent) : base(parent) { this.keyword = keyword; } public void AddChild(QueryNode child) { child.Parent = this; children.Add(child); } public void RemoveChild(QueryNode child) { child.Parent = null; children.Remove(child); } public void TakeChildren (QueryListNode from) { foreach (QueryNode child in from.Children) { AddChild (child); } from.Children.Clear (); } public void ReplaceChild(QueryNode old_child, QueryNode new_child) { int index = children.IndexOf(old_child); if(index < 0) { throw new ApplicationException("old_child does not exist"); } children.RemoveAt(index); children.Insert(index, new_child); } public void InsertChild(int index, QueryNode child) { child.Parent = this; children.Insert(index, child); } public int IndexOfChild(QueryNode child) { return children.IndexOf(child); } internal override void Dump(int depth) { PrintIndent(depth); Console.WriteLine("<{0}>", Keyword); foreach(QueryNode child in children) { child.Dump(depth + 1); } PrintIndent(depth); Console.WriteLine("", Keyword); } public QueryNode GetLeftSibling(QueryNode node) { int index = IndexOfChild(node); if(index >= 1) { return Children[index - 1]; } return null; } public QueryNode GetRightSibling(QueryNode node) { int index = IndexOfChild(node); if(index < 0 || index > ChildCount - 2) { return null; } return Children[index + 1]; } public override QueryNode Trim () { // Trim depth first List copy = new List (Children); foreach (QueryNode child in copy) child.Trim (); if (Keyword == Keyword.Not) { if (ChildCount != 1) { if (Parent != null) { Parent.RemoveChild (this); } else { return null; } } } else { if (ChildCount <= 1) { if (Parent != null) { QueryListNode p = Parent; p.RemoveChild (this); p.TakeChildren (this); } else if (ChildCount == 1) { Children[0].Parent = null; return Children[0]; } } } return this; } public override void AppendXml (XmlDocument doc, XmlNode parent, QueryFieldSet fieldSet) { if (ChildCount == 0) return; XmlElement node = doc.CreateElement (Keyword.ToString ().ToLower ()); parent.AppendChild (node); foreach (QueryNode child in Children) child.AppendXml (doc, node, fieldSet); } public override void AppendUserQuery (StringBuilder sb) { if (ChildCount == 0) return; if (Keyword != Keyword.Not) { if (ChildCount > 1 && Parent != null) sb.Append ("("); bool first = true; foreach (QueryNode child in Children) { if (!first) { if (Keyword == Keyword.Or) { // FIXME translate sb.Append (" or "); } else { sb.Append (" "); } } else { first = false; } child.AppendUserQuery (sb); } if (ChildCount > 1 && Parent != null) sb.Append (")"); } else { sb.Append ("-"); Children [0].AppendUserQuery (sb); } } public override void AppendSql (StringBuilder sb, QueryFieldSet fieldSet) { if (ChildCount == 0) return; if (Keyword != Keyword.Not) { sb.Append ("("); bool first = true; foreach (QueryNode child in Children) { if (!first) { sb.AppendFormat (" {0} ", Keyword); } else { first = false; } child.AppendSql (sb, fieldSet); } sb.Append (")"); } else { sb.Append ("NOT("); Children [0].AppendSql (sb, fieldSet); sb.Append (")"); } } public bool IsEmpty { get { return ChildCount == 0; } } public List Children { get { return children; } } public QueryNode LastChild { get { return ChildCount > 0 ? children[ChildCount - 1] : null; } } public int ChildCount { get { return children.Count; } } public Keyword Keyword { get { return keyword; } set { keyword = value; } } } } hyena-0.5/Hyena/Hyena.Query/IntegerQueryValue.cs0000644000175000001440000000736111377105342021774 0ustar00gabeusers00000000000000// // IntegerQueryValue.cs // // Authors: // Gabriel Burt // // Copyright (C) 2007-2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Xml; using System.Text; using Mono.Unix; using Hyena; namespace Hyena.Query { public class IntegerQueryValue : QueryValue { public static readonly Operator Equal = new Operator ("equals", Catalog.GetString ("is"), "= {0}", "=", "==", ":"); public static readonly Operator NotEqual = new Operator ("notEqual", Catalog.GetString ("is not"), "!= {0}", true, "!=", "!:"); public static readonly Operator LessThanEqual = new Operator ("lessThanEquals", Catalog.GetString ("at most"), "<= {0}", "<="); public static readonly Operator GreaterThanEqual = new Operator ("greaterThanEquals", Catalog.GetString ("at least"), ">= {0}", ">="); public static readonly Operator LessThan = new Operator ("lessThan", Catalog.GetString ("less than"), "< {0}", "<"); public static readonly Operator GreaterThan = new Operator ("greaterThan", Catalog.GetString ("more than"), "> {0}", ">"); protected long value; public override string XmlElementName { get { return "int"; } } public override void ParseUserQuery (string input) { IsEmpty = !Int64.TryParse (input, out value); } public override void LoadString (string input) { ParseUserQuery (input); } public override void ParseXml (XmlElement node) { ParseUserQuery (node.InnerText); } public void SetValue (int value) { SetValue ((long) value); } public virtual void SetValue (long value) { this.value = value; IsEmpty = false; } protected static AliasedObjectSet operators = new AliasedObjectSet (Equal, NotEqual, LessThan, GreaterThan, LessThanEqual, GreaterThanEqual); public override AliasedObjectSet OperatorSet { get { return operators; } } public override object Value { get { return value; } } public long IntValue { get { return value; } } public virtual long DefaultValue { get { return 0; } } public virtual long MinValue { get { return Int64.MinValue; } } public virtual long MaxValue { get { return Int64.MaxValue; } } public override string ToSql (Operator op) { return Convert.ToString (value, System.Globalization.CultureInfo.InvariantCulture); } } } hyena-0.5/Hyena/Hyena.Query/DateQueryValue.cs0000644000175000001440000001036511377105342021252 0ustar00gabeusers00000000000000// // DateQueryValue.cs // // Authors: // Gabriel Burt // // Copyright (C) 2007-2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Collections.Generic; using System.Xml; using System.Text; using System.Text.RegularExpressions; using Mono.Unix; using Hyena; namespace Hyena.Query { public class DateQueryValue : QueryValue { //public static readonly Operator Equal = new Operator ("equals", "= {0}", "==", "=", ":"); //public static readonly Operator NotEqual = new Operator ("notEqual", "!= {0}", true, "!=", "!:"); //public static readonly Operator LessThanEqual = new Operator ("lessThanEquals", "<= {0}", "<="); //public static readonly Operator GreaterThanEqual = new Operator ("greaterThanEquals", ">= {0}", ">="); public static readonly Operator LessThan = new Operator ("lessThan", Catalog.GetString ("before"), "< {0}", true, "<"); public static readonly Operator GreaterThan = new Operator ("greaterThan", Catalog.GetString ("after"), ">= {0}", ">"); protected DateTime value = DateTime.Now; public override string XmlElementName { get { return "date"; } } //protected static AliasedObjectSet operators = new AliasedObjectSet (Equal, NotEqual, LessThan, GreaterThan, LessThanEqual, GreaterThanEqual); protected static AliasedObjectSet operators = new AliasedObjectSet (LessThan, GreaterThan); public override AliasedObjectSet OperatorSet { get { return operators; } } public override object Value { get { return value; } } public override void ParseUserQuery (string input) { try { value = DateTime.Parse (input); IsEmpty = false; } catch { IsEmpty = true; } } public override string ToUserQuery () { if (value.Hour == 0 && value.Minute == 0 && value.Second == 0) { return value.ToString ("yyyy-MM-dd"); } else { return value.ToString (); } } public void SetValue (DateTime date) { value = date; IsEmpty = false; } public override void LoadString (string val) { try { SetValue (DateTime.Parse (val)); } catch { IsEmpty = true; } } public override void ParseXml (XmlElement node) { try { LoadString (node.InnerText); } catch { IsEmpty = true; } } public override string ToSql (Operator op) { if (op == GreaterThan) { return DateTimeUtil.FromDateTime (value.AddDays (1.0)).ToString (System.Globalization.CultureInfo.InvariantCulture); } else { return DateTimeUtil.FromDateTime (value).ToString (System.Globalization.CultureInfo.InvariantCulture); } } public DateTime DateTime { get { return value; } } } } hyena-0.5/Hyena/Hyena.Query/QueryToken.cs0000644000175000001440000000453611377105342020463 0ustar00gabeusers00000000000000// // QueryToken.cs // // Author: // Aaron Bockover // // Copyright (C) 2007 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; namespace Hyena.Query { public enum TokenID { Unknown, OpenParen, CloseParen, Not, Or, And, Range, Term } public class QueryToken { private TokenID id; private int line; private int column; private string term; public QueryToken() { } public QueryToken(string term) { this.id = TokenID.Term; this.term = term; } public QueryToken(TokenID id) { this.id = id; } public QueryToken(TokenID id, int line, int column) { this.id = id; this.line = line; this.column = column; } public TokenID ID { get { return id; } set { id = value; } } public int Line { get { return line; } set { line = value; } } public int Column { get { return column; } set { column = value; } } public string Term { get { return term; } set { term = value; } } } } hyena-0.5/Hyena/Hyena.Query/ExactUriStringQueryValue.cs0000644000175000001440000000267411377105342023314 0ustar00gabeusers00000000000000// // ExactUriStringQueryValue.cs // // Authors: // Andrés G. Aragoneses // // Copyright (C) 2010 Andrés G. Aragoneses // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; namespace Hyena.Query { public class ExactUriStringQueryValue : ExactStringQueryValue { protected override string StringValue { get { return Uri.EscapeUriString (base.StringValue); } } } } hyena-0.5/Hyena/Hyena.Query/QueryTermNode.cs0000644000175000001440000001257211377105342021117 0ustar00gabeusers00000000000000// // QueryTermNode.cs // // Author: // Aaron Bockover // Gabriel Burt // // Copyright (C) 2007-2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Xml; using System.Text; using System.Collections.Generic; namespace Hyena.Query { public class QueryTermNode : QueryNode { private QueryField field; private Operator op; private QueryValue qvalue; public static QueryTermNode ParseUserQuery (QueryFieldSet field_set, string token) { QueryTermNode term = new QueryTermNode (); // See if the query specifies a field, and if so, pull out the operator as well string field_alias = field_set.FindAlias (token); if (field_alias != null) { term.Field = field_set [field_alias]; string token_without_field = token.Substring (field_alias.Length); foreach (QueryValue val in term.Field.CreateQueryValues ()) { term.Value = val; string op_alias = term.Value.OperatorSet.FindAlias (token_without_field); if (op_alias != null) { term.Operator = term.Value.OperatorSet [op_alias]; int field_separator = token.IndexOf (op_alias); string temp = token.Substring (field_separator + op_alias.Length); term.Value.ParseUserQuery (temp); if (!term.Value.IsEmpty) { break; } } term.Operator = null; term.Value = null; } } if (term.Value == null) { term.Field = null; term.Value = QueryValue.CreateFromUserQuery (token, term.Field); term.Operator = StringQueryValue.Contains; } return term; } public QueryTermNode () : base () { } public override QueryNode Trim () { if (Parent != null && (qvalue == null || qvalue.IsEmpty || (field != null && op == null))) { Parent.RemoveChild (this); } return this; } public override void AppendUserQuery (StringBuilder sb) { sb.Append (Field == null ? Value.ToUserQuery () : Field.ToTermString (Operator.PrimaryAlias, Value.ToUserQuery ())); } public override void AppendXml (XmlDocument doc, XmlNode parent, QueryFieldSet fieldSet) { XmlElement op_node = doc.CreateElement (op == null ? "contains" : op.Name); parent.AppendChild (op_node); QueryField field = Field; if (field != null) { XmlElement field_node = doc.CreateElement ("field"); field_node.SetAttribute ("name", field.Name); op_node.AppendChild (field_node); } XmlElement val_node = doc.CreateElement (Value.XmlElementName); Value.AppendXml (val_node); op_node.AppendChild (val_node); } public override void AppendSql (StringBuilder sb, QueryFieldSet fieldSet) { if (Field == null) { sb.Append ("("); int emitted = 0; foreach (QueryField field in fieldSet.Fields) { if (field.IsDefault) if (EmitTermMatch (sb, field, emitted > 0)) emitted++; } sb.Append (")"); } else { EmitTermMatch (sb, Field, false); } } private bool EmitTermMatch (StringBuilder sb, QueryField field, bool emit_or) { if (Value.IsEmpty) { return false; } if (emit_or) { sb.Append (" OR "); } sb.Append (field.ToSql (Operator, Value)); return true; } public QueryField Field { get { return field; } set { field = value; } } public Operator Operator { get { return op; } set { op = value; } } public QueryValue Value { get { return qvalue; } set { qvalue = value; } } } } hyena-0.5/Hyena/Hyena.Query/QueryParser.cs0000644000175000001440000000377311377105342020641 0ustar00gabeusers00000000000000// // QueryParser.cs // // Author: // Aaron Bockover // Gabriel Burt // // Copyright (C) 2007 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.IO; using System.Text; namespace Hyena.Query { public abstract class QueryParser { protected StreamReader reader; public QueryParser() { Reset (); } public QueryParser(string inputQuery) : this(new MemoryStream(Encoding.UTF8.GetBytes(inputQuery))) { } public QueryParser(Stream stream) : this(new StreamReader(stream)) { } public QueryParser(StreamReader reader) : this() { InputReader = reader; } public abstract QueryNode BuildTree (QueryFieldSet fieldSet); public abstract void Reset (); public StreamReader InputReader { get { return reader; } set { reader = value; } } } } hyena-0.5/Hyena/Hyena.Query/QueryLimit.cs0000644000175000001440000000462511377105342020460 0ustar00gabeusers00000000000000// // QueryLimit.cs // // Authors: // Gabriel Burt // // Copyright (C) 2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Text; using System.Collections.Generic; namespace Hyena.Query { public class QueryLimit { private string name; public string Name { get { return name; } } private string label; public string Label { get { return label; } set { label = value; } } private bool row_based; public bool RowBased { get { return row_based; } } private int factor = 1; public int Factor { get { return factor; } } private string column; public string Column { get { return column; } } public QueryLimit (string name, string label, string column, int factor) : this (name, label, false) { this.column = column; this.factor = factor; } public QueryLimit (string name, string label, bool row_based) { this.name = name; this.label = label; this.row_based = row_based; } public string ToSql (IntegerQueryValue limit_value) { return RowBased ? String.Format ("LIMIT {0}", limit_value.ToSql ()) : null; } } } hyena-0.5/Hyena/Hyena.Query/NullQueryValue.cs0000644000175000001440000000503311377105342021303 0ustar00gabeusers00000000000000// // NullQueryValue.cs // // Authors: // Gabriel Burt // // Copyright (C) 2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Xml; using System.Text; using Mono.Unix; using Hyena; namespace Hyena.Query { public class NullQueryValue : QueryValue { public static readonly Operator IsNullOrEmpty = new Operator ("empty", Catalog.GetString ("empty"), "IN (NULL, '', 0)", true, "!"); public static readonly NullQueryValue Instance = new NullQueryValue (); public override string XmlElementName { get { return "empty"; } } public override object Value { get { return null; } } protected static AliasedObjectSet operators = new AliasedObjectSet (IsNullOrEmpty); public override AliasedObjectSet OperatorSet { get { return operators; } } private NullQueryValue () { IsEmpty = false; } public override void ParseUserQuery (string input) { } public override void LoadString (string input) { } public override void ParseXml (XmlElement node) { } public override void AppendXml (XmlElement node) { node.InnerText = String.Empty; } public void SetValue (string str) { } public override string ToSql (Operator op) { return null; } } } hyena-0.5/Hyena/Hyena.Query/ExactStringQueryValue.cs0000644000175000001440000000315211377105342022624 0ustar00gabeusers00000000000000// // ExactStringQueryValue.cs // // Authors: // John Millikin // // Copyright (C) 2009 John Millikin // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; namespace Hyena.Query { // A query value that requires the string match exactly public class ExactStringQueryValue : StringQueryValue { public override string ToSql (Operator op) { return String.IsNullOrEmpty (value) ? null : EscapeString (op, StringValue); } protected virtual string StringValue { get { return value.ToLower (); } } } } hyena-0.5/Hyena/Hyena.Query/QueryOrder.cs0000644000175000001440000000423311377105342020450 0ustar00gabeusers00000000000000// // QueryOrder.cs // // Authors: // Gabriel Burt // Aaron Bockover // // Copyright (C) 2007-2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Text; using System.Collections.Generic; namespace Hyena.Query { public class QueryOrder { private string name; public string Name { get { return name; } } private string label; public string Label { get { return label; } set { label = value; } } private string order_sql; public string OrderSql { get { return order_sql; } } private QueryField field; public QueryField Field { get { return field; } } public QueryOrder (string name, string label, string order_sql, QueryField field) { this.name = name; this.label = label; this.order_sql = order_sql; this.field = field; } public string ToSql () { return String.Format ("ORDER BY {0}", order_sql); } } } hyena-0.5/Hyena/Hyena.SExpEngine/0000777000175000001440000000000011453151002016707 5ustar00gabeusers00000000000000hyena-0.5/Hyena/Hyena.SExpEngine/CastFunctionSet.cs0000644000175000001440000000626111377105342022326 0ustar00gabeusers00000000000000// // CastFunctionSet.cs // // Author: // Aaron Bockover // // Copyright (C) 2007-2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; namespace Hyena.SExpEngine { public class CastFunctionSet : FunctionSet { [Function("cast-double")] public virtual TreeNode OnCastDouble(TreeNode [] args) { if(args.Length != 1) { throw new ArgumentException("cast must have only one argument"); } TreeNode arg = Evaluate(args[0]); if(arg is DoubleLiteral) { return arg; } else if(arg is IntLiteral) { return new DoubleLiteral((int)(arg as IntLiteral).Value); } else if(arg is StringLiteral) { return new DoubleLiteral(Convert.ToDouble((arg as StringLiteral).Value)); } throw new ArgumentException("can only cast double, int, or string literals"); } [Function("cast-int")] public virtual TreeNode OnCastInt(TreeNode [] args) { DoubleLiteral result = (DoubleLiteral)OnCastDouble(args); return new IntLiteral((int)result.Value); } [Function("cast-bool")] public virtual TreeNode OnCastBool(TreeNode [] args) { DoubleLiteral result = (DoubleLiteral)OnCastDouble(args); return new BooleanLiteral((int)result.Value != 0); } [Function("cast-string")] public virtual TreeNode OnCastString(TreeNode [] args) { if(args.Length != 1) { throw new ArgumentException("cast must have only one argument"); } TreeNode arg = Evaluate(args[0]); if(arg is DoubleLiteral) { return new StringLiteral(Convert.ToString((arg as DoubleLiteral).Value)); } else if(arg is IntLiteral) { return new StringLiteral(Convert.ToString((arg as IntLiteral).Value)); } else if(arg is StringLiteral) { return arg; } throw new ArgumentException("can only cast double, int, or string literals"); } } } hyena-0.5/Hyena/Hyena.SExpEngine/CompareFunctionSet.cs0000644000175000001440000001064711377105342023025 0ustar00gabeusers00000000000000// // CompareFunctionSet.cs // // Author: // Aaron Bockover // // Copyright (C) 2007-2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; namespace Hyena.SExpEngine { public class CompareFunctionSet : FunctionSet { [Function("compare-to")] public virtual TreeNode OnCompareTo(TreeNode [] args) { if(args.Length != 2) { throw new ArgumentException("must have two arguments"); } return Compare(Evaluator, args[0], args[1]); } public static TreeNode Compare(EvaluatorBase evaluator, TreeNode a, TreeNode b) { TreeNode arg_a = evaluator.Evaluate(a); TreeNode arg_b = evaluator.Evaluate(b); if(arg_a.GetType() != arg_b.GetType()) { throw new ArgumentException("arguments must be of the same type to compare"); } int result = 0; if(arg_a is IntLiteral) { result = (arg_a as IntLiteral).Value.CompareTo( (arg_b as IntLiteral).Value); } else if(arg_a is DoubleLiteral) { result = (arg_a as DoubleLiteral).Value.CompareTo( (arg_b as DoubleLiteral).Value); } else if(arg_a is StringLiteral) { result = (arg_a as StringLiteral).Value.CompareTo( (arg_b as StringLiteral).Value); } else if(arg_a is BooleanLiteral) { result = (arg_a as BooleanLiteral).Value.CompareTo( (arg_b as BooleanLiteral).Value); } else { throw new ArgumentException("invalid type for comparison"); } return new IntLiteral(result); } [Function("less-than", "<")] public virtual TreeNode OnCompareLessThan(TreeNode [] args) { IntLiteral result = (IntLiteral)OnCompareTo(args); return new BooleanLiteral(result.Value < 0); } [Function("greater-than", ">")] public virtual TreeNode OnCompareGreaterThan(TreeNode [] args) { IntLiteral result = (IntLiteral)OnCompareTo(args); return new BooleanLiteral(result.Value > 0); } [Function("equal", "=")] public virtual TreeNode OnCompareEqual(TreeNode [] args) { IntLiteral result = (IntLiteral)OnCompareTo(args); return new BooleanLiteral(result.Value == 0); } [Function("not-equal", "!=")] public virtual TreeNode OnCompareNotEqual(TreeNode [] args) { BooleanLiteral result = (BooleanLiteral)OnCompareEqual(args); return new BooleanLiteral(!result.Value); } [Function("less-than-or-equal", "<=")] public virtual TreeNode OnCompareLessThanOrEqual(TreeNode [] args) { BooleanLiteral a = (BooleanLiteral)OnCompareLessThan(args); BooleanLiteral b = (BooleanLiteral)OnCompareEqual(args); return new BooleanLiteral(a.Value || b.Value); } [Function("greater-than-or-equal", ">=")] public virtual TreeNode OnCompareGreaterThanOrEqual(TreeNode [] args) { BooleanLiteral a = (BooleanLiteral)OnCompareGreaterThan(args); BooleanLiteral b = (BooleanLiteral)OnCompareEqual(args); return new BooleanLiteral(a.Value || b.Value); } } } hyena-0.5/Hyena/Hyena.SExpEngine/FunctionFunctionSet.cs0000644000175000001440000000722611377105342023223 0ustar00gabeusers00000000000000// // FunctionFunctionSet.cs // // Author: // Aaron Bockover // // Copyright (C) 2007-2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; namespace Hyena.SExpEngine { public class FunctionFunctionSet : FunctionSet { [Function(false, "set")] public virtual TreeNode OnSet(TreeNode [] args) { return VariableSet(Evaluator, args, true); } public static TreeNode VariableSet(EvaluatorBase evaluator, TreeNode var, TreeNode value) { return VariableSet(evaluator, new TreeNode[] { var, value }, true); } public static TreeNode VariableSet(EvaluatorBase evaluator, TreeNode [] args, bool update) { if(args.Length != 2) { throw new ArgumentException("must have two arguments"); } if(!(args[0] is FunctionNode)) { throw new ArgumentException("first argument must be a variable"); } FunctionNode variable_node = evaluator.ResolveFunction(args[0] as FunctionNode); if(variable_node != null) { variable_node.Body = evaluator.Evaluate(args[1]); } else { TreeNode parent = args[0].Parent; parent = parent.Parent ?? parent; parent.RegisterFunction((args[0] as FunctionNode).Function, evaluator.Evaluate(args[1])); } return new VoidLiteral(); } [Function(false, "define")] public virtual TreeNode OnDefine(TreeNode [] args) { if(args.Length < 2 || args.Length > 3) { throw new ArgumentException("define must have two or three arguments"); } if(!(args[0] is FunctionNode)) { throw new ArgumentException("first define argument must be a variable"); } FunctionNode function = new FunctionNode((args[0] as FunctionNode).Function, args[args.Length - 1]); if(args.Length == 3 && args[1].HasChildren) { foreach(TreeNode function_arg in args[1].Children) { if(!(function_arg is FunctionNode)) { throw new ArgumentException("define function arguments must be variable tokens"); } function.RegisterFunction((function_arg as FunctionNode).Function, new VoidLiteral()); } } TreeNode parent = args[0].Parent; parent = parent.Parent ?? parent; parent.RegisterFunction(function.Function, function); return new VoidLiteral(); } } } hyena-0.5/Hyena/Hyena.SExpEngine/Literals.cs0000644000175000001440000000573011377105342021031 0ustar00gabeusers00000000000000// // Literals.cs // // Author: // Aaron Bockover // // Copyright (C) 2007-2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; namespace Hyena.SExpEngine { public class LiteralNodeBase : TreeNode { private Type type = null; public Type EnclosedType { get { return type ?? GetType(); } set { type = value; } } } public class LiteralNode : LiteralNodeBase { private T value; public LiteralNode(T value) { this.value = value; EnclosedType = typeof(T); } public override string ToString() { return Value.ToString(); } public T Value { get { return value; } } } // Literal Types public class VoidLiteral : LiteralNodeBase { public override string ToString() { return "void"; } } public class DoubleLiteral : LiteralNode { private static System.Globalization.CultureInfo culture_info = new System.Globalization.CultureInfo("en-US"); public DoubleLiteral(double value) : base(value) { } public override string ToString() { return (Value - (int)Value) == 0.0 ? String.Format("{0}.0", Value.ToString(culture_info)) : Value.ToString(culture_info); } } public class BooleanLiteral : LiteralNode { public BooleanLiteral(bool value) : base(value) { } public override string ToString() { return Value ? "true" : "false"; } } public class IntLiteral : LiteralNode { public IntLiteral(int value) : base(value) { } } public class StringLiteral : LiteralNode { public StringLiteral(string value) : base(value) { } } } hyena-0.5/Hyena/Hyena.SExpEngine/UtilityFunctionSet.cs0000644000175000001440000000427511377105342023102 0ustar00gabeusers00000000000000// // UtilityFunctionSet.cs // // Author: // Aaron Bockover // // Copyright (C) 2007-2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; namespace Hyena.SExpEngine { public class UtilityFunctionSet : FunctionSet { [Function("print")] public virtual TreeNode OnPrint(TreeNode [] args) { if(args.Length != 1) { throw new ArgumentException("print must have only one argument"); } Console.WriteLine(Evaluate(args[0])); return new VoidLiteral(); } [Function("print-type")] public virtual TreeNode OnPrintType(TreeNode [] args) { if(args.Length != 1) { throw new ArgumentException("print-type must have only one argument"); } Console.WriteLine(Evaluate(args[0]).GetType()); return new VoidLiteral(); } [Function("dump")] public virtual TreeNode OnDump(TreeNode [] args) { foreach(TreeNode arg in args) { Evaluate(arg).Dump(); } return new VoidLiteral(); } } } hyena-0.5/Hyena/Hyena.SExpEngine/StringFunctionSet.cs0000644000175000001440000001403111377105342022674 0ustar00gabeusers00000000000000// // StringFunctionSet.cs // // Author: // Aaron Bockover // // Copyright (C) 2007-2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Text; using System.Text.RegularExpressions; namespace Hyena.SExpEngine { public class StringFunctionSet : FunctionSet { [Function("string-concat")] public virtual TreeNode OnConcatenateStrings(TreeNode [] args) { return ConcatenateStrings(Evaluator, args); } public static TreeNode ConcatenateStrings(EvaluatorBase evaluator, TreeNode [] args) { StringBuilder result = new StringBuilder(); foreach(TreeNode arg in args) { TreeNode eval_arg = evaluator.Evaluate(arg); if(!(eval_arg is VoidLiteral)) { result.Append(eval_arg); } } return new StringLiteral(result.ToString()); } private void CheckArgumentCount(TreeNode [] args, int expected) { CheckArgumentCount(args, expected, expected); } private void CheckArgumentCount(TreeNode [] args, int expected_min, int expected_max) { if(args.Length < expected_min || args.Length > expected_max) { throw new ArgumentException("expects " + expected_min + " <= args <= " + expected_max + " arguments"); } } private string GetArgumentString(TreeNode [] args, int index) { TreeNode node = Evaluate(args[index]); if(!(node is StringLiteral)) { throw new ArgumentException("argument " + index + " must be a string"); } return (node as StringLiteral).Value; } private int GetArgumentInteger(TreeNode [] args, int index) { TreeNode node = Evaluate(args[index]); if(!(node is IntLiteral)) { throw new ArgumentException("argument " + index + " must be an integer"); } return (node as IntLiteral).Value; } [Function("length")] public virtual TreeNode OnLength(TreeNode [] args) { CheckArgumentCount(args, 1); TreeNode node = Evaluate(args[0]); if(node is StringLiteral) { return new IntLiteral((node as StringLiteral).Value.Length); } else if(!(node is LiteralNodeBase) && !(node is FunctionNode)) { return new IntLiteral(node.ChildCount); } return new IntLiteral(0); } [Function("contains")] public virtual TreeNode OnContains(TreeNode [] args) { CheckArgumentCount(args, 2); return new BooleanLiteral(GetArgumentString(args, 0).Contains(GetArgumentString(args, 1))); } [Function("index-of")] public virtual TreeNode OnIndexOf(TreeNode [] args) { CheckArgumentCount(args, 2); return new IntLiteral(GetArgumentString(args, 0).IndexOf(GetArgumentString(args, 1))); } [Function("last-index-of")] public virtual TreeNode OnLastIndexOf(TreeNode [] args) { CheckArgumentCount(args, 2); return new IntLiteral(GetArgumentString(args, 0).LastIndexOf(GetArgumentString(args, 1))); } [Function("starts-with")] public virtual TreeNode OnStartsWith(TreeNode [] args) { CheckArgumentCount(args, 2); return new BooleanLiteral(GetArgumentString(args, 0).StartsWith(GetArgumentString(args, 1))); } [Function("ends-with")] public virtual TreeNode OnEndsWith(TreeNode [] args) { CheckArgumentCount(args, 2); return new BooleanLiteral(GetArgumentString(args, 0).EndsWith(GetArgumentString(args, 1))); } [Function("substring")] public virtual TreeNode OnSubstring(TreeNode [] args) { CheckArgumentCount(args, 2, 3); if(args.Length == 2) { return new StringLiteral(GetArgumentString(args, 0).Substring(GetArgumentInteger(args, 1))); } else { return new StringLiteral(GetArgumentString(args, 0).Substring( GetArgumentInteger(args, 1), GetArgumentInteger(args, 2))); } } [Function("split")] public virtual TreeNode OnSplit(TreeNode [] args) { CheckArgumentCount(args, 2); TreeNode result = new TreeNode(); string str = GetArgumentString(args, 0); string pattern = GetArgumentString(args, 1); foreach(string item in Regex.Split(str, pattern)) { result.AddChild(new StringLiteral(item)); } return result; } [Function("trim")] public virtual TreeNode OnTrim(TreeNode [] args) { CheckArgumentCount(args, 1); return new StringLiteral(GetArgumentString(args, 0).Trim()); } } } hyena-0.5/Hyena/Hyena.SExpEngine/FunctionSet.cs0000644000175000001440000000604411377105342021512 0ustar00gabeusers00000000000000// // FunctionSet.cs // // Author: // Aaron Bockover // // Copyright (C) 2007-2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Reflection; namespace Hyena.SExpEngine { [AttributeUsage(AttributeTargets.Method)] public class FunctionAttribute : Attribute { private string [] names; private bool evaluate_variables; public FunctionAttribute(params string [] names) { this.evaluate_variables = true; this.names = names; } public FunctionAttribute(bool evaluateVariables, params string [] names) { this.evaluate_variables = evaluateVariables; this.names = names; } public string [] Names { get { return names; } } public bool EvaluateVariables { get { return evaluate_variables; } } } public abstract class FunctionSet { private EvaluatorBase evaluator; public void Load(EvaluatorBase evaluator) { this.evaluator = evaluator; foreach(MethodInfo method in GetType().GetMethods()) { string [] names = null; bool evaluate_variables = true; foreach(Attribute attr in method.GetCustomAttributes(false)) { if(attr is FunctionAttribute) { names = (attr as FunctionAttribute).Names; evaluate_variables = (attr as FunctionAttribute).EvaluateVariables; break; } } if(names == null || names.Length == 0) { continue; } evaluator.RegisterFunction(this, method, names, evaluate_variables); } } public TreeNode Evaluate(TreeNode node) { return evaluator.Evaluate(node); } protected EvaluatorBase Evaluator { get { return evaluator; } } } } hyena-0.5/Hyena/Hyena.SExpEngine/EvaluatorBase.cs0000644000175000001440000002466511377105342022017 0ustar00gabeusers00000000000000// // EvaluatorBase.cs // // Author: // Aaron Bockover // // Copyright (C) 2007-2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Reflection; using System.Collections.Generic; using System.Collections.ObjectModel; namespace Hyena.SExpEngine { public delegate TreeNode SExpFunctionHandler(EvaluatorBase evaluator, TreeNode [] args); public delegate TreeNode SExpVariableResolutionHandler(TreeNode node); public class EvaluationException : ApplicationException { public EvaluationException(TreeNode node, string token, Exception inner) : base(String.Format( "Evaluation exception at token `{0} ({1})' [{2},{3}]", node.GetType(), token, node.Line, node.Column), inner) { } } public class UnknownVariableException : ApplicationException { public UnknownVariableException(string var) : base(var) { } } public class EvaluatorBase { private class MethodInfoContainer { public object Object; public MethodInfo MethodInfo; public bool EvaluateVariables; } private TreeNode expression; private TreeNode function_table_expression = new TreeNode(); private string input; private Dictionary functions = new Dictionary(); private List exceptions = new List(); public EvaluatorBase() { expression = function_table_expression; } public EvaluatorBase(TreeNode expression) { this.expression = expression; } public EvaluatorBase(string input) { expression = function_table_expression; this.input = input; } public void RegisterVariable(string name, string value) { expression.RegisterFunction(name, value); } public void RegisterVariable(string name, bool value) { expression.RegisterFunction(name, value); } public void RegisterVariable(string name, int value) { expression.RegisterFunction(name, value); } public void RegisterVariable(string name, double value) { expression.RegisterFunction(name, value); } public void RegisterVariable(string name, SExpVariableResolutionHandler value) { expression.RegisterFunction(name, value); } public void RegisterVariable(string name, TreeNode value) { expression.RegisterFunction(name, value); } public void RegisterFunction(SExpFunctionHandler handler, params string [] names) { foreach(string name in names) { if(functions.ContainsKey(name)) { functions.Remove(name); } functions.Add(name, handler); } } public void RegisterFunction(object o, MethodInfo method, string [] names) { RegisterFunction(o, method, names, true); } public void RegisterFunction(object o, MethodInfo method, string [] names, bool evaluateVariables) { MethodInfoContainer container = new MethodInfoContainer(); container.MethodInfo = method; container.Object = o; container.EvaluateVariables = evaluateVariables; foreach(string name in names) { if(functions.ContainsKey(name)) { functions.Remove(name); } functions.Add(name, container); } } public void RegisterFunctionSet(FunctionSet functionSet) { functionSet.Load(this); } public TreeNode EvaluateTree(TreeNode expression) { this.expression = expression; this.input = null; return Evaluate(); } public TreeNode EvaluateString(string input) { this.expression = null; this.input = input; return Evaluate(); } public TreeNode Evaluate() { exceptions.Clear(); try { if(expression == null) { Parser parser = new Parser(); expression = parser.Parse(input); expression.CopyFunctionsFrom(function_table_expression); } return Evaluate(expression); } catch(Exception e) { Exception next = e; do { if(next != null) { exceptions.Add(next); next = next.InnerException; } } while(next != null && next.InnerException != null); if(next != null) { exceptions.Add(next); } } return null; } public TreeNode Evaluate(TreeNode node) { if(!node.HasChildren || node is FunctionNode) { return EvaluateNode(node); } TreeNode final_result_node = new TreeNode(); foreach(TreeNode child_node in node.Children) { TreeNode result_node = EvaluateNode(child_node); if(result_node != null) { final_result_node.AddChild(result_node); } if(child_node is FunctionNode) { if(functions.ContainsKey((child_node as FunctionNode).Function)) { break; } FunctionNode impl = ResolveFunction(child_node as FunctionNode); if(impl != null && impl.RequiresArguments) { break; } } } return final_result_node.ChildCount == 1 ? final_result_node.Children[0] : final_result_node; } private TreeNode EvaluateNode(TreeNode node) { TreeNode result_node = null; if(node is FunctionNode) { try { result_node = EvaluateFunction(node as FunctionNode); } catch(Exception e) { Exception ee = e; if(e is TargetInvocationException) { ee = e.InnerException; } throw new EvaluationException(node, (node as FunctionNode).Function, ee); } } else if(node is LiteralNodeBase) { result_node = node; } else { result_node = Evaluate(node); } return result_node; } private TreeNode EvaluateFunction(FunctionNode node) { object handler = null; TreeNode parent = node.Parent; TreeNode [] args = null; if(!functions.ContainsKey(node.Function)) { handler = ResolveFunction(node); if(handler == null) { throw new InvalidFunctionException(node.Function); } } else { handler = functions[node.Function]; } if(parent.Children[0] == node) { args = new TreeNode[parent.ChildCount - 1]; for(int i = 0; i < args.Length; i++) { args[i] = parent.Children[i + 1]; if(handler is MethodInfoContainer && !(handler as MethodInfoContainer).EvaluateVariables) { continue; } } } if(handler is FunctionNode) { return (handler as FunctionNode).Evaluate(this, args); } else if(handler is SExpFunctionHandler) { return ((SExpFunctionHandler)handler)(this, args); } else if(handler is MethodInfoContainer) { MethodInfoContainer container = (MethodInfoContainer)handler; return (TreeNode)container.MethodInfo.Invoke(container.Object, new object [] { args }); } else { throw new InvalidFunctionException(String.Format( "Unknown runtime method handler type {1}", handler.GetType())); } } internal FunctionNode ResolveFunction(FunctionNode node) { TreeNode shift_node = node; do { if(shift_node.Functions.ContainsKey(node.Function)) { return shift_node.Functions[node.Function]; } shift_node = shift_node.Parent; } while(shift_node != null); return null; } public bool Success { get { return exceptions.Count == 0; } } public TreeNode ExpressionTree { get { return expression; } } public ReadOnlyCollection Exceptions { get { return new ReadOnlyCollection(exceptions); } } public string ErrorMessage { get { if(exceptions.Count == 0) { return null; } else if(exceptions.Count >= 2) { return String.Format("{0}: {1}", exceptions[exceptions.Count - 2].Message, exceptions[exceptions.Count - 1].Message); } return exceptions[0].Message; } } } } hyena-0.5/Hyena/Hyena.SExpEngine/ListFunctionSet.cs0000644000175000001440000001335411377105342022350 0ustar00gabeusers00000000000000// // ListFunctionSet.cs // // Author: // Aaron Bockover // // Copyright (C) 2007-2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; namespace Hyena.SExpEngine { public class ListFunctionSet : FunctionSet { // FIXME: Why is this here? --Aaron // // private TreeNode EvaluateList(TreeNode node) // { // TreeNode list = new TreeNode(); // // foreach(TreeNode child in node.Children) { // list.AddChild(Evaluate(child)); // } // // return list; // } private bool IsList(TreeNode node) { return !(node is LiteralNodeBase) && !(node is FunctionNode); } public void CheckList(TreeNode node) { if(!IsList(node)) { throw new ArgumentException("argument must be a list"); } } [Function("is-list")] public virtual TreeNode OnIsList(TreeNode [] args) { return new BooleanLiteral(IsList(args[0])); } [Function("item-at")] public virtual TreeNode OnItemAt(TreeNode [] args) { TreeNode list = Evaluate(args[0]); CheckList(list); TreeNode node = Evaluate(args[1]); int index = 0; if(!(node is IntLiteral)) { throw new ArgumentException("argument must be an index"); } index = (node as IntLiteral).Value; return Evaluate(list.Children[index]); } [Function("remove-at")] public virtual TreeNode OnRemoveAt(TreeNode [] args) { TreeNode list = Evaluate(args[0]); CheckList(list); TreeNode node = Evaluate(args[1]); int index = 0; if(!(node is IntLiteral)) { throw new ArgumentException("argument must be an index"); } index = (node as IntLiteral).Value; list.Children.RemoveAt(index); return list; } [Function("remove")] public virtual TreeNode OnRemove(TreeNode [] args) { TreeNode list = Evaluate(args[0]); CheckList(list); TreeNode node = Evaluate(args[1]); foreach(TreeNode compare_node in list.Children) { if(((IntLiteral)CompareFunctionSet.Compare(Evaluator, node, compare_node)).Value == 0) { list.Children.Remove(compare_node); break; } } return list; } [Function("append")] public virtual TreeNode OnAppend(TreeNode [] args) { TreeNode list = Evaluate(args[0]); CheckList(list); list.Children.Add(Evaluate(args[1])); return list; } [Function("prepend")] public virtual TreeNode OnPrepend(TreeNode [] args) { TreeNode list = Evaluate(args[0]); CheckList(list); list.Children.Insert(0, Evaluate(args[1])); return list; } [Function("insert")] public virtual TreeNode OnInsert(TreeNode [] args) { TreeNode list = Evaluate(args[0]); CheckList(list); TreeNode node = Evaluate(args[1]); int index = 0; if(!(node is IntLiteral)) { throw new ArgumentException("argument must be an index"); } index = (node as IntLiteral).Value; list.Children.Insert(index, Evaluate(args[2])); return list; } [Function("foreach")] public virtual TreeNode OnForeach(TreeNode [] args) { TreeNode list = Evaluate(args[1]); CheckList(list); FunctionNode item_variable = (FunctionNode)args[0]; TreeNode function = args[2]; TreeNode self = args[0].Parent.Children[0]; self.Parent.RegisterFunction(item_variable.Function, item_variable); foreach(TreeNode child in list.Children) { item_variable.Body = child; try { if(function is FunctionNode) { FunctionNode function_impl = Evaluator.ResolveFunction(function as FunctionNode); function_impl.Evaluate(Evaluator, new TreeNode [] { child }); } else { Evaluate(function); } } catch(Exception e) { if(ControlFunctionSet.BreakHandler(e)) { break; } } } return new VoidLiteral(); } } } hyena-0.5/Hyena/Hyena.SExpEngine/Parser.cs0000644000175000001440000002012211377105342020476 0ustar00gabeusers00000000000000// // Parser.cs // // Author: // Aaron Bockover // // Copyright (C) 2007-2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.IO; using System.Text; using System.Text.RegularExpressions; using System.Globalization; namespace Hyena.SExpEngine { public class ParserException : ApplicationException { public ParserException(string token, int line, int col, Exception inner) : base(String.Format( "Parser exception at token `{0}' [{1},{2}]: {3}", token, line, col, inner == null ? "Unknown error" : inner.Message), inner) { } } public class Parser { private static Regex number_regex = new Regex(@"^[-+]?(0x[\dA-Fa-f]+)?[\d]*\.?[\d]*([eE][-+]?[\d]+)?$"); private static System.Globalization.CultureInfo culture_info = new System.Globalization.CultureInfo("en-US"); private StreamReader reader; private bool debug; private StringBuilder current_token; private TreeNode root_node ; private TreeNode current_parent; private int scope; private int line; private int column; public Parser() { } public TreeNode Parse(string input) { return Parse(new MemoryStream(Encoding.UTF8.GetBytes(input))); } public TreeNode Parse(Stream stream) { return Parse(new StreamReader(stream)); } public TreeNode Parse(StreamReader reader) { this.reader = reader; current_token = new StringBuilder(); root_node = new TreeNode(); current_parent = root_node; scope = 0; line = 1; column = 0; try { Tokenize(); if(scope != 0) { throw new ApplicationException("Scope does pop back to zero"); } } catch(Exception e) { throw new ParserException(current_token.ToString(), line, column, e); } return root_node; } private void Tokenize() { bool in_string = false; bool in_comment = false; while(true) { int ich = reader.Read(); char ch = (char)ich; if(ich < 0) { break; } if(ch == '\n') { line++; column = 0; } else { column++; } if(in_comment) { if(ch == '\r' || ch == '\n') { in_comment = false; } continue; } switch(ch) { case '(': case ')': if(!in_string) { TokenPush(false); if(ch == '(') { ScopePush(); } else { ScopePop(); } } else { current_token.Append(ch); } break; case '"': if(in_string) { in_string = false; TokenPush(true); } else { in_string = true; } break; case '\\': if((char)reader.Peek() == '"') { current_token.Append((char)reader.Read()); } break; case ';': if(in_string) { current_token.Append(ch); } else { TokenPush(false); in_comment = true; } break; default: if(Char.IsWhiteSpace(ch)) { if(in_string) { current_token.Append(ch); } else { TokenPush(false); } } else { current_token.Append(ch); } break; } } TokenPush(false); reader.Close(); } private void ScopePush() { current_parent = new TreeNode(current_parent); scope++; } private void ScopePop() { current_parent = current_parent.Parent; scope--; } private void TokenPush(bool as_string) { if(current_token.Length == 0 && !as_string) { return; } TreeNode node = null; string token = current_token.ToString(); if(Debug) { Console.Write("{3}[{0}] TOKEN({4},{5}): [{2}{1}{2}]", scope, token, as_string ? "\"" : String.Empty, String.Empty.PadLeft(scope - 1, ' '), line, column - current_token.Length); } if(as_string) { node = new StringLiteral(token); } else if(token == "#t") { node = new BooleanLiteral(true); } else if(token == "#f") { node = new BooleanLiteral(false); } else if(token.Length > 0 && token != "." && token != "-" && token != "+" && number_regex.IsMatch(token)) { try { if(token.StartsWith("0x") || token.StartsWith("-0x")) { int offset = token[0] == '-' ? 3 : 2; int value = Int32.Parse(token.Substring(offset), NumberStyles.HexNumber, culture_info.NumberFormat); node = new IntLiteral(value * (offset == 3 ? -1 : 1)); } else if(token.Contains(".")) { node = new DoubleLiteral(Double.Parse(token, NumberStyles.Float, culture_info.NumberFormat)); } else { node = new IntLiteral(Int32.Parse(token, NumberStyles.Integer, culture_info.NumberFormat)); } } catch { throw new FormatException("Invalid number format: " + token); } } else { node = new FunctionNode(token); } if(Debug) { Console.WriteLine(" => [{0}]", node); } node.Line = line; node.Column = column; current_parent.AddChild(node); current_token.Remove(0, current_token.Length); } public bool Debug { get { return debug; } set { debug = value; } } } } hyena-0.5/Hyena/Hyena.SExpEngine/ArithmeticFunctionSet.cs0000644000175000001440000001232511377105342023523 0ustar00gabeusers00000000000000// // ArithmeticFunctionSet.cs // // Author: // Aaron Bockover // // Copyright (C) 2007-2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; namespace Hyena.SExpEngine { public class ArithmeticFunctionSet : FunctionSet { public enum ArithmeticOperation { Add, Subtract, Multiply, Divide, Modulo } public virtual TreeNode OnPerformArithmetic(TreeNode [] args, ArithmeticOperation operation) { double result = 0.0; bool as_int = true; for(int i = 0; i < args.Length; i++) { TreeNode arg = Evaluate(args[i]); if(arg is IntLiteral || arg is DoubleLiteral) { double arg_value; if(arg is DoubleLiteral) { as_int = false; arg_value = (arg as DoubleLiteral).Value; } else { arg_value = (int)(arg as IntLiteral).Value; } if(i == 0) { result = arg_value; continue; } switch(operation) { case ArithmeticOperation.Add: result += arg_value; break; case ArithmeticOperation.Subtract: result -= arg_value; break; case ArithmeticOperation.Multiply: result *= arg_value; break; case ArithmeticOperation.Divide: result /= arg_value; break; case ArithmeticOperation.Modulo: if(!(arg is IntLiteral)) { throw new ArgumentException("Modulo requires int arguments"); } result %= (int)arg_value; break; } } else { throw new ArgumentException("arguments must be double or int"); } } return as_int ? ((TreeNode)new IntLiteral((int)result)) : ((TreeNode)new DoubleLiteral(result)); } [Function("add", "+")] public virtual TreeNode OnAdd(TreeNode [] args) { TreeNode first = Evaluate(args[0]); if(first is StringLiteral) { return StringFunctionSet.ConcatenateStrings(Evaluator, args); } return OnPerformArithmetic(args, ArithmeticOperation.Add); } [Function("sub", "-")] public virtual TreeNode OnSubtract(TreeNode [] args) { return OnPerformArithmetic(args, ArithmeticOperation.Subtract); } [Function("mul", "*")] public virtual TreeNode OnMultiply(TreeNode [] args) { return OnPerformArithmetic(args, ArithmeticOperation.Multiply); } [Function("div", "/")] public virtual TreeNode OnDivide(TreeNode [] args) { return OnPerformArithmetic(args, ArithmeticOperation.Divide); } [Function("mod", "%")] public virtual TreeNode OnModulo(TreeNode [] args) { return OnPerformArithmetic(args, ArithmeticOperation.Modulo); } [Function("++")] public virtual TreeNode OnIncrement(TreeNode [] args) { return IntegerUpdate(args, 1); } [Function("--")] public virtual TreeNode OnDecrement(TreeNode [] args) { return IntegerUpdate(args, -1); } private TreeNode IntegerUpdate(TreeNode [] args, int value) { TreeNode variable_node = (FunctionNode)args[0]; TreeNode result = Evaluate(variable_node); TreeNode new_result = new IntLiteral(((IntLiteral)result).Value + value); FunctionFunctionSet.VariableSet(Evaluator, args[0], new_result); return new_result; } } } hyena-0.5/Hyena/Hyena.SExpEngine/LogicFunctionSet.cs0000644000175000001440000000565011377105342022472 0ustar00gabeusers00000000000000// // LogicFunctionSet.cs // // Author: // Aaron Bockover // // Copyright (C) 2007-2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; namespace Hyena.SExpEngine { public class LogicFunctionSet : FunctionSet { [Function("not", "!")] public virtual TreeNode OnNot(TreeNode [] args) { if(args.Length != 1) { throw new ArgumentException("not must have only one argument"); } TreeNode arg = Evaluate(args[0]); if(!(arg is BooleanLiteral)) { throw new ArgumentException("can only not a boolean"); } return new BooleanLiteral(!(arg as BooleanLiteral).Value); } [Function("or", "|")] public virtual TreeNode OnOr(TreeNode [] args) { return OnAndOr(args, false); } [Function("and", "|")] public virtual TreeNode OnAnd(TreeNode [] args) { return OnAndOr(args, true); } private TreeNode OnAndOr(TreeNode [] args, bool and) { if(args.Length < 2) { throw new ArgumentException("must have two or more boolean arguments"); } bool result = false; for(int i = 0; i < args.Length; i++) { TreeNode node = Evaluate(args[i]); if(!(node is BooleanLiteral)) { throw new ArgumentException("arguments must be boolean"); } BooleanLiteral arg = (BooleanLiteral)node; if(i == 0) { result = arg.Value; continue; } if(and) { result &= arg.Value; } else { result |= arg.Value; } } return new BooleanLiteral(result); } } } hyena-0.5/Hyena/Hyena.SExpEngine/Evaluator.cs0000644000175000001440000000424711377105342021216 0ustar00gabeusers00000000000000// // Evaluator.cs // // Author: // Aaron Bockover // // Copyright (C) 2007-2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; namespace Hyena.SExpEngine { public class Evaluator : EvaluatorBase { public Evaluator() : base() { RegisterFunctions(); } public Evaluator(TreeNode expression) : base(expression) { RegisterFunctions(); } public Evaluator(string expression) : base(expression) { RegisterFunctions(); } private void RegisterFunctions() { RegisterFunctionSet(new ControlFunctionSet()); RegisterFunctionSet(new LogicFunctionSet()); RegisterFunctionSet(new FunctionFunctionSet()); RegisterFunctionSet(new CastFunctionSet()); RegisterFunctionSet(new CompareFunctionSet()); RegisterFunctionSet(new ArithmeticFunctionSet()); RegisterFunctionSet(new StringFunctionSet()); RegisterFunctionSet(new UtilityFunctionSet()); RegisterFunctionSet(new ListFunctionSet()); } } } hyena-0.5/Hyena/Hyena.SExpEngine/FunctionNode.cs0000644000175000001440000000772711377105342021655 0ustar00gabeusers00000000000000// // FunctionNode.cs // // Author: // Aaron Bockover // // Copyright (C) 2007-2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Collections.Generic; namespace Hyena.SExpEngine { public class InvalidFunctionException : Exception { public InvalidFunctionException(string message) : base(message) { } } public class FunctionNode : TreeNode { private string function; private object body; public FunctionNode(string function) { this.function = function; } public FunctionNode(string function, object body) { this.function = function; this.body = body; } public TreeNode Evaluate(EvaluatorBase evaluator, TreeNode [] args) { if(args != null && args.Length != FunctionCount && RequiresArguments) { throw new ArgumentException("Function " + function + " takes " + FunctionCount + " arguments, not " + args.Length); } if(args != null && RequiresArguments) { int i = 0; string [] names = new string[args.Length]; foreach(KeyValuePair var in Functions) { names[i++] = var.Key; } for(i = 0; i < args.Length; i++) { (body as TreeNode).RegisterFunction(names[i], evaluator.Evaluate(args[i])); } } return evaluator.Evaluate(ResolveBody(evaluator)); } private TreeNode ResolveBody(EvaluatorBase evaluator) { if(body == null) { throw new UnknownVariableException(Function); } if(body is string) { return new StringLiteral((string)body); } else if(body is double) { return new DoubleLiteral((double)body); } else if(body is int) { return new IntLiteral((int)body); } else if(body is bool) { return new BooleanLiteral((bool)body); } else if(body is SExpVariableResolutionHandler) { return ((SExpVariableResolutionHandler)body)(this); } else if(body is TreeNode) { return evaluator.Evaluate((TreeNode)body); } throw new UnknownVariableException(String.Format( "Unknown function type `{0}' for function `{1}'", body.GetType(), Function)); } public override string ToString() { return Function; } internal object Body { get { return body; } set { body = value; } } internal bool RequiresArguments { get { return FunctionCount > 0 && body is TreeNode; } } public string Function { get { return function; } } } } hyena-0.5/Hyena/Hyena.SExpEngine/TreeNode.cs0000644000175000001440000001326111377105342020755 0ustar00gabeusers00000000000000// // TreeNode.cs // // Author: // Aaron Bockover // // Copyright (C) 2007-2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Collections.Generic; using System.Collections.ObjectModel; namespace Hyena.SExpEngine { public class TreeNode { private List children = new List(); private Dictionary functions = new Dictionary(); private TreeNode parent; private int column; private int line; public TreeNode() { } public TreeNode(TreeNode parent) { this.parent = parent; parent.AddChild(this); } internal void CopyFunctionsFrom(TreeNode node) { foreach(KeyValuePair function in node.Functions) { RegisterFunction(function.Key, function.Value); } } internal void RegisterFunction(string name, object value) { if(functions.ContainsKey(name)) { functions[name] = new FunctionNode(name, value); } else { functions.Add(name, new FunctionNode(name, value)); } } internal void RegisterFunction(string name, FunctionNode function) { if(functions.ContainsKey(name)) { functions[name] = function; } else { functions.Add(name, function); } } public TreeNode Flatten() { TreeNode result_node = new TreeNode(); Flatten(result_node, this); return result_node.ChildCount == 1 ? result_node.Children[0] : result_node; } private void Flatten(TreeNode result_node, TreeNode node) { if(node == null) { return; } if(!node.HasChildren && !(node is VoidLiteral)) { result_node.AddChild(node); return; } foreach(TreeNode child_node in node.Children) { Flatten(result_node, child_node); } } public void AddChild(TreeNode child) { child.Parent = this; children.Add(child); } public TreeNode Parent { get { return parent; } set { parent = value; } } public int ChildCount { get { return children.Count; } } public bool HasChildren { get { return ChildCount > 0; } } public int Line { get { return line; } set { line = value; } } public int Column { get { return column; } set { column = value; } } public List Children { get { return children; } } public IDictionary Functions { get { return functions; } } public int FunctionCount { get { return functions.Count; } } public bool Empty { get { return ChildCount == 0 && !(this is LiteralNodeBase) && !(this is FunctionNode); } } public void Dump() { DumpTree(this); } public TreeNode FindRootNode() { TreeNode shift_node = this; while(shift_node.Parent != null) { shift_node = shift_node.Parent; } return shift_node; } public static void DumpTree(TreeNode node) { DumpTree(node, 0); } private static void DumpTree(TreeNode node, int depth) { if(node is LiteralNodeBase || node is FunctionNode) { PrintIndent(depth, node); } else if(node != null) { int i = 0; Console.Write("{0}+ [", String.Empty.PadLeft(depth * 2, ' ')); foreach(KeyValuePair function in node.Functions) { Console.Write("{0}{1}", function.Key, i++ < node.FunctionCount - 1 ? ", " : String.Empty); } Console.WriteLine("]"); foreach(TreeNode child in node.Children) { DumpTree(child, depth + 1); } } } private static void PrintIndent(int depth, TreeNode node) { Console.Write(String.Empty.PadLeft(depth * 2, ' ')); if(node is FunctionNode) { Console.WriteLine((node as FunctionNode).Function); } else { Console.WriteLine(node); } } } } hyena-0.5/Hyena/Hyena.SExpEngine/ControlFunctionSet.cs0000644000175000001440000000711111377105342023047 0ustar00gabeusers00000000000000// // ControlFunctionSet.cs // // Author: // Aaron Bockover // // Copyright (C) 2007-2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; namespace Hyena.SExpEngine { public class ControlFunctionSet : FunctionSet { [Function("if")] public virtual TreeNode OnIf(TreeNode [] args) { if(args == null || args.Length < 2 || args.Length > 3) { throw new ArgumentException("if accepts 2 or 3 arguments"); } TreeNode arg = Evaluate(args[0]); if(!(arg is BooleanLiteral)) { throw new ArgumentException("first if argument must be boolean"); } BooleanLiteral conditional = (BooleanLiteral)arg; if(conditional.Value) { return Evaluate(args[1]); } else if(args.Length == 3) { return Evaluate(args[2]); } return new VoidLiteral(); } [Function("while")] public virtual TreeNode OnWhile(TreeNode [] args) { if(args == null || args.Length < 1 || args.Length > 2) { throw new ArgumentException("while accepts a condition and an expression or just an expression"); } while(true) { if(args.Length == 2) { TreeNode result = Evaluate(args[0]); if(!(result is BooleanLiteral)) { throw new ArgumentException("condition is not boolean"); } if(!(result as BooleanLiteral).Value) { break; } } try { Evaluate(args[args.Length - 1]); } catch(Exception e) { if(BreakHandler(e)) { break; } } } return new VoidLiteral(); } [Function("break")] public virtual TreeNode OnBreak(TreeNode [] args) { throw new BreakException(); } private class BreakException : Exception { public BreakException() { } } public static bool BreakHandler(Exception e) { Exception parent_e = e; while(parent_e != null) { if(parent_e is BreakException) { return true; } parent_e = parent_e.InnerException; } throw e; } } } hyena-0.5/Hyena/Hyena.Downloader/0000777000175000001440000000000011453151001016777 5ustar00gabeusers00000000000000hyena-0.5/Hyena/Hyena.Downloader/Tests/0000777000175000001440000000000011453151001020101 5ustar00gabeusers00000000000000hyena-0.5/Hyena/Hyena.Downloader/Tests/HttpTestServer.cs0000644000175000001440000002027411452674367023427 0ustar00gabeusers00000000000000// // HttpTestServer.cs // // Author: // Aaron Bockover // // Copyright 2010 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #if ENABLE_TESTS using System; using System.IO; using System.Net; using System.Text; using System.Collections.Generic; using System.Security.Cryptography; namespace Hyena.Downloader.Tests { internal class HttpTestServer : IDisposable { private class Resource { public string Path; public string Checksum; public long Length; } private List resources = new List (); private bool stop_requested; private bool running; private bool serving; private HttpListener listener; public int ResourceCount { get; set; } public int MinResourceSize { get; set; } public int MaxResourceSize { get; set; } public bool IsServing { get { return serving; } } public bool Debug = true; public string BaseUrl { get { return "http://localhost:8080/"; } } public HttpTestServer () { ResourceCount = 5; MinResourceSize = 5 * 1024 * 1024; MaxResourceSize = 15 * 1024 * 1024; } public void Run () { stop_requested = false; running = true; GenerateStaticContent (); ServeStaticContent (); running = false; serving = false; } public void Dispose () { Stop (); } public void Stop () { lock (this) { if (!running) return; stop_requested = true; listener.Abort (); // busy wait, oh well if (Debug) Console.WriteLine ("waiting for server to stop"); while (running) {} if (Debug) Console.WriteLine (" > done waiting for server to stop"); } } private void ServeStaticContent () { if (Debug) Console.WriteLine (); if (Debug) Console.WriteLine ("Serving static content..."); listener = new HttpListener (); listener.Prefixes.Add (BaseUrl); listener.Start (); serving = true; while (!stop_requested) { var async_result = listener.BeginGetContext (result => { var context = listener.EndGetContext (result); var response = context.Response; var path = context.Request.Url.LocalPath; response.StatusCode = 200; response.StatusDescription = "OK"; response.ProtocolVersion = new Version ("1.1"); try { if (Debug) Console.WriteLine ("Serving: {0}", path); if (path == "/") { ServeString (response, resources.Count.ToString () + "\n"); return; } else if (path == "/shutdown") { ServeString (response, "Goodbye\n"); lock (this) { stop_requested = true; } } var resource = resources[Int32.Parse (path.Substring (1))]; response.ContentType = "application/octet-stream"; response.ContentLength64 = resource.Length; response.AppendHeader ("X-Content-MD5-Sum", resource.Checksum); if (context.Request.HttpMethod == "HEAD") { response.Close (); } using (var resource_stream = File.OpenRead (resource.Path)) { var buffer = new byte[32 << 10]; using (response.OutputStream) { while (true) { var read = resource_stream.Read (buffer, 0, buffer.Length); if (read <= 0) { break; } response.OutputStream.Write (buffer, 0, read); } } } } catch { response.StatusCode = 404; response.StatusDescription = "404 Not Found"; ServeString (response, "Invalid resource: " + path + "\n"); } response.Close (); }, null); async_result.AsyncWaitHandle.WaitOne (); } } private void ServeString (HttpListenerResponse response, string content) { var buffer = Encoding.UTF8.GetBytes (content); response.ContentType = "text/plain"; response.ContentLength64 = buffer.Length; using (var stream = response.OutputStream) { stream.Write (buffer, 0, buffer.Length); } } private void GenerateStaticContent () { resources.Clear (); var random = new Random (); var root = "/tmp/hyena-download-test-server"; try { Directory.Delete (root, true); } catch { } Directory.CreateDirectory (root); for (int i = 0; i < ResourceCount; i++) { var md5 = new MD5CryptoServiceProvider (); var resource = new Resource () { Path = Path.Combine (root, i.ToString ()), Length = random.Next (MinResourceSize, MaxResourceSize + 1) }; if (Debug) Console.WriteLine (); using (var stream = File.OpenWrite (resource.Path)) { var buffer = new byte[32 << 10]; long written = 0; long remaining; while ((remaining = resource.Length - written) > 0) { var buffer_length = remaining > buffer.Length ? (int)buffer.Length : (int)remaining; random.NextBytes (buffer); stream.Write (buffer, 0, buffer_length); written += buffer_length; md5.TransformBlock (buffer, 0, buffer_length, null, 0); if (Debug) Console.Write ("\rCreating resource: {0} ({1:0.00} MB): [{2}/{3}] {4:0.0}% ", resource.Path, resource.Length / 1024.0 / 1024.0, i + 1, ResourceCount, written / (double)resource.Length * 100.0); } md5.TransformFinalBlock (buffer, 0, 0); resource.Checksum = BitConverter.ToString (md5.Hash).Replace ("-", String.Empty).ToLower (); } resources.Add (resource); } } } } #endif hyena-0.5/Hyena/Hyena.Downloader/Tests/Tests.cs0000644000175000001440000000544511452674367021566 0ustar00gabeusers00000000000000// // Tests.cs // // Author: // Gabriel Burt // // Copyright (C) 2010 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // #if ENABLE_TESTS using System; using System.IO; using System.Linq; using NUnit.Framework; using Hyena; namespace Hyena.Downloader.Tests { [TestFixture] public class Tests { [Test] public void SimpleDownload () { StartServer (); new HttpStringDownloader () { Uri = new Uri (server.BaseUrl), Finished = (d) => { Assert.IsTrue (d.State.Success); Assert.AreEqual (server.ResourceCount.ToString () + "\n", d.Content); } }.StartSync (); var f = new HttpFileDownloader () { Uri = new Uri (server.BaseUrl + "/1") }; f.FileFinished += (d) => { Assert.IsTrue (d.State.Success); var size = new System.IO.FileInfo (d.LocalPath).Length; Assert.IsTrue (size <= server.MaxResourceSize); Assert.IsTrue (size >= server.MinResourceSize); System.IO.File.Delete (d.LocalPath); }; f.StartSync (); } [Test] public void DownloadManager () { } private void StartServer () { server.Stop (); new System.Threading.Thread (server.Run).Start (); while (!server.IsServing) {} } private HttpTestServer server; [TestFixtureSetUp] public void Setup () { server = new HttpTestServer (); server.Debug = false; } [TestFixtureTearDown] public void Teardown () { server.Dispose (); } } } #endif hyena-0.5/Hyena/Hyena.Downloader/HttpDownloaderState.cs0000644000175000001440000000447411452674367023322 0ustar00gabeusers00000000000000// // HttpDownloaderState.cs // // Author: // Aaron Bockover // // Copyright 2010 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. using System; namespace Hyena.Downloader { public class HttpDownloaderState { public DateTime StartTime { get; internal set; } public DateTime FinishTime { get; internal set; } public double PercentComplete { get; internal set; } public double TransferRate { get; internal set; } public Buffer Buffer { get; internal set; } public long TotalBytesRead { get; internal set; } public long TotalBytesExpected { get; internal set; } public bool Success { get; internal set; } public bool Working { get; internal set; } public string ContentType { get; internal set; } public string CharacterSet { get; internal set; } public Exception FailureException { get; internal set; } public override string ToString () { if (Working) { return String.Format ("HttpDownloaderState: working ({0}% complete)", PercentComplete * 100.0); } else { return String.Format ("HttpDownloaderState: finished, {0}", Success ? "successful" : "error: " + FailureException.Message); } } } } hyena-0.5/Hyena/Hyena.Downloader/DownloadManager.cs0000644000175000001440000001104311452674367022413 0ustar00gabeusers00000000000000// // DownloadManager.cs // // Author: // Aaron Bockover // // Copyright 2010 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. using System; using System.Collections.Generic; namespace Hyena.Downloader { public class DownloadManager { private object sync_root = new object (); internal object SyncRoot { get { return sync_root; } } private Queue pending_downloaders = new Queue (); private List active_downloaders = new List (); protected Queue PendingDownloaders { get { return pending_downloaders; } } internal List ActiveDownloaders { get { return active_downloaders; } } public event Action Started; public event Action Finished; public event Action Progress; public event Action BufferUpdated; public int MaxConcurrentDownloaders { get; set; } public int PendingDownloadCount { get { return pending_downloaders.Count; } } public int ActiveDownloadCount { get { return active_downloaders.Count; } } public int TotalDownloadCount { get { return PendingDownloadCount + ActiveDownloadCount; } } public DownloadManager () { MaxConcurrentDownloaders = 2; } public void QueueDownloader (HttpDownloader downloader) { lock (SyncRoot) { pending_downloaders.Enqueue (downloader); Update (); } } public void WaitUntilFinished () { while (TotalDownloadCount > 0); } private void Update () { lock (SyncRoot) { while (pending_downloaders.Count > 0 && active_downloaders.Count < MaxConcurrentDownloaders) { var downloader = pending_downloaders.Peek (); downloader.Started += OnDownloaderStarted; downloader.Finished += OnDownloaderFinished; downloader.Progress += OnDownloaderProgress; downloader.BufferUpdated += OnDownloaderBufferUpdated; active_downloaders.Add (downloader); pending_downloaders.Dequeue (); downloader.Start (); } } } protected virtual void OnDownloaderStarted (HttpDownloader downloader) { var handler = Started; if (handler != null) { handler (downloader); } } protected virtual void OnDownloaderFinished (HttpDownloader downloader) { lock (SyncRoot) { active_downloaders.Remove (downloader); Update (); } var handler = Finished; if (handler != null) { handler (downloader); } } protected virtual void OnDownloaderProgress (HttpDownloader downloader) { var handler = Progress; if (handler != null) { handler (downloader); } } protected virtual void OnDownloaderBufferUpdated (HttpDownloader downloader) { var handler = BufferUpdated; if (handler != null) { handler (downloader); } } } } hyena-0.5/Hyena/Hyena.Downloader/HttpFileDownloader.cs0000644000175000001440000000575711420137571023110 0ustar00gabeusers00000000000000// // HttpFileDownloader.cs // // Author: // Aaron Bockover // // Copyright 2010 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. using System; using System.IO; namespace Hyena.Downloader { public class HttpFileDownloader : HttpDownloader { private FileStream file_stream; public string TempPathRoot { get; set; } public string FileExtension { get; set; } public string LocalPath { get; private set; } public event Action FileFinished; public HttpFileDownloader () { TempPathRoot = System.IO.Path.GetTempPath (); } protected override void OnStarted () { Directory.CreateDirectory (TempPathRoot); LocalPath = Path.Combine (TempPathRoot, CryptoUtil.Md5Encode (Uri.AbsoluteUri)); if (!String.IsNullOrEmpty (FileExtension)) { LocalPath += "." + FileExtension; } base.OnStarted (); } protected override void OnBufferUpdated () { if (file_stream == null) { file_stream = new FileStream (LocalPath, FileMode.Create, FileAccess.Write); } file_stream.Write (State.Buffer.Data, 0, (int)State.Buffer.Length); base.OnBufferUpdated (); } protected override void OnFinished () { if (file_stream != null) { try { file_stream.Close (); file_stream = null; OnFileFinished (); } catch (Exception e) { Log.Exception (String.Format ("HttpFileDownloader.OnFinished ({0})", Uri), e); } } base.OnFinished (); } protected virtual void OnFileFinished () { var handler = FileFinished; if (handler != null) { handler (this); } } } } hyena-0.5/Hyena/Hyena.Downloader/HttpDownloader.cs0000644000175000001440000002275711420137571022307 0ustar00gabeusers00000000000000// // HttpDownloader.cs // // Author: // Aaron Bockover // // Copyright 2010 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. using System; using System.IO; using System.Net; using System.Threading; namespace Hyena.Downloader { public class HttpDownloader { private object sync_root = new object (); protected object SyncRoot { get { return sync_root; } } private HttpWebRequest request; private HttpWebResponse response; private Stream response_stream; private DateTime last_raised_percent_complete; private IAsyncResult async_begin_result; private ManualResetEvent sync_event; public string UserAgent { get; set; } public Uri Uri { get; set; } public TimeSpan ProgressEventRaiseLimit { get; set; } public HttpDownloaderState State { get; private set; } public string [] AcceptContentTypes { get; set; } private int buffer_size = 8192; public int BufferSize { get { return buffer_size; } set { if (value <= 0) { throw new InvalidOperationException ("Invalid buffer size"); } buffer_size = value; } } private string name; public string Name { get { return name ?? Path.GetFileName (Uri.UnescapeDataString (Uri.LocalPath)); } set { name = value; } } public event Action Started; public event Action Finished; public event Action Progress; public event Action BufferUpdated; public HttpDownloader () { ProgressEventRaiseLimit = TimeSpan.FromSeconds (0.25); } public void StartSync () { sync_event = new ManualResetEvent (false); Start (); sync_event.WaitOne (); sync_event = null; } public void Start () { lock (SyncRoot) { if (request != null || async_begin_result != null) { throw new InvalidOperationException ("HttpDownloader is already active"); } State = new HttpDownloaderState () { Buffer = new Buffer () { Data = new byte[BufferSize] } }; request = CreateRequest (); async_begin_result = request.BeginGetResponse (OnRequestResponse, this); State.StartTime = DateTime.Now; State.Working = true; OnStarted (); } } public void Abort () { lock (SyncRoot) { Close (); OnFinished (); } } private void Close () { lock (SyncRoot) { State.FinishTime = DateTime.Now; State.Working = false; if (response_stream != null) { response_stream.Close (); } if (response != null) { response.Close (); } response_stream = null; response = null; request = null; } } protected virtual HttpWebRequest CreateRequest () { var request = (HttpWebRequest)WebRequest.Create (Uri); request.Method = "GET"; request.AllowAutoRedirect = true; request.UserAgent = UserAgent; request.Timeout = 10000; return request; } private void OnRequestResponse (IAsyncResult asyncResult) { lock (SyncRoot) { async_begin_result = null; if (request == null) { return; } var raise = false; try { response = (HttpWebResponse)request.EndGetResponse (asyncResult); if (response.StatusCode != HttpStatusCode.OK) { State.Success = false; raise = true; return; } else if (AcceptContentTypes != null) { var accepted = false; foreach (var type in AcceptContentTypes) { if (type == response.ContentType) { accepted = true; break; } } if (!accepted) { throw new WebException ("Invalid content type: " + response.ContentType + "; expected one of: " + String.Join (", ", AcceptContentTypes)); } } State.ContentType = response.ContentType; State.CharacterSet = response.CharacterSet; State.TotalBytesExpected = response.ContentLength; response_stream = response.GetResponseStream (); async_begin_result = response_stream.BeginRead (State.Buffer.Data, 0, State.Buffer.Data.Length, OnResponseRead, this); } catch (Exception e) { State.FailureException = e; State.Success = false; raise = true; } finally { if (raise) { Close (); OnFinished (); } } } } private void OnResponseRead (IAsyncResult asyncResult) { lock (SyncRoot) { async_begin_result = null; if (request == null || response == null || response_stream == null) { return; } try { var now = DateTime.Now; State.Buffer.Length = response_stream.EndRead (asyncResult); State.Buffer.TimeStamp = now; State.TotalBytesRead += State.Buffer.Length; State.TransferRate = State.TotalBytesRead / (now - State.StartTime).TotalSeconds; State.PercentComplete = (double)State.TotalBytesRead / (double)State.TotalBytesExpected; OnBufferUpdated (); if (State.Buffer.Length <= 0) { State.Success = true; Close (); OnFinished (); return; } if (State.PercentComplete >= 1 || last_raised_percent_complete == DateTime.MinValue || (now - last_raised_percent_complete >= ProgressEventRaiseLimit)) { last_raised_percent_complete = now; OnProgress (); } async_begin_result = response_stream.BeginRead (State.Buffer.Data, 0, State.Buffer.Data.Length, OnResponseRead, this); } catch (Exception e) { State.FailureException = e; State.Success = false; Close (); OnFinished (); } } } protected virtual void OnStarted () { var handler = Started; if (handler != null) { handler (this); } } protected virtual void OnBufferUpdated () { var handler = BufferUpdated; if (handler != null) { handler (this); } } protected virtual void OnProgress () { var handler = Progress; if (handler != null) { handler (this); } } protected virtual void OnFinished () { var handler = Finished; if (handler != null) { try { handler (this); } catch (Exception e) { Log.Exception (String.Format ("HttpDownloader.Finished handler ({0})", Uri), e); } } if (sync_event != null) { sync_event.Set (); } } public override string ToString () { return Name; } } } hyena-0.5/Hyena/Hyena.Downloader/Buffer.cs0000644000175000001440000000257311417122613020551 0ustar00gabeusers00000000000000// // Buffer.cs // // Author: // Aaron Bockover // // Copyright 2010 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. using System; namespace Hyena.Downloader { public class Buffer { public int Length { get; set; } public DateTime TimeStamp { get; set; } public byte [] Data { get; set; } } } hyena-0.5/Hyena/Hyena.Downloader/HttpStringDownloader.cs0000644000175000001440000000500011420137571023454 0ustar00gabeusers00000000000000// // HttpStringDownloader.cs // // Author: // Aaron Bockover // // Copyright 2010 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. using System; using System.Text; namespace Hyena.Downloader { public class HttpStringDownloader : HttpDownloader { private Encoding detected_encoding; public string Content { get; private set; } public Encoding Encoding { get; set; } public new Action Finished { get; set; } protected override void OnBufferUpdated () { var default_encoding = Encoding.UTF8; if (detected_encoding == null && !String.IsNullOrEmpty (State.CharacterSet)) { try { detected_encoding = Encoding.GetEncoding (State.CharacterSet); } catch { } } if (detected_encoding == null) { detected_encoding = default_encoding; } Content += (Encoding ?? detected_encoding).GetString (State.Buffer.Data, 0, State.Buffer.Length); } protected override void OnFinished () { var handler = Finished; if (handler != null) { try { handler (this); } catch (Exception e) { Log.Exception (String.Format ("HttpStringDownloader.Finished handler ({0})", Uri), e); } } base.OnFinished (); } } } hyena-0.5/Hyena/Hyena.Downloader/DownloadManagerJob.cs0000644000175000001440000000707011452674367023053 0ustar00gabeusers00000000000000// // DownloadManagerJob.cs // // Author: // Aaron Bockover // Gabriel Burt // // Copyright 2010 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. using System; using System.IO; using System.Linq; using System.Collections.Generic; using Mono.Unix; using Hyena; namespace Hyena.Downloader { public class DownloadManagerJob : Hyena.Jobs.Job { private DownloadManager manager; private int finished_count = 0; public DownloadManagerJob (DownloadManager manager) { this.manager = manager; manager.Progress += OnDownloaderProgress; manager.Finished += OnDownloaderFinished; } private void OnDownloaderProgress (HttpDownloader downloader) { FreezeUpdate (); lock (manager.SyncRoot) { double weight = 1.0 / (manager.TotalDownloadCount + finished_count); double progress = finished_count * weight; double speed = 0; int count = 0; foreach (var active_downloader in manager.ActiveDownloaders) { progress += weight * active_downloader.State.PercentComplete; speed = active_downloader.State.TransferRate; count++; } Progress = progress; var human_speed = new Hyena.Query.FileSizeQueryValue ((long)Math.Round (speed)).ToUserQuery (); if (manager.PendingDownloadCount == 0) { Status = String.Format ( Catalog.GetPluralString ( "{0} download at {1}/s", "{0} downloads at {1}/s", count), count, human_speed ); } else { Status = String.Format ( Catalog.GetPluralString ( "{0} download at {1}/s ({2} pending)", "{0} downloads at {1}/s ({2} pending)", count), count, human_speed, manager.PendingDownloadCount ); } } ThawUpdate (true); } private void OnDownloaderFinished (HttpDownloader downloader) { lock (manager.SyncRoot) { finished_count++; if (manager.TotalDownloadCount <= 0) { OnFinished (); } } } } } hyena-0.5/Hyena/Hyena.Json/0000777000175000001440000000000011453151001015612 5ustar00gabeusers00000000000000hyena-0.5/Hyena/Hyena.Json/Token.cs0000644000175000001440000000645011377105342017236 0ustar00gabeusers00000000000000// // Token.cs // // Author: // Aaron Bockover // // Copyright (C) 2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; namespace Hyena.Json { internal class Token { public Token (TokenType type) : this (type, null) { } public Token (TokenType type, object value) { this.type = type; this.value = value; } private TokenType type; public TokenType Type { get { return type; } } private object value; public object Value { get { return value; } set { this.value = value; } } private int source_line; public int SourceLine { get { return source_line; } internal set { source_line = value; } } private int source_column; public int SourceColumn { get { return source_column; } internal set { source_column = value; } } internal static Token ObjectStart { get { return new Token (TokenType.ObjectStart); } } internal static Token ObjectFinish { get { return new Token (TokenType.ObjectFinish); } } internal static Token ArrayStart { get { return new Token (TokenType.ArrayStart); } } internal static Token ArrayFinish { get { return new Token (TokenType.ArrayFinish); } } internal static Token Null { get { return new Token (TokenType.Null); } } internal static Token Comma { get { return new Token (TokenType.Comma); } } internal static Token Colon { get { return new Token (TokenType.Colon); } } internal static Token Number (double value) { return new Token (TokenType.Number, value); } internal static Token Integer (int value) { return new Token (TokenType.Integer, value); } internal static Token String (string value) { return new Token (TokenType.String, value); } internal static Token Bool (bool value) { return new Token (TokenType.Boolean, value); } } } hyena-0.5/Hyena/Hyena.Json/Tests/0000777000175000001440000000000011453151001016714 5ustar00gabeusers00000000000000hyena-0.5/Hyena/Hyena.Json/Tests/SerializerTests.cs0000644000175000001440000001372411377105342022416 0ustar00gabeusers00000000000000// // SerializerTests.cs // // Authors: // Sandy Armstrong // // Copyright (c) 2009 Novell, Inc. (http://www.novell.com) // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // #if ENABLE_TESTS using System; using Hyena.Json; using NUnit.Framework; namespace Hyena.Json.Tests { [TestFixture] public class SerializerTests : Hyena.Tests.TestBase { [Test] public void SerializeBoolTest () { Serializer ser = new Serializer (true); Assert.AreEqual ("true", ser.Serialize ()); ser.SetInput (false); Assert.AreEqual ("false", ser.Serialize ()); } [Test] public void SerializeIntTest () { Serializer ser = new Serializer (12); Assert.AreEqual ("12", ser.Serialize ()); ser.SetInput (-658); Assert.AreEqual ("-658", ser.Serialize ()); ser.SetInput (0); Assert.AreEqual ("0", ser.Serialize ()); } [Test] public void SerializeDoubleTest () { Serializer ser = new Serializer (12.5); Assert.AreEqual ("12.5", ser.Serialize ()); ser.SetInput (-658.1); Assert.AreEqual ("-658.1", ser.Serialize ()); ser.SetInput (0.0); Assert.AreEqual ("0", ser.Serialize ()); ser.SetInput (0.1); Assert.AreEqual ("0.1", ser.Serialize ()); } [Test] public void SerializeStringTest () { VerifyString ("The cat\njumped \"over\" the rat! We escape with \\\"", @"""The cat\njumped \""over\"" the rat! We escape with \\\"""""); } [Test] public void EscapedCharactersTest () { VerifyString ("\\", @"""\\"""); VerifyString ("\b", @"""\b"""); VerifyString ("\f", @"""\f"""); VerifyString ("\n", @"""\n"""); VerifyString ("\r", @"""\r"""); VerifyString ("\t", @"""\t"""); VerifyString ("\u2022", "\"\u2022\""); } private void VerifyString (string original, string expectedSerialized) { Serializer ser = new Serializer (original); string output = ser.Serialize (); Assert.AreEqual (expectedSerialized, output, "Serialized Output"); Assert.AreEqual (original, new Deserializer (output).Deserialize (), "Input should be identical after serialized then deserialized back to string"); } [Test] public void SerializeNullTest () { Serializer ser = new Serializer (null); Assert.AreEqual ("null", ser.Serialize ()); } [Test] public void SerializeArrayTest () { JsonArray simpleArray = new JsonArray (); simpleArray.Add (1); simpleArray.Add ("text"); simpleArray.Add (0.1); simpleArray.Add ("5"); simpleArray.Add (false); simpleArray.Add (null); Serializer ser = new Serializer (simpleArray); Assert.AreEqual ("[1,\"text\",0.1,\"5\",false,null]", ser.Serialize ()); JsonArray emptyArray = new JsonArray (); ser.SetInput (emptyArray); Assert.AreEqual ("[]", ser.Serialize ()); } // TODO: Test arrays/objects in each other, various levels deep [Test] public void SerializeObjectTest () { JsonObject obj1 = new JsonObject (); obj1 ["intfield"] = 1; obj1 ["text field"] = "text"; obj1 ["double-field"] = 0.1; obj1 ["Boolean, Field"] = true; obj1 ["\"Null\"\nfield"] = null; Serializer ser = new Serializer (obj1); // Test object equality, since order not guaranteed string output = ser.Serialize (); JsonObject reconstitutedObj1 = (JsonObject) new Deserializer (output).Deserialize (); AssertJsonObjectsEqual (obj1, reconstitutedObj1); JsonObject obj2 = new JsonObject (); obj2 ["double-field"] = 0.1; obj2 ["\"Null\"\nfield"] = null; ser.SetInput (obj2); output = ser.Serialize (); Assert.IsTrue ((output == "{\"double-field\":0.1,\"\\\"Null\\\"\\nfield\":null}") || (output == "{\"\\\"Null\\\"\\nfield\":null,\"double-field\":0.1}"), "Serialized output format"); } private void AssertJsonObjectsEqual (JsonObject expectedObj, JsonObject actualObj) { Assert.AreEqual (expectedObj.Count, actualObj.Count, "Field count"); foreach (var expectedPair in expectedObj) Assert.AreEqual (expectedPair.Value, actualObj [expectedPair.Key], expectedPair.Key + " field"); } } } #endif hyena-0.5/Hyena/Hyena.Json/Tests/DeserializerTests.cs0000644000175000001440000000735411377105342022731 0ustar00gabeusers00000000000000// // DeserializerTests.cs // // Author: // Aaron Bockover // // Copyright (C) 2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // #if ENABLE_TESTS using System; using System.Reflection; using NUnit.Framework; using Hyena.Json; namespace Hyena.Json.Tests { [TestFixture] public class DeserializerTests : Hyena.Tests.TestBase { private Deserializer deserializer; [TestFixtureSetUp] public void Setup () { deserializer = new Deserializer (); } [Test] public void Literal () { Assert.AreEqual ("hello", (string)deserializer.SetInput ("\"hello\"").Deserialize ()); Assert.AreEqual (-1.76e-3, (double)deserializer.SetInput ("-1.76e-3").Deserialize ()); Assert.AreEqual (null, deserializer.SetInput ("null").Deserialize ()); Assert.AreEqual (true, (bool)deserializer.SetInput ("true").Deserialize ()); Assert.AreEqual (false, (bool)deserializer.SetInput ("false").Deserialize ()); } [Test] public void Array () { JsonArray array = (JsonArray)deserializer.SetInput ("[]").Deserialize (); Assert.AreEqual (0, array.Count); array = (JsonArray)deserializer.SetInput ("[[]]").Deserialize (); Assert.AreEqual (1, array.Count); Assert.AreEqual (0, ((JsonArray)array[0]).Count); array = (JsonArray)deserializer.SetInput ("[[true,[]]]").Deserialize (); Assert.AreEqual (1, array.Count); Assert.AreEqual (2, ((JsonArray)array[0]).Count); Assert.AreEqual (0, ((JsonArray)((JsonArray)array[0])[1]).Count); array = (JsonArray)deserializer.SetInput ("[\"a\", 1.0, true]").Deserialize (); Assert.AreEqual (3, array.Count); Assert.AreEqual ("a", (string)array[0]); Assert.AreEqual (1, (double)array[1]); Assert.AreEqual (true, (bool)array[2]); } [Test] public void Object () { JsonObject obj = (JsonObject)deserializer.SetInput ("{}").Deserialize (); Assert.AreEqual (0, obj.Count); obj = (JsonObject)deserializer.SetInput ("{\"a\":{}}").Deserialize (); Assert.AreEqual (1, obj.Count); Assert.AreEqual (0, ((JsonObject)obj["a"]).Count); obj = (JsonObject)deserializer.SetInput ("{\"a\":[{\"b\":false},\"c\"]}").Deserialize (); Assert.AreEqual (1, obj.Count); JsonArray arr = (JsonArray)obj["a"]; Assert.AreEqual (2, arr.Count); Assert.AreEqual (false, ((JsonObject)arr[0])["b"]); Assert.AreEqual ("c", (string)arr[1]); } } } #endif hyena-0.5/Hyena/Hyena.Json/Tests/TokenizerTests.cs0000644000175000001440000002111611377105342022251 0ustar00gabeusers00000000000000// // TokenizerTests.cs // // Author: // Aaron Bockover // // Copyright (C) 2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // #if ENABLE_TESTS using System; using System.Reflection; using NUnit.Framework; using Hyena.Json; namespace Hyena.Json.Tests { [TestFixture] public class TokenizerTests : Hyena.Tests.TestBase { private Tokenizer tokenizer; [TestFixtureSetUp] public void Setup () { tokenizer = new Tokenizer (); } [Test] public void Whitespace () { AssertTokenStream (""); AssertTokenStream (" "); AssertTokenStream ("\f\n\r\t "); } [Test] public void BoolNull () { // Boolean/null tests AssertTokenStream ("true", Token.Bool (true)); AssertTokenStream ("false", Token.Bool (false)); AssertTokenStream ("null", Token.Null); } [Test] public void NumberInt () { AssertTokenStream ("0", Token.Integer (0)); AssertTokenStream ("-0", Token.Integer (-0)); AssertTokenStream ("9", Token.Integer (9)); AssertTokenStream ("-9", Token.Integer (-9)); AssertTokenStream ("14", Token.Integer (14)); AssertTokenStream ("-14", Token.Integer (-14)); AssertTokenStream ("15309", Token.Integer (15309)); AssertTokenStream ("-15309", Token.Integer (-15309)); } [Test] public void NumberFloat () { AssertTokenStream ("0.0", Token.Number (0.0)); AssertTokenStream ("-0.0", Token.Number (-0.0)); AssertTokenStream ("1.9", Token.Number (1.9)); AssertTokenStream ("-1.9", Token.Number (-1.9)); AssertTokenStream ("9.1", Token.Number (9.1)); AssertTokenStream ("-9.1", Token.Number (-9.1)); AssertTokenStream ("15309.0", Token.Number (15309.0)); AssertTokenStream ("15309.9", Token.Number (15309.9)); AssertTokenStream ("-15309.01", Token.Number (-15309.01)); AssertTokenStream ("-15309.9009", Token.Number (-15309.9009)); } [Test] public void NumberExponent () { AssertTokenStream ("20.6e3", Token.Number (20.6e3)); AssertTokenStream ("20.6e+3", Token.Number (20.6e+3)); AssertTokenStream ("20.6e-3", Token.Number (20.6e-3)); AssertTokenStream ("-20.6e3", Token.Number (-20.6e3)); AssertTokenStream ("-20.6e+3", Token.Number (-20.6e+3)); AssertTokenStream ("-20.6e-3", Token.Number (-20.6e-3)); AssertTokenStream ("1e1", Token.Number (1e1)); AssertTokenStream ("1E2", Token.Number (1E2)); AssertTokenStream ("1.0e1", Token.Number (1.0e1)); AssertTokenStream ("1.0E1", Token.Number (1.0E1)); } [Test] public void Strings () { AssertTokenStream (@"""""", Token.String ("")); AssertTokenStream (@"""a""", Token.String ("a")); AssertTokenStream (@"""ab""", Token.String ("ab")); AssertTokenStream (@" ""a b"" ", Token.String ("a b")); AssertTokenStream (@"""\""\""""", Token.String ("\"\"")); AssertTokenStream (@" ""a \"" \"" b"" ", Token.String ("a \" \" b")); AssertTokenStream (@"""\ubeef""", Token.String ("\ubeef")); AssertTokenStream (@"""\u00a9""", Token.String ("\u00a9")); AssertTokenStream (@"""\u0000\u0001\u0002""", Token.String ("\u0000\u0001\u0002")); AssertTokenStream (@"""1\uabcdef0""", Token.String ("1\uabcdef0")); AssertTokenStream (@"""\b\f\n\r\t""", Token.String ("\b\f\n\r\t")); } [Test] public void Container () { AssertTokenStream ("{}", Token.ObjectStart, Token.ObjectFinish); AssertTokenStream ("[]", Token.ArrayStart, Token.ArrayFinish); AssertTokenStream ("{ }", Token.ObjectStart, Token.ObjectFinish); AssertTokenStream ("[ ]", Token.ArrayStart, Token.ArrayFinish); AssertTokenStream ("[{}]", Token.ArrayStart, Token.ObjectStart, Token.ObjectFinish, Token.ArrayFinish); AssertTokenStream ("[[[ { } ]]]", Token.ArrayStart, Token.ArrayStart, Token.ArrayStart, Token.ObjectStart, Token.ObjectFinish, Token.ArrayFinish, Token.ArrayFinish, Token.ArrayFinish); } [Test] public void Array () { AssertTokenStream ("[1]", Token.ArrayStart, Token.Integer (1), Token.ArrayFinish); AssertTokenStream ("[1,0]", Token.ArrayStart, Token.Integer (1), Token.Comma, Token.Integer (0), Token.ArrayFinish); AssertTokenStream ("[\"a\",true,null]", Token.ArrayStart, Token.String ("a"), Token.Comma, Token.Bool (true), Token.Comma, Token.Null, Token.ArrayFinish); AssertTokenStream ("[0,1,[[2,[4]],5],6]", Token.ArrayStart, Token.Integer (0), Token.Comma, Token.Integer (1), Token.Comma, Token.ArrayStart, Token.ArrayStart, Token.Integer (2), Token.Comma, Token.ArrayStart, Token.Integer (4), Token.ArrayFinish, Token.ArrayFinish, Token.Comma, Token.Integer (5), Token.ArrayFinish, Token.Comma, Token.Integer (6), Token.ArrayFinish); } [Test] public void Object () { AssertTokenStream ("{\"a\":{}}", Token.ObjectStart, Token.String ("a"), Token.Colon, Token.ObjectStart, Token.ObjectFinish, Token.ObjectFinish); AssertTokenStream ("{\"a\":{\"b\":[],\"c\":false}}", Token.ObjectStart, Token.String ("a"), Token.Colon, Token.ObjectStart, Token.String ("b"), Token.Colon, Token.ArrayStart, Token.ArrayFinish, Token.Comma, Token.String ("c"), Token.Colon, Token.Bool (false), Token.ObjectFinish, Token.ObjectFinish); AssertTokenStream ("[{\"a\":{},{}]", Token.ArrayStart, Token.ObjectStart, Token.String ("a"), Token.Colon, Token.ObjectStart, Token.ObjectFinish, Token.Comma, Token.ObjectStart, Token.ObjectFinish, Token.ArrayFinish); } private void AssertTokenStream (string input, params Token [] tokens) { int cmp_idx = 0; tokenizer.SetInput (input); while (true) { Token token = tokenizer.Scan (); if (token == null) { if (cmp_idx != tokens.Length) { throw new ApplicationException ("Unexpected EOF"); } break; } Token compare = tokens[cmp_idx++]; if (compare.Type != token.Type) { throw new ApplicationException (String.Format ("TokenTypes do not match (exp {0}, got {1}", compare.Type, token.Type)); } if (compare.Value == null && token.Value == null) { continue; } if ((compare.Type == TokenType.Integer && (int)compare.Value != (int)token.Value) || (compare.Type == TokenType.Number && (double)compare.Value != (double)token.Value) || (compare.Type == TokenType.String && (string)compare.Value != (string)token.Value) || (compare.Type == TokenType.Boolean && (bool)compare.Value != (bool)token.Value)) { throw new ApplicationException ("Token values do not match"); } } } } } #endif hyena-0.5/Hyena/Hyena.Json/JsonArray.cs0000644000175000001440000000320311377105342020057 0ustar00gabeusers00000000000000// // JsonArray.cs // // Author: // Aaron Bockover // // Copyright (C) 2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Linq; using System.Collections.Generic; using System.Text; namespace Hyena.Json { public class JsonArray : List, IJsonCollection { public void Dump () { Dump (1); } public void Dump (int level) { Console.Write (ToString ()); } public override string ToString () { return new Serializer (this).Serialize (); } } } hyena-0.5/Hyena/Hyena.Json/Serializer.cs0000644000175000001440000001160511377105342020265 0ustar00gabeusers00000000000000// // Serializer.cs // // Copyright (c) 2009 Novell, Inc. (http://www.novell.com) // // Authors: // Sandy Armstrong // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Text; namespace Hyena.Json { public class Serializer { private const string serializedNull = "null"; private const string serializedTrue = "true"; private const string serializedFalse = "false"; private object input; public Serializer () { } public Serializer (object input) { SetInput (input); } public void SetInput (object input) { this.input = input; } // TODO: Support serialize to stream? public string Serialize () { return Serialize (input); } private string SerializeBool (bool val) { return val ? serializedTrue : serializedFalse; } private string SerializeInt (int val) { return val.ToString (); } private string SerializeDouble (double val) { return val.ToString (System.Globalization.CultureInfo.InvariantCulture.NumberFormat); } // TODO: exponent stuff private string SerializeString (string val) { // TODO: More work, escaping, etc return "\"" + val.Replace ("\\", "\\\\"). Replace ("\"", "\\\""). Replace ("\b", "\\b"). Replace ("\f", "\\f"). Replace ("\n", "\\n"). Replace ("\r", "\\r"). Replace ("\t", "\\t") + "\""; } private string SerializeEnumerable (IEnumerable array) { StringBuilder builder = new StringBuilder ("["); int i = 0; foreach (var obj in array) { builder.Append (Serialize (obj)); builder.Append (","); i++; } // Get rid of trailing comma if (i > 0) builder.Remove (builder.Length - 1, 1); builder.Append ("]"); return builder.ToString (); } private string SerializeDictionary (Dictionary obj) { StringBuilder builder = new StringBuilder ("{"); foreach (var pair in obj) { builder.Append (SerializeString (pair.Key)); builder.Append (":"); builder.Append (Serialize (pair.Value)); builder.Append (","); } // Get rid of trailing comma if (obj.Count > 0) builder.Remove (builder.Length - 1, 1); builder.Append ("}"); return builder.ToString (); } private string Serialize (object unknownObj) { if (unknownObj == null) return serializedNull; bool? b = unknownObj as bool?; if (b.HasValue) return SerializeBool (b.Value); int? i = unknownObj as int?; if (i.HasValue) return SerializeInt (i.Value); double? d = unknownObj as double?; if (d.HasValue) return SerializeDouble (d.Value); string s = unknownObj as string; if (s != null) return SerializeString (s); var o = unknownObj as Dictionary; if (o != null) return SerializeDictionary (o); var a = unknownObj as IEnumerable; if (a != null) return SerializeEnumerable (a); throw new ArgumentException ("Cannot serialize anything but doubles, integers, strings, JsonObjects, and JsonArrays"); } } } hyena-0.5/Hyena/Hyena.Json/TokenType.cs0000644000175000001440000000326711377105342020103 0ustar00gabeusers00000000000000// // TokenType.cs // // Author: // Aaron Bockover // // Copyright (C) 2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; namespace Hyena.Json { [Flags] internal enum TokenType { None = 0 << 0, ObjectStart = 1 << 0, ObjectFinish = 1 << 1, ArrayStart = 1 << 2, ArrayFinish = 1 << 3, Boolean = 1 << 4, String = 1 << 5, Null = 1 << 6, Number = 1 << 7, Integer = 1 << 8, Comma = 1 << 9, Colon = 1 << 10, Literal = String | Number | Boolean | Null | Integer, Value = ObjectStart | ArrayStart | Literal } } hyena-0.5/Hyena/Hyena.Json/Tokenizer.cs0000644000175000001440000002471611377105342020135 0ustar00gabeusers00000000000000// // Tokenizer.cs // // Author: // Aaron Bockover // // Copyright (C) 2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.IO; using System.Text; namespace Hyena.Json { internal class Tokenizer { private StreamReader reader; private StringBuilder string_buffer; private char peek = ' '; private int current_line = 1; private int current_column = 1; private int token_start_line; private int token_start_column; public Tokenizer () { Reset (); } public Tokenizer (string input) { SetInput (input); } public Tokenizer (Stream stream) { SetInput (stream); } public Tokenizer (StreamReader reader) { SetInput (reader); } private void Reset () { peek = ' '; current_line = 1; current_column = 1; token_start_line = 0; token_start_column = 0; } public void SetInput (StreamReader reader) { this.reader = reader; Reset (); } public void SetInput (Stream stream) { SetInput (new StreamReader (stream)); } public void SetInput (string input) { SetInput (new MemoryStream (Encoding.UTF8.GetBytes (input))); } private void ReadChar () { int val = reader.Read (); peek = val == -1 ? Char.MaxValue : (char)val; current_column++; } private void UnexpectedCharacter (char ch) { throw new ApplicationException (String.Format ("Unexpected character '{0}' at [{1}:{2}]", ch, current_line, current_column - 1)); } private void InvalidSyntax (string message) { throw new ApplicationException (String.Format ("Invalid syntax: {0} at [{1}:{2}]", message, current_line, current_column)); } private StringBuilder GetStringBuilder () { if (string_buffer == null) { string_buffer = new StringBuilder (64); return string_buffer; } string_buffer.Remove (0, string_buffer.Length); return string_buffer; } private string LexString () { StringBuilder buffer = GetStringBuilder (); bool read = true; while (!reader.EndOfStream) { if (read) { ReadChar (); } read = true; if (peek == '\\') { ReadChar (); switch (peek) { case 'u': ReadChar (); buffer.Append ((char)LexInt (true, 4)); read = false; break; case '"': case '\\': case '/': buffer.Append (peek); break; case 'b': buffer.Append ('\b'); break; case 'f': buffer.Append ('\f'); break; case 'n': buffer.Append ('\n'); break; case 'r': buffer.Append ('\r'); break; case 't': buffer.Append ('\t'); break; default: UnexpectedCharacter (peek); break; } } else if (peek == '"') { ReadChar (); return buffer.ToString (); } else { buffer.Append (peek); } } if (peek != '"') { InvalidSyntax ("Unterminated string, expected '\"' termination, got '" + peek + "'"); } else if (!read && reader.EndOfStream) { ReadChar (); } return buffer.ToString (); } private string LexId () { StringBuilder buffer = GetStringBuilder (); do { buffer.Append (peek); ReadChar (); } while (Char.IsLetterOrDigit (peek)); return buffer.ToString (); } private int LexInt () { return LexInt (false, 0); } private int LexInt (bool hex, int maxDigits) { int value = 0; int count = 0; do { value = (hex ? 16 : 10) * value + (hex ? peek >= 'A' && peek <= 'F' ? 10 + peek - 'A' : (peek >= 'a' && peek <= 'f' ? 10 + peek - 'a' : peek - '0') : peek - '0'); if (maxDigits > 0 && ++count >= maxDigits) { ReadChar (); return value; } ReadChar (); } while (Char.IsDigit (peek) || (hex && ((peek >= 'a' && peek <= 'f') || (peek >= 'A' && peek <= 'F')))); return value; } private double LexFraction () { double fraction = 0; double d = 10; while (true) { ReadChar (); if (!Char.IsDigit (peek)) { break; } fraction += (peek - '0') / d; d *= 10; } return fraction; } private object LexNumber (out bool isDouble) { isDouble = false; int intVal = 0; double doubleVal = 0.0; bool negate = peek == '-'; if (negate) { ReadChar (); } if (peek != '0') { doubleVal = intVal = LexInt (); } else { ReadChar (); } if (peek == '.') { isDouble = true; doubleVal += LexFraction (); } if (peek == 'e' || peek == 'E') { isDouble = true; ReadChar (); if (peek == '-') { ReadChar (); doubleVal /= Math.Pow (10, LexInt ()); } else if (peek == '+') { ReadChar (); doubleVal *= Math.Pow (10, LexInt ()); } else if (Char.IsDigit (peek)) { doubleVal *= Math.Pow (10, LexInt ()); } else { InvalidSyntax ("Malformed exponent"); } } if (Char.IsDigit (peek)) { InvalidSyntax ("Numbers starting with 0 must be followed by a . or not " + "followed by a digit (octal syntax not legal)"); } if (!isDouble) return negate ? -1 * intVal : intVal; else return negate ? -1.0 * doubleVal : doubleVal; } public Token Scan () { Token token = InnerScan (); if (token == null) { return null; } token.SourceLine = token_start_line; token.SourceColumn = token_start_column - 1; return token; } private Token InnerScan () { for (; ; ReadChar ()) { if (Char.IsWhiteSpace (peek) && peek != '\n') { continue; } else if (peek == '\n') { current_line++; current_column = 0; } else { break; } } token_start_column = current_column; token_start_line = current_line; switch (peek) { case '{': ReadChar (); return new Token (TokenType.ObjectStart); case '}': ReadChar (); return new Token (TokenType.ObjectFinish); case '[': ReadChar (); return new Token (TokenType.ArrayStart); case ']': ReadChar (); return new Token (TokenType.ArrayFinish); case ',': ReadChar (); return new Token (TokenType.Comma); case ':': ReadChar (); return new Token (TokenType.Colon); case '"': return new Token (TokenType.String, LexString ()); default: if (peek == '-' || Char.IsDigit (peek)) { bool isDouble; object num = LexNumber (out isDouble); if (!isDouble) return new Token (TokenType.Integer, num); else return new Token (TokenType.Number, num); } else if (Char.IsLetter (peek)) { string identifier = LexId (); switch (identifier) { case "true": return new Token (TokenType.Boolean, true); case "false": return new Token (TokenType.Boolean, false); case "null": return new Token (TokenType.Null); default: InvalidSyntax ("Invalid identifier '" + identifier + "'"); break; } } if (peek != Char.MaxValue) { UnexpectedCharacter (peek); } break; } return null; } } } hyena-0.5/Hyena/Hyena.Json/JsonObject.cs0000644000175000001440000000322311377105342020211 0ustar00gabeusers00000000000000// // JsonObject.cs // // Author: // Aaron Bockover // // Copyright (C) 2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Linq; using System.Collections.Generic; using System.Text; namespace Hyena.Json { public class JsonObject : Dictionary, IJsonCollection { public void Dump () { Dump (1); } public void Dump (int level) { Console.Write (ToString ()); } public override string ToString () { return new Serializer (this).Serialize (); } } } hyena-0.5/Hyena/Hyena.Json/IJsonCollection.cs0000644000175000001440000000257311377105342021216 0ustar00gabeusers00000000000000// // IJsonCollection.cs // // Author: // Aaron Bockover // // Copyright (C) 2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Collections; using System.Text; namespace Hyena.Json { public interface IJsonCollection : ICollection { void Dump (); void Dump (int count); } } hyena-0.5/Hyena/Hyena.Json/Deserializer.cs0000644000175000001440000001205611377105342020577 0ustar00gabeusers00000000000000// // Deserializer.cs // // Author: // Aaron Bockover // // Copyright (C) 2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.IO; namespace Hyena.Json { public class Deserializer { private Tokenizer tokenizer = new Tokenizer (); public Deserializer () { } public Deserializer (string input) { SetInput (input); } public Deserializer (Stream stream) { SetInput (stream); } public Deserializer (StreamReader reader) { SetInput (reader); } public Deserializer SetInput (StreamReader reader) { tokenizer.SetInput (reader); return this; } public Deserializer SetInput (Stream stream) { tokenizer.SetInput (stream); return this; } public Deserializer SetInput (string input) { tokenizer.SetInput (input); return this; } public object Deserialize () { Token token = CheckScan (TokenType.Value, true); if (token == null) { return null; } return Parse (token); } private object Parse (Token token) { if (token.Type == TokenType.ObjectStart) { return ParseObject (); } else if (token.Type == TokenType.ArrayStart) { return ParseArray (); } return token.Value; } private JsonObject ParseObject () { JsonObject obj = new JsonObject (); while (true) { Token key = CheckScan (TokenType.String | TokenType.ObjectFinish); if (key.Type == TokenType.ObjectFinish) { break; } CheckScan (TokenType.Colon); Token value = CheckScan (TokenType.Value); object value_val = value.Value; if (value.Type == TokenType.ArrayStart) { value_val = ParseArray (); } else if (value.Type == TokenType.ObjectStart) { value_val = ParseObject (); } obj.Add ((string)key.Value, value_val); Token token = CheckScan (TokenType.Comma | TokenType.ObjectFinish); if (token.Type == TokenType.ObjectFinish) { break; } } return obj; } private JsonArray ParseArray () { JsonArray array = new JsonArray (); while (true) { Token value = CheckScan (TokenType.Value | TokenType.ArrayFinish); if (value.Type == TokenType.ArrayFinish) { break; } array.Add (Parse (value)); Token token = CheckScan (TokenType.Comma | TokenType.ArrayFinish); if (token.Type == TokenType.ArrayFinish) { break; } } return array; } private Token CheckScan (TokenType expected) { return CheckScan (expected, false); } private Token CheckScan (TokenType expected, bool eofok) { Token token = tokenizer.Scan (); if (token == null && eofok) { return null; } else if (token == null) { UnexpectedEof (expected); } else if ((expected & token.Type) == 0) { UnexpectedToken (expected, token); } return token; } private void UnexpectedToken (TokenType expected, Token got) { throw new ApplicationException (String.Format ("Unexpected token {0} at [{1}:{2}]; expected {3}", got.Type, got.SourceLine, got.SourceColumn, expected)); } private void UnexpectedEof (TokenType expected) { throw new ApplicationException (String.Format ("Unexpected End of File; expected {0}", expected)); } } } hyena-0.5/Hyena/Hyena.dll.config0000644000175000001440000000027111430346046016651 0ustar00gabeusers00000000000000 hyena-0.5/Hyena/Hyena.Collections/0000777000175000001440000000000011453151001017157 5ustar00gabeusers00000000000000hyena-0.5/Hyena/Hyena.Collections/Tests/0000777000175000001440000000000011453151001020261 5ustar00gabeusers00000000000000hyena-0.5/Hyena/Hyena.Collections/Tests/IntervalHeapTests.cs0000644000175000001440000000664111377105342024234 0ustar00gabeusers00000000000000// // IntervalHeapTests.cs // // Author: // Aaron Bockover // // Copyright (C) 2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // #if ENABLE_TESTS using System; using NUnit.Framework; using Hyena.Collections; namespace Hyena.Collections.Tests { [TestFixture] public class IntervalHeapTests { private IntervalHeap heap; private static int [] heap_data = new int[2048]; [TestFixtureSetUp] public void Init() { heap = new IntervalHeap(); for(int i = 0; i < heap_data.Length; i++) { heap_data[i] = i; } } private void PopulateHeap() { heap.Clear(); foreach(int i in heap_data) { heap.Push(i, 0); } Assert.AreEqual(heap.Count, heap_data.Length); } [Test] public void PopHeap() { PopulateHeap(); int i = 0; while(heap.Count > 0) { heap.Pop(); i++; } Assert.AreEqual(i, heap_data.Length); } [Test] public void IterateHeap() { PopulateHeap(); int i = 0; foreach(int x in heap) { Assert.AreEqual(x, heap_data[i++]); } Assert.AreEqual(i, heap.Count); } [Test] public void RemoveItemsFromHeap() { IntervalHeap h = new IntervalHeap(); for(int i = 0; i < 20; i++) { h.Push(i, i); } h.Remove(10); h.Remove(2); h.Remove(11); h.Remove(9); h.Remove(19); h.Remove(0); Assert.AreEqual(h.Pop(), 18); Assert.AreEqual(h.Pop(), 17); Assert.AreEqual(h.Pop(), 16); Assert.AreEqual(h.Pop(), 15); Assert.AreEqual(h.Pop(), 14); Assert.AreEqual(h.Pop(), 13); Assert.AreEqual(h.Pop(), 12); Assert.AreEqual(h.Pop(), 8); Assert.AreEqual(h.Pop(), 7); Assert.AreEqual(h.Pop(), 6); Assert.AreEqual(h.Pop(), 5); Assert.AreEqual(h.Pop(), 4); Assert.AreEqual(h.Pop(), 3); Assert.AreEqual(h.Pop(), 1); Assert.AreEqual(h.Count, 0); } } } #endif hyena-0.5/Hyena/Hyena.Collections/Tests/RangeCollectionTests.cs0000644000175000001440000003665211377105342024727 0ustar00gabeusers00000000000000// // RangeCollectionTests.cs // // Author: // Aaron Bockover // // Copyright (C) 2007-2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // #if ENABLE_TESTS using System; using System.Collections.Generic; using NUnit.Framework; using Hyena.Collections; namespace Hyena.Collections.Tests { [TestFixture] public class RangeCollectionTests { [Test] public void SingleRanges () { _TestRanges (new RangeCollection (), new int [] { 1, 11, 5, 7, 15, 32, 3, 9, 34 }); } [Test] public void MergedRanges () { RangeCollection range = new RangeCollection (); int [] indexes = new int [] { 0, 7, 5, 9, 1, 6, 8, 2, 10, 12 }; _TestRanges (range, indexes); Assert.AreEqual (3, range.RangeCount); int i= 0; foreach (RangeCollection.Range r in range.Ranges) { switch (i++) { case 0: Assert.AreEqual (0, r.Start); Assert.AreEqual (2, r.End); break; case 1: Assert.AreEqual (5, r.Start); Assert.AreEqual (10, r.End); break; case 2: Assert.AreEqual (12, r.Start); Assert.AreEqual (12, r.End); break; default: Assert.Fail ("This should not be reached!"); break; } } } [Test] public void LargeSequentialContains () { RangeCollection range = new RangeCollection (); int i, n = 1000000; for (i = 0; i < n; i++) { range.Add (i); } for (i = 0; i < n; i++) { Assert.AreEqual (true, range.Contains (i)); } } [Test] public void LargeSequential () { RangeCollection range = new RangeCollection (); int i, n = 1000000; for (i = 0; i < n; i++) { range.Add (i); Assert.AreEqual (1, range.RangeCount); } Assert.AreEqual (n, range.Count); i = 0; foreach (int j in range) { Assert.AreEqual (i++, j); } Assert.AreEqual (n, i); } [Test] public void LargeNonAdjacent () { RangeCollection range = new RangeCollection (); int i, n = 1000000; for (i = 0; i < n; i += 2) { range.Add (i); } Assert.AreEqual (n / 2, range.Count); i = 0; foreach (int j in range) { Assert.AreEqual (i, j); i += 2; } Assert.AreEqual (n, i); } private static void _TestRanges (RangeCollection range, int [] indexes) { foreach (int index in indexes) { range.Add (index); } Assert.AreEqual (indexes.Length, range.Count); Array.Sort (indexes); int i = 0; foreach (int index in range) { Assert.AreEqual (indexes[i++], index); } #pragma warning disable 0618 i = 0; foreach (int index in range.Indexes) { Assert.AreEqual (indexes[i++], index); } for (i = 0; i < range.Indexes.Length; i++) { Assert.AreEqual (indexes[i], range.Indexes[i]); } #pragma warning restore 0618 } [Test] public void RemoveSingles () { RangeCollection range = new RangeCollection (); int [] indexes = new int [] { 0, 2, 4, 6, 8, 10, 12, 14 }; foreach (int index in indexes) { range.Add (index); } foreach (int index in indexes) { Assert.AreEqual (true, range.Remove (index)); } } [Test] public void RemoveStarts () { RangeCollection range = _SetupTestRemoveMerges (); Assert.AreEqual (true, range.Contains (0)); range.Remove (0); Assert.AreEqual (false, range.Contains (0)); Assert.AreEqual (4, range.RangeCount); Assert.AreEqual (true, range.Contains (2)); range.Remove (2); Assert.AreEqual (false, range.Contains (2)); Assert.AreEqual (4, range.RangeCount); Assert.AreEqual (3, range.Ranges[0].Start); Assert.AreEqual (5, range.Ranges[0].End); Assert.AreEqual (true, range.Contains (14)); range.Remove (14); Assert.AreEqual (false, range.Contains (14)); Assert.AreEqual (4, range.RangeCount); Assert.AreEqual (15, range.Ranges[2].Start); Assert.AreEqual (15, range.Ranges[2].End); } [Test] public void RemoveEnds () { RangeCollection range = _SetupTestRemoveMerges (); Assert.AreEqual (true, range.Contains (5)); range.Remove (5); Assert.AreEqual (false, range.Contains (5)); Assert.AreEqual (5, range.RangeCount); Assert.AreEqual (2, range.Ranges[1].Start); Assert.AreEqual (4, range.Ranges[1].End); Assert.AreEqual (true, range.Contains (15)); range.Remove (15); Assert.AreEqual (false, range.Contains (15)); Assert.AreEqual (5, range.RangeCount); Assert.AreEqual (14, range.Ranges[3].Start); Assert.AreEqual (14, range.Ranges[3].End); } [Test] public void RemoveMids () { RangeCollection range = _SetupTestRemoveMerges (); Assert.AreEqual (5, range.RangeCount); Assert.AreEqual (14, range.Ranges[3].Start); Assert.AreEqual (15, range.Ranges[3].End); Assert.AreEqual (true, range.Contains (9)); range.Remove (9); Assert.AreEqual (false, range.Contains (9)); Assert.AreEqual (6, range.RangeCount); Assert.AreEqual (7, range.Ranges[2].Start); Assert.AreEqual (8, range.Ranges[2].End); Assert.AreEqual (10, range.Ranges[3].Start); Assert.AreEqual (11, range.Ranges[3].End); Assert.AreEqual (14, range.Ranges[4].Start); Assert.AreEqual (15, range.Ranges[4].End); } private static RangeCollection _SetupTestRemoveMerges () { RangeCollection range = new RangeCollection (); int [] indexes = new int [] { 0, 2, 3, 4, 5, 7, 8, 9, 10, 11, 14, 15, 17, 18, 19 }; foreach (int index in indexes) { range.Add (index); } int i = 0; foreach (RangeCollection.Range r in range.Ranges) { switch (i++) { case 0: Assert.AreEqual (0, r.Start); Assert.AreEqual (0, r.End); break; case 1: Assert.AreEqual (2, r.Start); Assert.AreEqual (5, r.End); break; case 2: Assert.AreEqual (7, r.Start); Assert.AreEqual (11, r.End); break; case 3: Assert.AreEqual (14, r.Start); Assert.AreEqual (15, r.End); break; case 4: Assert.AreEqual (17, r.Start); Assert.AreEqual (19, r.End); break; default: Assert.Fail ("Should never reach here"); break; } } return range; } #pragma warning disable 0618 [Test] public void IndexesCacheGeneration () { RangeCollection range = new RangeCollection (); int [] index_cache = range.Indexes; Assert.AreSame (index_cache, range.Indexes); range.Add (0); range.Add (5); if (index_cache == range.Indexes) { Assert.Fail ("Indexes Cache not regenerated after change"); } index_cache = range.Indexes; range.Remove (0); range.Add (3); if (index_cache == range.Indexes) { Assert.Fail ("Indexes Cache not regenerated after change"); } } #pragma warning restore 0618 [Test] public void IndexOf () { RangeCollection range = new RangeCollection (); range.Add (0); range.Add (2); range.Add (3); range.Add (5); range.Add (6); range.Add (7); range.Add (8); range.Add (11); range.Add (12); range.Add (13); Assert.AreEqual (0, range.IndexOf (0)); Assert.AreEqual (1, range.IndexOf (2)); Assert.AreEqual (2, range.IndexOf (3)); Assert.AreEqual (3, range.IndexOf (5)); Assert.AreEqual (4, range.IndexOf (6)); Assert.AreEqual (5, range.IndexOf (7)); Assert.AreEqual (6, range.IndexOf (8)); Assert.AreEqual (7, range.IndexOf (11)); Assert.AreEqual (8, range.IndexOf (12)); Assert.AreEqual (9, range.IndexOf (13)); Assert.AreEqual (-1, range.IndexOf (99)); } [Test] public void IndexerForGoodIndexes () { RangeCollection range = new RangeCollection (); /* Range Idx Value 0-2 0 -> 0 1 -> 1 2 -> 2 7-9 3 -> 7 4 -> 8 5 -> 9 11-13 6 -> 11 7 -> 12 8 -> 13 */ range.Add (0); range.Add (1); range.Add (2); range.Add (7); range.Add (8); range.Add (9); range.Add (11); range.Add (12); range.Add (13); Assert.AreEqual (0, range[0]); Assert.AreEqual (1, range[1]); Assert.AreEqual (2, range[2]); Assert.AreEqual (7, range[3]); Assert.AreEqual (8, range[4]); Assert.AreEqual (9, range[5]); Assert.AreEqual (11, range[6]); Assert.AreEqual (12, range[7]); Assert.AreEqual (13, range[8]); } [Test] public void StressForGoodIndexes () { Random random = new Random (0xbeef); RangeCollection ranges = new RangeCollection (); List indexes = new List (); for (int i = 0, n = 75000; i < n; i++) { int value = random.Next (n); if (ranges.Add (value)) { CollectionExtensions.SortedInsert (indexes, value); } } Assert.AreEqual (indexes.Count, ranges.Count); for (int i = 0; i < indexes.Count; i++) { Assert.AreEqual (indexes[i], ranges[i]); } } [Test] [ExpectedException (typeof (IndexOutOfRangeException))] public void IndexerForNegativeBadIndex () { RangeCollection range = new RangeCollection (); Assert.AreEqual (0, range[1]); } [Test] [ExpectedException (typeof (IndexOutOfRangeException))] public void IndexerForZeroBadIndex () { RangeCollection range = new RangeCollection (); Assert.AreEqual (0, range[0]); } [Test] [ExpectedException (typeof (IndexOutOfRangeException))] public void IndexerForPositiveBadIndex () { RangeCollection range = new RangeCollection (); range.Add (1); Assert.AreEqual (0, range[1]); } [Test] public void ExplicitInterface () { ICollection range = new RangeCollection (); range.Add (1); range.Add (2); range.Add (5); range.Add (6); Assert.AreEqual (4, range.Count); } [Test] public void NegativeIndices () { RangeCollection c = new RangeCollection (); c.Add (-10); c.Add (-5); c.Add (5); c.Add (-8); c.Add (10); c.Add (-9); c.Add (-11); Assert.IsTrue (c.Contains(-10), "#1"); Assert.IsTrue (c.Contains(-5), "#2"); Assert.IsTrue (c.Contains(5), "#3"); Assert.IsTrue (c.Contains(-8), "#4"); Assert.AreEqual (4, c.RangeCount, "#5"); Assert.AreEqual (new RangeCollection.Range (-11, -8), c.Ranges[0], "#6"); Assert.AreEqual (new RangeCollection.Range (-5, -5), c.Ranges[1], "#7"); Assert.AreEqual (new RangeCollection.Range (5, 5), c.Ranges[2], "#8"); Assert.AreEqual (new RangeCollection.Range (10, 10), c.Ranges[3], "#9"); Assert.AreEqual (0, c.FindRangeIndexForValue (-9), "#10"); Assert.IsTrue (c.FindRangeIndexForValue (-7) < 0, "#11"); } [Test] public void IPAddressRanges () { RangeCollection ranges = new RangeCollection (); int start = GetAddress ("127.0.0.1"); int end = GetAddress ("127.0.0.50"); for (int i = start; i <= end; i++) { ranges.Add (i); } Assert.IsTrue (ranges.Contains (GetAddress ("127.0.0.15"))); Assert.IsFalse (ranges.Contains (GetAddress ("127.0.0.0"))); Assert.IsFalse (ranges.Contains (GetAddress ("127.0.0.51"))); } private static int GetAddress (string addressStr) { System.Net.IPAddress address = System.Net.IPAddress.Parse (addressStr); return (int)(System.Net.IPAddress.NetworkToHostOrder ( BitConverter.ToInt32 (address.GetAddressBytes (), 0)) >> 32); } } } #endif hyena-0.5/Hyena/Hyena.Collections/Tests/QueuePipelineTests.cs0000644000175000001440000000512011377105342024413 0ustar00gabeusers00000000000000// // ElementQueueProcessor.cs // // Author: // Aaron Bockover // // Copyright (C) 2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // #if ENABLE_TESTS using System; using System.Threading; using System.Collections.Generic; using NUnit.Framework; using Hyena.Collections; namespace Hyena.Collections.Tests { [TestFixture] public class QueuePipelineTests { private class FakeElement : QueuePipelineElement { protected override object ProcessItem (object item) { return null; } } [Test] public void BuildPipeline () { BuildPipeline (1); BuildPipeline (2); BuildPipeline (3); BuildPipeline (10); BuildPipeline (1000); } private void BuildPipeline (int count) { List elements = new List (); for (int i = 0; i < count; i++) { elements.Add (new FakeElement ()); } QueuePipeline qp = new QueuePipeline (); foreach (FakeElement s in elements) { qp.AddElement (s); } Assert.AreEqual (elements[0], qp.FirstElement); int index = 0; FakeElement element = (FakeElement)qp.FirstElement; while (element != null) { Assert.AreEqual (elements[index++], element); element = (FakeElement)element.NextElement; } } } } #endif hyena-0.5/Hyena/Hyena.Collections/RangeCollection.cs0000644000175000001440000002615511377105342022577 0ustar00gabeusers00000000000000// // RangeCollection.cs // // Author: // Aaron Bockover // // Copyright (C) 2007-2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Collections; #if NET_2_0 using System.Collections.Generic; #endif #if NET_1_1 namespace System.Collections #else namespace Hyena.Collections #endif { #if NET_1_1 internal #else public #endif class RangeCollection : ICloneable, #if NET_2_0 ICollection #else ICollection #endif { public struct Range { private int start; private int end; public Range (int start, int end) { this.start = start; this.end = end; } public override string ToString () { return String.Format ("{0}-{1} ({2})", Start, End, Count); } public int Start { get { return start; } set { start = value; } } public int End { get { return end; } set { end = value; } } public int Count { get { return End - Start + 1; } } } private const int MIN_CAPACITY = 16; private Range [] ranges; private int range_count; private int index_count; private int generation; private int [] indexes_cache; private int indexes_cache_generation; public RangeCollection () { Clear (); } #region Private Array Logic private void Shift (int start, int delta) { if (delta < 0) { start -= delta; } if (start < range_count) { Array.Copy (ranges, start, ranges, start + delta, range_count - start); } range_count += delta; } private void EnsureCapacity (int growBy) { int new_capacity = ranges.Length == 0 ? 1 : ranges.Length; int min_capacity = ranges.Length == 0 ? MIN_CAPACITY : ranges.Length + growBy; while (new_capacity < min_capacity) { new_capacity <<= 1; } #if NET_2_0 Array.Resize (ref ranges, new_capacity); #else Range [] new_ranges = new Range[new_capacity]; Array.Copy (ranges, 0, new_ranges, 0, ranges.Length); ranges = new_ranges; #endif } private void Insert (int position, Range range) { if (range_count == ranges.Length) { EnsureCapacity (1); } Shift (position, 1); ranges[position] = range; } private void RemoveAt (int position) { Shift (position, -1); Array.Clear (ranges, range_count, 1); } #endregion #region Private Range Logic private bool RemoveIndexFromRange (int index) { int range_index = FindRangeIndexForValue (index); if (range_index < 0) { return false; } Range range = ranges[range_index]; if (range.Start == index && range.End == index) { RemoveAt (range_index); } else if (range.Start == index) { ranges[range_index].Start++; } else if (range.End == index) { ranges[range_index].End--; } else { Range split_range = new Range (index + 1, range.End); ranges[range_index].End = index - 1; Insert (range_index + 1, split_range); } index_count--; return true; } private void InsertRange (Range range) { int position = FindInsertionPosition (range); bool merged_left = MergeLeft (range, position); bool merged_right = MergeRight (range, position); if (!merged_left && !merged_right) { Insert (position, range); } else if (merged_left && merged_right) { ranges[position - 1].End = ranges[position].End; RemoveAt (position); } } private bool MergeLeft (Range range, int position) { int left = position - 1; if (left >= 0 && ranges[left].End + 1 == range.Start) { ranges[left].End = range.Start; return true; } return false; } private bool MergeRight (Range range, int position) { if (position < range_count && ranges[position].Start - 1 == range.End) { ranges[position].Start = range.End; return true; } return false; } private static int CompareRanges (Range a, Range b) { return (a.Start + (a.End - a.Start)).CompareTo (b.Start + (b.End - b.Start)); } private int FindInsertionPosition (Range range) { int min = 0; int max = range_count - 1; while (min <= max) { int mid = min + ((max - min) / 2); int cmp = CompareRanges (ranges[mid], range); if (cmp == 0) { return mid; } else if (cmp > 0) { if (mid > 0 && CompareRanges (ranges[mid - 1], range) < 0) { return mid; } max = mid - 1; } else { min = mid + 1; } } return min; } public int FindRangeIndexForValue (int value) { int min = 0; int max = range_count - 1; while (min <= max) { int mid = min + ((max - min) / 2); Range range = ranges[mid]; if (value >= range.Start && value <= range.End) { return mid; // In Range } else if (value < range.Start) { max = mid - 1; // Below Range } else { min = mid + 1; // Above Range } } return ~min; } #endregion #region Public RangeCollection API public Range [] Ranges { get { Range [] ranges_copy = new Range[range_count]; Array.Copy (ranges, ranges_copy, range_count); return ranges_copy; } } public int RangeCount { get { return range_count; } } #if NET_2_0 [Obsolete ("Do not use the Indexes property in 2.0 profiles if enumerating only; Indexes allocates an array to avoid boxing in the 1.1 profile")] #endif public int [] Indexes { get { if (indexes_cache != null && generation == indexes_cache_generation) { return indexes_cache; } indexes_cache = new int[Count]; indexes_cache_generation = generation; for (int i = 0, j = 0; i < range_count; i++) { for (int k = ranges[i].Start; k <= ranges[i].End; j++, k++) { indexes_cache[j] = k; } } return indexes_cache; } } public int IndexOf (int value) { int offset = 0; foreach (Range range in ranges) { if (value >= range.Start && value <= range.End) { return offset + (value - range.Start); } offset += range.End - range.Start + 1; } return -1; } public int this[int index] { get { for (int i = 0, cuml_count = 0; i < range_count && index >= 0; i++) { if (index < (cuml_count += ranges[i].Count)) { return ranges[i].End - (cuml_count - index) + 1; } } throw new IndexOutOfRangeException (index.ToString ()); } } #endregion #region ICollection Implementation public bool Add (int value) { if (!Contains (value)) { generation++; InsertRange (new Range (value, value)); index_count++; return true; } return false; } void #if NET_2_0 ICollection. #else ICollection. #endif Add (int value) { Add (value); } public bool Remove (int value) { generation++; return RemoveIndexFromRange (value); } public void Clear () { range_count = 0; index_count = 0; generation++; ranges = new Range[MIN_CAPACITY]; } public bool Contains (int value) { return FindRangeIndexForValue (value) >= 0; } public void CopyTo (int [] array, int index) { throw new NotImplementedException (); } public void CopyTo (Array array, int index) { throw new NotImplementedException (); } public int Count { get { return index_count; } } public bool IsReadOnly { get { return false; } } #if !NET_2_0 public bool IsSynchronized { get { return false; } } public object SyncRoot { get { return this; } } #endif #endregion #region ICloneable Implementation public object Clone () { return MemberwiseClone (); } #endregion #region IEnumerable Implementation #if NET_2_0 public IEnumerator GetEnumerator () { for (int i = 0; i < range_count; i++) { for (int j = ranges[i].Start; j <= ranges[i].End; j++) { yield return j; } } } IEnumerator IEnumerable.GetEnumerator () { return GetEnumerator (); } #else public IEnumerator GetEnumerator () { return Indexes.GetEnumerator (); } #endif #endregion } } hyena-0.5/Hyena/Hyena.Collections/LruCache.cs0000644000175000001440000001440311377105342021206 0ustar00gabeusers00000000000000// // LruCache.cs // // Author: // Aaron Bockover // // Copyright (C) 2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Collections; using System.Collections.Generic; namespace Hyena.Collections { public struct CacheEntry { private TKey key; public TKey Key { get { return key; } set { key = value; } } private TValue value; public TValue Value { get { return this.value; } set { this.value = value; } } internal DateTime LastUsed; internal int UsedCount; } public class LruCache : IEnumerable> { private Dictionary> cache; private int max_count; private long hits; private long misses; private double? minimum_hit_ratio; public LruCache () : this (1024) { } public LruCache (int maxCount) : this (maxCount, null) { } public LruCache (int maxCount, double? minimumHitRatio) { max_count = maxCount; minimum_hit_ratio = minimumHitRatio; cache = new Dictionary> (); } public void Add (TKey key, TValue value) { lock (cache) { CacheEntry entry; if (cache.TryGetValue (key, out entry)) { Ref (ref entry); cache[key] = entry; return; } entry.Key = key; entry.Value = value; Ref (ref entry); cache.Add (key, entry); misses++; EnsureMinimumHitRatio (); if (Count > max_count) { TKey expire = FindOldestEntry (); ExpireItem (cache[expire].Value); cache.Remove (expire); } } } public bool Contains (TKey key) { lock (cache) { return cache.ContainsKey (key); } } public void Remove (TKey key) { lock (cache) { if (Contains (key)) { ExpireItem (cache[key].Value); cache.Remove (key); } } } public bool TryGetValue (TKey key, out TValue value) { lock (cache) { CacheEntry entry; if (cache.TryGetValue (key, out entry)) { value = entry.Value; Ref (ref entry); cache[key] = entry; hits++; return true; } misses++; EnsureMinimumHitRatio (); value = default (TValue); return false; } } private void EnsureMinimumHitRatio () { if (minimum_hit_ratio != null && Count > MaxCount && HitRatio < minimum_hit_ratio) { MaxCount = Count; } } private void Ref (ref CacheEntry entry) { entry.LastUsed = DateTime.Now; entry.UsedCount++; } IEnumerator IEnumerable.GetEnumerator () { return GetEnumerator (); } public IEnumerator> GetEnumerator () { lock (cache) { foreach (KeyValuePair> item in cache) { yield return item.Value; } } } // Ok, this blows. I have no time to implement anything clever or proper here. // Using a hashtable generally sucks for this, but it's not bad for a 15 minute // hack. max_count will be sufficiently small in our case that this can't be // felt anyway. Meh. private TKey FindOldestEntry () { lock (cache) { DateTime oldest = DateTime.Now; TKey oldest_key = default (TKey); foreach (CacheEntry item in this) { if (item.LastUsed < oldest) { oldest = item.LastUsed; oldest_key = item.Key; } } return oldest_key; } } protected virtual void ExpireItem (TValue item) { } public int MaxCount { get { lock (cache) { return max_count; } } set { lock (cache) { max_count = value; } } } public int Count { get { lock (cache) { return cache.Count; } } } public double? MinimumHitRatio { get { return minimum_hit_ratio; } } public long Hits { get { return hits; } } public long Misses { get { return misses; } } public double HitRatio { get { if (misses == 0) { return 1.0; } else { return ((double)hits) / ((double)(hits + misses)); } } } } } hyena-0.5/Hyena/Hyena.Collections/CollectionExtensions.cs0000644000175000001440000000553311377105342023677 0ustar00gabeusers00000000000000// // CollectionExtensions.cs // // Author: // Aaron Bockover // // Copyright (C) 2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Text; using System.Collections.Generic; namespace Hyena.Collections { public static class CollectionExtensions { public static void SortedInsert (List list, T value) where T : IComparable { if (list.Count == 0 || list[list.Count - 1].CompareTo (value) < 0) { list.Add (value); } else if (list[0].CompareTo (value) > 0) { list.Insert (0, value); } else { int index = list.BinarySearch (value); list.Insert (index < 0 ? ~index : index, value); } } public static string Join (IList list) { return Join (list, ", "); } public static string Join (IList list, string separator) { return Join (list, null, null, separator); } public static string Join (IList list, string wrapper, string separator) { return Join (list, wrapper, wrapper, separator); } public static string Join (IList list, string front, string back, string separator) { StringBuilder builder = new StringBuilder (); for (int i = 0, n = list.Count; i < n; i++) { if (front != null) { builder.Append (front); } builder.Append (list[i]); if (back != null) { builder.Append (back); } if (i < n - 1) { builder.Append (separator); } } return builder.ToString (); } } } hyena-0.5/Hyena/Hyena.Collections/IntervalHeap.cs0000644000175000001440000002455011377105342022106 0ustar00gabeusers00000000000000// // IntervalHeap.cs // // Author: // Aaron Bockover // // Copyright (C) 2006-2007 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Collections; using System.Collections.Generic; namespace Hyena.Collections { public class IntervalHeap : ICollection, ICollection { private const int MIN_CAPACITY = 16; private int count; private int generation; private Interval [] heap; public IntervalHeap () { Clear (); } public virtual T Pop () { if (count == 0) { throw new InvalidOperationException (); } T item = heap[0].Item; MoveDown (0, heap[--count]); generation++; return item; } public virtual T Peek () { if (count == 0) { throw new InvalidOperationException (); } return heap[0].Item; } public virtual void Push (T item, int priority) { if (item == null) { throw new ArgumentNullException ("item"); } if (count == heap.Length) { OptimalArrayResize (ref heap, 1); } MoveUp (++count - 1, new Interval (item, priority)); generation++; } public virtual void Clear () { generation = 0; count = 0; heap = new Interval[MIN_CAPACITY]; } void ICollection.CopyTo (Array array, int index) { if (array == null) { throw new ArgumentNullException ("array"); } if (index < 0) { throw new ArgumentOutOfRangeException ("index"); } Array.Copy (heap, 0, array, index, count); } public virtual void CopyTo (T [] array, int index) { if (array == null) { throw new ArgumentNullException ("array"); } if (index < 0) { throw new ArgumentOutOfRangeException ("index"); } Array.Copy (heap, 0, array, index, count); } public virtual bool Contains (T item) { if (item == null) { throw new ArgumentNullException ("item"); } return FindItemHeapIndex (item) >= 0; } public virtual void Add (T item) { if (item == null) { throw new ArgumentNullException ("item"); } Push (item, 0); } public virtual bool Remove (T item) { if (item == null) { throw new ArgumentNullException ("item"); } int index = FindItemHeapIndex (item); if (index < 0) { return false; } MoveDown (index, heap[--count]); generation++; return true; } public virtual void TrimExcess () { if (count < heap.Length * 0.9) { Array.Resize (ref heap, count); } } IEnumerator IEnumerable.GetEnumerator () { return GetEnumerator (); } public virtual IEnumerator GetEnumerator () { return new IntervalHeapEnumerator (this); } public static IntervalHeap Synchronized (IntervalHeap heap) { if (heap == null) { throw new ArgumentNullException ("heap"); } return new SyncIntervalHeap (heap); } private int FindItemHeapIndex (T item) { for (int i = 0; i < count; i++) { if (item.Equals (heap[i].Item)) { return i; } } return -1; } private int GetLeftChildIndex (int index) { return index * 2 + 1; } private int GetParentIndex (int index) { return (index - 1) / 2; } private static void OptimalArrayResize (ref Interval [] array, int grow) { int new_capacity = array.Length == 0 ? 1 : array.Length; int min_capacity = array.Length == 0 ? MIN_CAPACITY : array.Length + grow; while (new_capacity < min_capacity) { new_capacity <<= 1; } Array.Resize (ref array, new_capacity); } private void MoveUp (int index, Interval node) { int parent_index = GetParentIndex (index); while (index > 0 && heap[parent_index].Priority < node.Priority) { heap[index] = heap[parent_index]; index = parent_index; parent_index = GetParentIndex (index); } heap[index] = node; } private void MoveDown (int index, Interval node) { int child_index = GetLeftChildIndex (index); while (child_index < count) { if (child_index + 1 < count && heap[child_index].Priority < heap[child_index + 1].Priority) { child_index++; } heap[index] = heap[child_index]; index = child_index; child_index = GetLeftChildIndex (index); } MoveUp (index, node); } public virtual int Count { get { return count; } } public bool IsReadOnly { get { return false; } } public virtual object SyncRoot { get { return this; } } public virtual bool IsSynchronized { get { return false; } } private struct Interval { private T item; private int priority; public Interval (T item, int priority) { this.item = item; this.priority = priority; } public T Item { get { return item; } } public int Priority { get { return priority; } } } private class SyncIntervalHeap : IntervalHeap { private IntervalHeap heap; internal SyncIntervalHeap (IntervalHeap heap) { this.heap = heap; } public override int Count { get { lock (heap) { return heap.Count; } } } public override bool IsSynchronized { get { return true; } } public override object SyncRoot { get { return heap.SyncRoot; } } public override void Clear () { lock (heap) { heap.Clear (); } } public override bool Contains(T item) { lock (heap) { return heap.Contains (item); } } public override T Pop() { lock (heap) { return heap.Pop (); } } public override T Peek () { lock (heap) { return heap.Peek (); } } public override void Push (T item, int priority) { lock (heap) { heap.Push (item, priority); } } public override void Add (T item) { lock (heap) { heap.Add (item); } } public override bool Remove (T item) { lock (heap) { return heap.Remove (item); } } public override void TrimExcess () { lock (heap) { heap.TrimExcess (); } } public override void CopyTo (T [] array, int index) { lock (heap) { heap.CopyTo (array, index); } } public override IEnumerator GetEnumerator () { lock (heap) { return new IntervalHeapEnumerator (this); } } } private class IntervalHeapEnumerator : IEnumerator, IEnumerator { private IntervalHeap heap; private int index; private int generation; public IntervalHeapEnumerator (IntervalHeap heap) { this.heap = heap; Reset (); } public void Reset () { generation = heap.generation; index = -1; } public void Dispose () { heap = null; } public bool MoveNext () { if (generation != heap.generation) { throw new InvalidOperationException (); } if (index + 1 == heap.count) { return false; } index++; return true; } object IEnumerator.Current { get { return Current; } } public T Current { get { if (generation != heap.generation) { throw new InvalidOperationException (); } return heap.heap[index].Item; } } } } } hyena-0.5/Hyena/Hyena.Collections/SelectionProxy.cs0000644000175000001440000000573711377105342022521 0ustar00gabeusers00000000000000// // SelectionProxy.cs // // Author: // Gabriel Burt // // Copyright (C) 2007 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; namespace Hyena.Collections { public class SelectionProxy { private Selection selection; public event EventHandler Changed; public event EventHandler SelectionChanged; public event EventHandler FocusChanged; public Selection Selection { get { return selection; } set { if (selection == value) return; if (selection != null) { selection.Changed -= HandleSelectionChanged; selection.FocusChanged -= HandleSelectionFocusChanged; } selection = value; if (selection != null) { selection.Changed += HandleSelectionChanged; selection.FocusChanged += HandleSelectionFocusChanged; } OnSelectionChanged (); } } protected virtual void OnChanged () { EventHandler handler = Changed; if (handler != null) { handler (selection, EventArgs.Empty); } } protected virtual void OnFocusChanged () { EventHandler handler = FocusChanged; if (handler != null) { handler (selection, EventArgs.Empty); } } protected virtual void OnSelectionChanged () { EventHandler handler = SelectionChanged; if (handler != null) { handler (selection, EventArgs.Empty); } } private void HandleSelectionChanged (object o, EventArgs args) { OnChanged (); } private void HandleSelectionFocusChanged (object o, EventArgs args) { OnFocusChanged (); } } } hyena-0.5/Hyena/Hyena.Collections/Selection.cs0000644000175000001440000001421311377105342021444 0ustar00gabeusers00000000000000// // Selection.cs // // Author: // Aaron Bockover // Gabriel Burt // // Copyright (C) 2007 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Collections; #if NET_2_0 using System.Collections.Generic; #endif namespace Hyena.Collections { #if NET_1_1 internal #else public #endif class Selection : #if NET_2_0 IEnumerable #else IEnumerable #endif { RangeCollection ranges = new RangeCollection (); private int max_index; private int first_selected_index; public event EventHandler Changed; public event EventHandler FocusChanged; private int focused_index = -1; public Selection () { } public int FocusedIndex { get { return focused_index; } set { focused_index = value; var handler = FocusChanged; if (handler != null) { handler (this, EventArgs.Empty); } } } protected virtual void OnChanged () { EventHandler handler = Changed; if (handler != null) { handler (this, EventArgs.Empty); } } public void ToggleSelect (int index) { if (!ranges.Remove (index)) { ranges.Add (index); } OnChanged (); } public void Select (int index) { ranges.Add (index); if (Count == 1) first_selected_index = index; OnChanged (); } public void QuietSelect (int index) { ranges.Add (index); if (Count == 1) first_selected_index = index; } public void Unselect (int index) { if (ranges.Remove (index)) OnChanged (); } public void QuietUnselect (int index) { ranges.Remove (index); } public bool Contains(int index) { return ranges.Contains (index); } public void SelectFromFirst (int end, bool clear) { bool contains = Contains (first_selected_index); if (clear) Clear(false); if (contains) SelectRange (first_selected_index, end); else Select (end); } public void SelectRange (int a, int b) { int start = Math.Min (a, b); int end = Math.Max (a, b); int i; for (i = start; i <= end; i++) { ranges.Add (i); } if (Count == i) first_selected_index = a; OnChanged (); } public void UnselectRange (int a, int b) { int start = Math.Min (a, b); int end = Math.Max (a, b); int i; for (i = start; i <= end; i++) { ranges.Remove (i); } OnChanged (); } public virtual void SelectAll () { SelectRange (0, max_index); } public void Clear () { Clear (true); } public void Clear (bool raise) { if (ranges.Count <= 0) { return; } ranges.Clear (); if (raise) OnChanged (); } public int Count { get { return ranges.Count; } } public int MaxIndex { set { max_index = value; } get { return max_index; } } public virtual bool AllSelected { get { if (ranges.RangeCount == 1) { RangeCollection.Range range = ranges.Ranges[0]; return range.Start == 0 && range.End == max_index; } return false; } } public RangeCollection RangeCollection { get { return ranges; } } public RangeCollection.Range [] Ranges { get { return ranges.Ranges; } } public int FirstIndex { get { return Count > 0 ? ranges[0] : -1; } } public int LastIndex { get { return Count > 0 ? ranges[Count - 1]: -1; } } #if NET_2_0 public IEnumerator GetEnumerator () { return ranges.GetEnumerator (); } IEnumerator IEnumerable.GetEnumerator () { return GetEnumerator (); } #else public IEnumerator GetEnumerator () { return ranges.GetEnumerator (); } #endif public override string ToString () { System.Text.StringBuilder sb = new System.Text.StringBuilder (); sb.AppendFormat (""); return sb.ToString (); } } } hyena-0.5/Hyena/Hyena.Collections/WriteLineElement.cs0000644000175000001440000000303011377105342022726 0ustar00gabeusers00000000000000// // WriteLineElement.cs // // Author: // Aaron Bockover // // Copyright (C) 2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; namespace Hyena.Collections { public class WriteLineElement : QueuePipelineElement where T : class { public WriteLineElement () { Threaded = false; } protected override T ProcessItem (T item) { Console.WriteLine (item); return null; } } } hyena-0.5/Hyena/Hyena.Collections/QueuePipeline.cs0000644000175000001440000000714611377105342022300 0ustar00gabeusers00000000000000// // QueuePipeline.cs // // Author: // Aaron Bockover // // Copyright (C) 2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; namespace Hyena.Collections { public class QueuePipeline where T : class { #pragma warning disable 0067 // FIXME: This is to mute gmcs: https://bugzilla.novell.com/show_bug.cgi?id=360455 public event EventHandler Finished; #pragma warning restore 0067 private object sync = new object (); private QueuePipelineElement first_element; internal QueuePipelineElement FirstElement { get { return first_element; } } public QueuePipeline () { } public void AddElement (QueuePipelineElement element) { element.Finished += OnElementFinished; lock (sync) { if (first_element == null) { first_element = element; return; } QueuePipelineElement current = first_element; while (current != null) { if (current.NextElement == null) { current.NextElement = element; break; } current = current.NextElement; } } } public virtual void Enqueue (T item) { if (first_element == null) { throw new InvalidOperationException ("There are no elements in this pipeline"); } first_element.Enqueue (item); } public virtual void Cancel () { if (first_element != null) { first_element.Cancel (); } } private void OnElementFinished (object o, EventArgs args) { bool any_processing = false; lock (sync) { QueuePipelineElement element = FirstElement; while (element != null) { any_processing |= element.Processing || element.ProcessedCount < element.TotalCount; if (any_processing) { break; } element = element.NextElement; } } if (!any_processing) { OnFinished (); } } protected virtual void OnFinished () { EventHandler handler = Finished; if (handler != null) { handler (this, EventArgs.Empty); } } } } hyena-0.5/Hyena/Hyena.Collections/IStackProvider.cs0000644000175000001440000000260311377105342022410 0ustar00gabeusers00000000000000// // IStackProvider.cs // // Author: // Aaron Bockover // // Copyright (C) 2007 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; namespace Hyena.Collections { public interface IStackProvider { T Peek (); T Pop (); void Push (T t); void Clear (); int Count { get; } } } hyena-0.5/Hyena/Hyena.Collections/QueuePipelineElement.cs0000644000175000001440000001425211377105342023606 0ustar00gabeusers00000000000000// // QueuePipelineElement.cs // // Author: // Aaron Bockover // // Copyright (C) 2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Threading; using System.Collections.Generic; namespace Hyena.Collections { internal class ElementProcessCanceledException : ApplicationException { } public abstract class QueuePipelineElement where T : class { #pragma warning disable 0067 // FIXME: This is to mute gmcs: https://bugzilla.novell.com/show_bug.cgi?id=360455 public event EventHandler Finished; public event EventHandler ProcessedItem; #pragma warning restore 0067 private Queue queue = new Queue (); private object monitor = new object (); private AutoResetEvent thread_wait; private bool processing = false; private bool threaded = true; private bool canceled = false; private int processed_count; public int ProcessedCount { get { return processed_count; } } private int total_count; public int TotalCount { get { return total_count; } } protected abstract T ProcessItem (T item); protected virtual void OnFinished () { lock (this) { canceled = false; } lock (queue) { total_count = 0; processed_count = 0; } EventHandler handler = Finished; if (handler != null) { handler (this, EventArgs.Empty); } } protected void OnProcessedItem () { EventHandler handler = ProcessedItem; if (handler != null) { handler (this, EventArgs.Empty); } } protected virtual void OnCanceled () { lock (queue) { queue.Clear (); total_count = 0; processed_count = 0; } } public virtual void Enqueue (T item) { lock (this) { lock (queue) { queue.Enqueue (item); total_count++; } if (!threaded) { Processor (null); return; } if (thread_wait == null) { thread_wait = new AutoResetEvent (false); } if (Monitor.TryEnter (monitor)) { Monitor.Exit (monitor); ThreadPool.QueueUserWorkItem (Processor); thread_wait.WaitOne (); } } } protected virtual void EnqueueDownstream (T item) { if (NextElement != null && item != null) { NextElement.Enqueue (item); } } private void Processor (object state) { lock (monitor) { if (threaded) { thread_wait.Set (); } lock (this) { processing = true; } try { while (queue.Count > 0) { CheckForCanceled (); T item = null; lock (queue) { item = queue.Dequeue (); processed_count++; } EnqueueDownstream (ProcessItem (item)); OnProcessedItem (); } } catch (ElementProcessCanceledException) { OnCanceled (); } lock (this) { processing = false; } if (threaded) { thread_wait.Close (); thread_wait = null; } OnFinished (); } } protected virtual void CheckForCanceled () { lock (this) { if (canceled) { throw new ElementProcessCanceledException (); } } } public void Cancel () { lock (this) { if (processing) { canceled = true; } if (NextElement != null) { NextElement.Cancel (); } } } public bool Processing { get { lock (this) { return processing; } } } public bool Threaded { get { return threaded; } set { if (processing) { throw new InvalidOperationException ("Cannot change threading model while the element is processing"); } threaded = value; } } protected Queue Queue { get { return queue; } } private QueuePipelineElement next_element; internal QueuePipelineElement NextElement { get { return next_element; } set { next_element = value; } } } } hyena-0.5/Hyena/Hyena.Data/0000777000175000001440000000000011453151001015552 5ustar00gabeusers00000000000000hyena-0.5/Hyena/Hyena.Data/ISortable.cs0000644000175000001440000000251011377105342017773 0ustar00gabeusers00000000000000// // ISortable.cs // // Author: // Aaron Bockover // // Copyright (C) 2007 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // namespace Hyena.Data { public interface ISortable { bool Sort (ISortableColumn column); ISortableColumn SortColumn { get; } } } hyena-0.5/Hyena/Hyena.Data/ISortableColumn.cs0000644000175000001440000000261511377105342021157 0ustar00gabeusers00000000000000// // ISortableColumn.cs // // Author: // Aaron Bockover // // Copyright (C) 2007 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // namespace Hyena.Data { public interface ISortableColumn { string SortKey { get; } SortType SortType { get; set; } Hyena.Query.QueryField Field { get; } string Id { get; } } } hyena-0.5/Hyena/Hyena.Data/ArrayModelCache.cs0000644000175000001440000000446611430346046021104 0ustar00gabeusers00000000000000// // ArrayModelCache.cs // // Author: // Gabriel Burt // // Copyright (C) 2007 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; namespace Hyena.Data { public abstract class ArrayModelCache : ModelCache where T : ICacheableItem, new () { protected T [] cache; protected long offset = -1; protected long limit = 0; public ArrayModelCache (ICacheableModel model) : base (model) { cache = new T [Model.FetchCount]; } public override bool ContainsKey (long i) { return (i >= offset && i <= (offset + limit)); } public override void Add (long i, T item) { if (cache.Length != Model.FetchCount) { cache = new T [Model.FetchCount]; Clear (); } if (offset == -1 || i < offset || i >= (offset + cache.Length)) { offset = i; limit = 0; } cache [i - offset] = item; limit++; } public override T this [long i] { get { return cache [i - offset]; } } public override void Clear () { offset = -1; limit = 0; } } } hyena-0.5/Hyena/Hyena.Data/ICareAboutView.cs0000644000175000001440000000243211377105342020723 0ustar00gabeusers00000000000000// // ICareAboutView.cs // // Author: // Aaron Bockover // // Copyright (C) 2007 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // namespace Hyena.Data { public interface ICareAboutView { int RowsInView { set; } } } hyena-0.5/Hyena/Hyena.Data/ColumnDescription.cs0000644000175000001440000000672511377105342021564 0ustar00gabeusers00000000000000// // ColumnDescription.cs // // Author: // Aaron Bockover // // Copyright (C) 2007 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; namespace Hyena.Data { public class ColumnDescription { private string title; private string long_title; private double width; private bool visible; private string property; private bool initialized; public event EventHandler VisibilityChanged; public event EventHandler WidthChanged; public ColumnDescription (string property, string title, double width) : this (property, title, width, true) { } public ColumnDescription (string property, string title, double width, bool visible) { this.property = property; this.title = title; this.long_title = title; Width = width; Visible = visible; initialized = true; } protected virtual void OnVisibilityChanged () { EventHandler handler = VisibilityChanged; if (handler != null) { handler (this, EventArgs.Empty); } } protected virtual void OnWidthChanged () { EventHandler handler = WidthChanged; if (handler != null) { handler (this, EventArgs.Empty); } } public string Title { get { return title; } set { title = value; } } public string LongTitle { get { return long_title; } set { long_title = value; } } public double Width { get { return width; } set { if (Double.IsNaN (value)) { return; } double old = width; width = value; if (initialized && value != old) { OnWidthChanged (); } } } public int OrderHint { get; set; } public string Property { get { return property; } set { property = value; } } public bool Visible { get { return visible; } set { bool old = Visible; visible = value; if(initialized && value != old) { OnVisibilityChanged (); } } } } } hyena-0.5/Hyena/Hyena.Data/ICacheableItem.cs0000644000175000001440000000253111377105342020671 0ustar00gabeusers00000000000000// // ICacheableItem.cs // // Author: // Gabriel Burt // // Copyright (C) 2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using Hyena.Data; namespace Hyena.Data { public interface ICacheableItem { object CacheEntryId { get; set; } long CacheModelId { get; set; } } } hyena-0.5/Hyena/Hyena.Data/ModelCache.cs0000644000175000001440000000443411430346046020100 0ustar00gabeusers00000000000000// // ModelCache.cs // // Author: // Gabriel Burt // // Copyright (C) 2007 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Collections.Generic; namespace Hyena.Data { public abstract class ModelCache where T : ICacheableItem, new () { private ICacheableModel model; protected ICacheableModel Model { get { return model; } } public ModelCache (ICacheableModel model) { this.model = model; } public virtual T GetValue (long index) { lock (this) { if (ContainsKey (index)) return this[index]; FetchSet (index, model.FetchCount); if (ContainsKey (index)) return this[index]; return default (T); } } // Responsible for fetching a set of items and placing them in the cache protected abstract void FetchSet (long offset, long limit); // Regenerate the cache public abstract void Reload (); public abstract bool ContainsKey (long i); public abstract void Add (long i, T item); public abstract T this[long i] { get; } public abstract void Clear (); } } hyena-0.5/Hyena/Hyena.Data/PropertyStore.cs0000644000175000001440000001530211436010340020740 0ustar00gabeusers00000000000000// // PropertyStore.cs // // Author: // Aaron Bockover // // Copyright (C) 2007 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Collections.Generic; namespace Hyena.Data { public delegate void PropertyChangeEventHandler(object o, PropertyChangeEventArgs args); public class PropertyChangeEventArgs : EventArgs { private string property_name; private bool added; private bool removed; private object old_value; private object new_value; public PropertyChangeEventArgs(string propertyName, bool added, bool removed, object oldValue, object newValue) { this.property_name = propertyName; this.added = added; this.removed = removed; this.old_value = oldValue; this.new_value = newValue; } public string PropertyName { get { return property_name; } } public bool Added { get { return added; } } public bool Removed { get { return removed; } } public object OldValue { get { return old_value; } } public object NewValue { get { return new_value; } } } public class PropertyStore { private Dictionary object_store; public event PropertyChangeEventHandler PropertyChanged; public PropertyStore() { } protected virtual void OnPropertyChanged(string propertyName, bool added, bool removed, object oldValue, object newValue) { PropertyChangeEventHandler handler = PropertyChanged; if(handler != null) { PropertyChangeEventArgs args = new PropertyChangeEventArgs(propertyName, added, removed, oldValue, newValue); handler(this, args); } } public void Remove(string name) { bool raise = false; object old_value = null; lock(this) { if(object_store.ContainsKey(name)) { old_value = object_store[name]; object_store.Remove(name); raise = true; } } if (raise) { OnPropertyChanged(name, false, true, old_value, null); } } public void RemoveStartingWith (string prefix) { lock(this) { Queue to_remove = null; foreach (KeyValuePair item in object_store) { if (item.Key.StartsWith (prefix)) { if (to_remove == null) { to_remove = new Queue (); } to_remove.Enqueue (item.Key); } } while (to_remove != null && to_remove.Count > 0) { Remove (to_remove.Dequeue ()); } } } public void Set(string name, T value) { bool added = false; T old_value = default(T); lock(this) { if(object_store == null) { object_store = new Dictionary(); } if(object_store.ContainsKey(name)) { old_value = (T)object_store[name]; if ((value == null && old_value == null) || value.Equals (old_value)) return; object_store[name] = value; } else { added = true; object_store.Add(name, value); } } OnPropertyChanged(name, added, false, old_value, value); } public T Get(string name) { lock(this) { if(object_store != null && object_store.ContainsKey(name)) { return (T)object_store[name]; } return default(T); } } public T Get(string name, T fallback) { lock(this) { if(object_store != null && object_store.ContainsKey(name)) { return (T)object_store[name]; } return fallback; } } public int GetInteger(string name) { return Get(name); } public void SetInteger(string name, int value) { Set(name, value); } // No longer used, since it causes strings to be marked for translation /*public string GetString(string name) { return Get(name); }*/ public void SetString(string name, string value) { Set(name, value); } public string [] GetStringList(string name) { return Get(name); } public void SetStringList(string name, params string [] value) { Set(name, value); } public bool GetBoolean(string name) { return Get(name); } public void SetBoolean(string name, bool value) { Set(name, value); } public bool Contains(string name) { lock(this) { return object_store != null && object_store.ContainsKey(name); } } public Type GetType(string name) { lock(this) { return Contains(name) ? object_store[name].GetType() : null; } } } } hyena-0.5/Hyena/Hyena.Data/MemoryListModel.cs0000644000175000001440000000511611377105342021201 0ustar00gabeusers00000000000000// // MemoryListModel.cs // // Author: // Gabriel Burt // // Copyright (C) 2009 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Collections.Generic; using Hyena.Collections; namespace Hyena.Data { public class MemoryListModel : BaseListModel { private List list; public MemoryListModel () { list = new List (); Selection = new Selection (); } public override void Clear () { lock (list) { list.Clear (); } OnCleared (); } public override void Reload () { OnReloaded (); } public int IndexOf (T item) { lock (list) { return list.IndexOf (item); } } public void Add (T item) { lock (list) { list.Add (item); } } public void Remove (T item) { lock (list) { list.Remove (item); } } public override T this[int index] { get { lock (list) { if (list.Count <= index || index < 0) { return default (T); } return list[index]; } } } public override int Count { get { lock (list) { return list.Count; } } } } } hyena-0.5/Hyena/Hyena.Data/DictionaryModelCache.cs0000644000175000001440000000370211377105342022125 0ustar00gabeusers00000000000000// // DictionaryModelCache.cs // // Author: // Gabriel Burt // // Copyright (C) 2007 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Collections.Generic; namespace Hyena.Data { public abstract class DictionaryModelCache : ModelCache where T : ICacheableItem, new () { protected Dictionary cache; public DictionaryModelCache (ICacheableModel model) : base (model) { cache = new Dictionary (model.FetchCount); } public override bool ContainsKey (long i) { return cache.ContainsKey (i); } public override void Add (long i, T item) { cache.Add (i, item); } public override T this [long i] { get { return cache [i]; } } public override void Clear () { cache.Clear (); } } } hyena-0.5/Hyena/Hyena.Data/ISelectable.cs0000644000175000001440000000250211377105342020264 0ustar00gabeusers00000000000000// // ISelectable.cs // // Author: // Aaron Bockover // // Copyright (C) 2007 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using Hyena.Collections; namespace Hyena.Data { public interface ISelectable { Selection Selection { get; } } } hyena-0.5/Hyena/Hyena.Data/IListModel.cs0000644000175000001440000000334411377105342020122 0ustar00gabeusers00000000000000// // IListModel.cs // // Author: // Aaron Bockover // // Copyright (C) 2007 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using Hyena.Collections; namespace Hyena.Data { public interface IListModel : ISelectable { event EventHandler Cleared; event EventHandler Reloaded; void Clear (); void Reload (); int Count { get; } bool CanReorder { get; } object GetItem (int index); } public interface IListModel : IListModel { T this[int index] { get; } } public interface IObjectListModel : IListModel { ColumnDescription [] ColumnDescriptions { get; } } }hyena-0.5/Hyena/Hyena.Data/ICacheableModel.cs0000644000175000001440000000252411377105342021035 0ustar00gabeusers00000000000000// // ICacheableModel.cs // // Author: // Gabriel Burt // // Copyright (C) 2007 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Collections.Generic; namespace Hyena.Data { public interface ICacheableModel : ISelectable { int FetchCount { get; } } }hyena-0.5/Hyena/Hyena.Data/BaseListModel.cs0000644000175000001440000000610511377105342020602 0ustar00gabeusers00000000000000// // BaseListModel.cs // // Author: // Gabriel Burt // Aaron Bockover // // Copyright (C) 2007-2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using Hyena.Collections; namespace Hyena.Data { public abstract class BaseListModel : IListModel { private Selection selection; public event EventHandler Cleared; public event EventHandler Reloaded; public BaseListModel () : base () { } protected virtual void OnCleared () { Selection.MaxIndex = Count - 1; EventHandler handler = Cleared; if(handler != null) { handler(this, EventArgs.Empty); } } protected virtual void OnReloaded () { Selection.MaxIndex = Count - 1; EventHandler handler = Reloaded; if(handler != null) { handler(this, EventArgs.Empty); } } public void RaiseReloaded () { OnReloaded (); } public abstract void Clear(); public abstract void Reload(); public abstract T this[int index] { get; } public abstract int Count { get; } public virtual object GetItem (int index) { return this[index]; } public virtual Selection Selection { get { return selection; } protected set { selection = value; } } protected ModelSelection model_selection; public virtual ModelSelection SelectedItems { get { return model_selection ?? (model_selection = new ModelSelection (this, Selection)); } } public T FocusedItem { get { return Selection.FocusedIndex == -1 ? default(T) : this[Selection.FocusedIndex]; } } private bool can_reorder = false; public bool CanReorder { get { return can_reorder; } set { can_reorder = value; } } } } hyena-0.5/Hyena/Hyena.Data/ModelSelection.cs0000644000175000001440000000472711377105342021031 0ustar00gabeusers00000000000000// // ModelSelection.cs.cs // // Author: // Gabriel Burt // // Copyright (C) 2007 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Collections; using System.Collections.Generic; using Hyena.Collections; namespace Hyena.Data { //public class ModelSelection : IList public class ModelSelection : IEnumerable { private IListModel model; private Selection selection; #region Properties /*public T this [int index] { get { if (index >= selection.Count) throw new ArgumentOutOfRangeException ("index"); //return model [selection [index]]; return default(T); } }*/ public int Count { get { return selection.Count; } } #endregion public ModelSelection (IListModel model, Selection selection) { this.model = model; this.selection = selection; } #region Methods /*public int IndexOf (T value) { //selection.IndexOf (model.IndexOf (value)); return -1; }*/ public IEnumerator GetEnumerator () { foreach (int i in selection) { yield return model [i]; } } IEnumerator IEnumerable.GetEnumerator () { return GetEnumerator (); } #endregion } } hyena-0.5/Hyena/Hyena.Data/SortType.cs0000644000175000001440000000243511377105342017706 0ustar00gabeusers00000000000000// // SortType.cs // // Author: // Aaron Bockover // // Copyright (C) 2007 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // namespace Hyena.Data { public enum SortType { None, Ascending, Descending } } hyena-0.5/Hyena/Hyena.Data/IFilterable.cs0000644000175000001440000000250011377105342020270 0ustar00gabeusers00000000000000// // IFilterable.cs // // Author: // Aaron Bockover // // Copyright (C) 2007 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // namespace Hyena.Data { public interface IFilterable { string UserQuery { get; set; } int UnfilteredCount { get; } } } hyena-0.5/Hyena/Hyena.Data/IPropertyStoreExpose.cs0000644000175000001440000000250211377105342022246 0ustar00gabeusers00000000000000// // IPropertyStoreExpose.cs // // Author: // Aaron Bockover // // Copyright (C) 2007 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; namespace Hyena.Data { public interface IPropertyStoreExpose { PropertyStore PropertyStore { get; } } } hyena-0.5/Hyena/System.Web/0000777000175000001440000000000011453151002015637 5ustar00gabeusers00000000000000hyena-0.5/Hyena/System.Web/Helpers.cs0000644000175000001440000000256711377105342017611 0ustar00gabeusers00000000000000// // System.Web.Util.Helpers // // Authors: // Marek Habersack (mhabersack@novell.com) // // (C) 2009 Novell, Inc (http://novell.com) // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Globalization; namespace System.Web.Util { class Helpers { public static readonly CultureInfo InvariantCulture = CultureInfo.InvariantCulture; } } hyena-0.5/Hyena/System.Web/HttpUtility.cs0000644000175000001440000007335111377105342020511 0ustar00gabeusers00000000000000// // System.Web.HttpUtility // // Authors: // Patrik Torstensson (Patrik.Torstensson@labs2.com) // Wictor Wilén (decode/encode functions) (wictor@ibizkit.se) // Tim Coleman (tim@timcoleman.com) // Gonzalo Paniagua Javier (gonzalo@ximian.com) // // Copyright (C) 2005 Novell, Inc (http://www.novell.com) // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System.Collections; using System.Collections.Specialized; using System.Globalization; using System.IO; using System.Security.Permissions; using System.Text; using System.Web.Util; #if NET_2_0 using System.Collections.Generic; #endif namespace System.Web { #if !MONOTOUCH // CAS - no InheritanceDemand here as the class is sealed [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] #endif public sealed class HttpUtility { #region Fields static Hashtable entities; static object lock_ = new object (); #endregion // Fields static Hashtable Entities { get { lock (lock_) { if (entities == null) InitEntities (); return entities; } } } #region Constructors static void InitEntities () { // Build the hash table of HTML entity references. This list comes // from the HTML 4.01 W3C recommendation. entities = new Hashtable (); entities.Add ("nbsp", '\u00A0'); entities.Add ("iexcl", '\u00A1'); entities.Add ("cent", '\u00A2'); entities.Add ("pound", '\u00A3'); entities.Add ("curren", '\u00A4'); entities.Add ("yen", '\u00A5'); entities.Add ("brvbar", '\u00A6'); entities.Add ("sect", '\u00A7'); entities.Add ("uml", '\u00A8'); entities.Add ("copy", '\u00A9'); entities.Add ("ordf", '\u00AA'); entities.Add ("laquo", '\u00AB'); entities.Add ("not", '\u00AC'); entities.Add ("shy", '\u00AD'); entities.Add ("reg", '\u00AE'); entities.Add ("macr", '\u00AF'); entities.Add ("deg", '\u00B0'); entities.Add ("plusmn", '\u00B1'); entities.Add ("sup2", '\u00B2'); entities.Add ("sup3", '\u00B3'); entities.Add ("acute", '\u00B4'); entities.Add ("micro", '\u00B5'); entities.Add ("para", '\u00B6'); entities.Add ("middot", '\u00B7'); entities.Add ("cedil", '\u00B8'); entities.Add ("sup1", '\u00B9'); entities.Add ("ordm", '\u00BA'); entities.Add ("raquo", '\u00BB'); entities.Add ("frac14", '\u00BC'); entities.Add ("frac12", '\u00BD'); entities.Add ("frac34", '\u00BE'); entities.Add ("iquest", '\u00BF'); entities.Add ("Agrave", '\u00C0'); entities.Add ("Aacute", '\u00C1'); entities.Add ("Acirc", '\u00C2'); entities.Add ("Atilde", '\u00C3'); entities.Add ("Auml", '\u00C4'); entities.Add ("Aring", '\u00C5'); entities.Add ("AElig", '\u00C6'); entities.Add ("Ccedil", '\u00C7'); entities.Add ("Egrave", '\u00C8'); entities.Add ("Eacute", '\u00C9'); entities.Add ("Ecirc", '\u00CA'); entities.Add ("Euml", '\u00CB'); entities.Add ("Igrave", '\u00CC'); entities.Add ("Iacute", '\u00CD'); entities.Add ("Icirc", '\u00CE'); entities.Add ("Iuml", '\u00CF'); entities.Add ("ETH", '\u00D0'); entities.Add ("Ntilde", '\u00D1'); entities.Add ("Ograve", '\u00D2'); entities.Add ("Oacute", '\u00D3'); entities.Add ("Ocirc", '\u00D4'); entities.Add ("Otilde", '\u00D5'); entities.Add ("Ouml", '\u00D6'); entities.Add ("times", '\u00D7'); entities.Add ("Oslash", '\u00D8'); entities.Add ("Ugrave", '\u00D9'); entities.Add ("Uacute", '\u00DA'); entities.Add ("Ucirc", '\u00DB'); entities.Add ("Uuml", '\u00DC'); entities.Add ("Yacute", '\u00DD'); entities.Add ("THORN", '\u00DE'); entities.Add ("szlig", '\u00DF'); entities.Add ("agrave", '\u00E0'); entities.Add ("aacute", '\u00E1'); entities.Add ("acirc", '\u00E2'); entities.Add ("atilde", '\u00E3'); entities.Add ("auml", '\u00E4'); entities.Add ("aring", '\u00E5'); entities.Add ("aelig", '\u00E6'); entities.Add ("ccedil", '\u00E7'); entities.Add ("egrave", '\u00E8'); entities.Add ("eacute", '\u00E9'); entities.Add ("ecirc", '\u00EA'); entities.Add ("euml", '\u00EB'); entities.Add ("igrave", '\u00EC'); entities.Add ("iacute", '\u00ED'); entities.Add ("icirc", '\u00EE'); entities.Add ("iuml", '\u00EF'); entities.Add ("eth", '\u00F0'); entities.Add ("ntilde", '\u00F1'); entities.Add ("ograve", '\u00F2'); entities.Add ("oacute", '\u00F3'); entities.Add ("ocirc", '\u00F4'); entities.Add ("otilde", '\u00F5'); entities.Add ("ouml", '\u00F6'); entities.Add ("divide", '\u00F7'); entities.Add ("oslash", '\u00F8'); entities.Add ("ugrave", '\u00F9'); entities.Add ("uacute", '\u00FA'); entities.Add ("ucirc", '\u00FB'); entities.Add ("uuml", '\u00FC'); entities.Add ("yacute", '\u00FD'); entities.Add ("thorn", '\u00FE'); entities.Add ("yuml", '\u00FF'); entities.Add ("fnof", '\u0192'); entities.Add ("Alpha", '\u0391'); entities.Add ("Beta", '\u0392'); entities.Add ("Gamma", '\u0393'); entities.Add ("Delta", '\u0394'); entities.Add ("Epsilon", '\u0395'); entities.Add ("Zeta", '\u0396'); entities.Add ("Eta", '\u0397'); entities.Add ("Theta", '\u0398'); entities.Add ("Iota", '\u0399'); entities.Add ("Kappa", '\u039A'); entities.Add ("Lambda", '\u039B'); entities.Add ("Mu", '\u039C'); entities.Add ("Nu", '\u039D'); entities.Add ("Xi", '\u039E'); entities.Add ("Omicron", '\u039F'); entities.Add ("Pi", '\u03A0'); entities.Add ("Rho", '\u03A1'); entities.Add ("Sigma", '\u03A3'); entities.Add ("Tau", '\u03A4'); entities.Add ("Upsilon", '\u03A5'); entities.Add ("Phi", '\u03A6'); entities.Add ("Chi", '\u03A7'); entities.Add ("Psi", '\u03A8'); entities.Add ("Omega", '\u03A9'); entities.Add ("alpha", '\u03B1'); entities.Add ("beta", '\u03B2'); entities.Add ("gamma", '\u03B3'); entities.Add ("delta", '\u03B4'); entities.Add ("epsilon", '\u03B5'); entities.Add ("zeta", '\u03B6'); entities.Add ("eta", '\u03B7'); entities.Add ("theta", '\u03B8'); entities.Add ("iota", '\u03B9'); entities.Add ("kappa", '\u03BA'); entities.Add ("lambda", '\u03BB'); entities.Add ("mu", '\u03BC'); entities.Add ("nu", '\u03BD'); entities.Add ("xi", '\u03BE'); entities.Add ("omicron", '\u03BF'); entities.Add ("pi", '\u03C0'); entities.Add ("rho", '\u03C1'); entities.Add ("sigmaf", '\u03C2'); entities.Add ("sigma", '\u03C3'); entities.Add ("tau", '\u03C4'); entities.Add ("upsilon", '\u03C5'); entities.Add ("phi", '\u03C6'); entities.Add ("chi", '\u03C7'); entities.Add ("psi", '\u03C8'); entities.Add ("omega", '\u03C9'); entities.Add ("thetasym", '\u03D1'); entities.Add ("upsih", '\u03D2'); entities.Add ("piv", '\u03D6'); entities.Add ("bull", '\u2022'); entities.Add ("hellip", '\u2026'); entities.Add ("prime", '\u2032'); entities.Add ("Prime", '\u2033'); entities.Add ("oline", '\u203E'); entities.Add ("frasl", '\u2044'); entities.Add ("weierp", '\u2118'); entities.Add ("image", '\u2111'); entities.Add ("real", '\u211C'); entities.Add ("trade", '\u2122'); entities.Add ("alefsym", '\u2135'); entities.Add ("larr", '\u2190'); entities.Add ("uarr", '\u2191'); entities.Add ("rarr", '\u2192'); entities.Add ("darr", '\u2193'); entities.Add ("harr", '\u2194'); entities.Add ("crarr", '\u21B5'); entities.Add ("lArr", '\u21D0'); entities.Add ("uArr", '\u21D1'); entities.Add ("rArr", '\u21D2'); entities.Add ("dArr", '\u21D3'); entities.Add ("hArr", '\u21D4'); entities.Add ("forall", '\u2200'); entities.Add ("part", '\u2202'); entities.Add ("exist", '\u2203'); entities.Add ("empty", '\u2205'); entities.Add ("nabla", '\u2207'); entities.Add ("isin", '\u2208'); entities.Add ("notin", '\u2209'); entities.Add ("ni", '\u220B'); entities.Add ("prod", '\u220F'); entities.Add ("sum", '\u2211'); entities.Add ("minus", '\u2212'); entities.Add ("lowast", '\u2217'); entities.Add ("radic", '\u221A'); entities.Add ("prop", '\u221D'); entities.Add ("infin", '\u221E'); entities.Add ("ang", '\u2220'); entities.Add ("and", '\u2227'); entities.Add ("or", '\u2228'); entities.Add ("cap", '\u2229'); entities.Add ("cup", '\u222A'); entities.Add ("int", '\u222B'); entities.Add ("there4", '\u2234'); entities.Add ("sim", '\u223C'); entities.Add ("cong", '\u2245'); entities.Add ("asymp", '\u2248'); entities.Add ("ne", '\u2260'); entities.Add ("equiv", '\u2261'); entities.Add ("le", '\u2264'); entities.Add ("ge", '\u2265'); entities.Add ("sub", '\u2282'); entities.Add ("sup", '\u2283'); entities.Add ("nsub", '\u2284'); entities.Add ("sube", '\u2286'); entities.Add ("supe", '\u2287'); entities.Add ("oplus", '\u2295'); entities.Add ("otimes", '\u2297'); entities.Add ("perp", '\u22A5'); entities.Add ("sdot", '\u22C5'); entities.Add ("lceil", '\u2308'); entities.Add ("rceil", '\u2309'); entities.Add ("lfloor", '\u230A'); entities.Add ("rfloor", '\u230B'); entities.Add ("lang", '\u2329'); entities.Add ("rang", '\u232A'); entities.Add ("loz", '\u25CA'); entities.Add ("spades", '\u2660'); entities.Add ("clubs", '\u2663'); entities.Add ("hearts", '\u2665'); entities.Add ("diams", '\u2666'); entities.Add ("quot", '\u0022'); entities.Add ("amp", '\u0026'); entities.Add ("lt", '\u003C'); entities.Add ("gt", '\u003E'); entities.Add ("OElig", '\u0152'); entities.Add ("oelig", '\u0153'); entities.Add ("Scaron", '\u0160'); entities.Add ("scaron", '\u0161'); entities.Add ("Yuml", '\u0178'); entities.Add ("circ", '\u02C6'); entities.Add ("tilde", '\u02DC'); entities.Add ("ensp", '\u2002'); entities.Add ("emsp", '\u2003'); entities.Add ("thinsp", '\u2009'); entities.Add ("zwnj", '\u200C'); entities.Add ("zwj", '\u200D'); entities.Add ("lrm", '\u200E'); entities.Add ("rlm", '\u200F'); entities.Add ("ndash", '\u2013'); entities.Add ("mdash", '\u2014'); entities.Add ("lsquo", '\u2018'); entities.Add ("rsquo", '\u2019'); entities.Add ("sbquo", '\u201A'); entities.Add ("ldquo", '\u201C'); entities.Add ("rdquo", '\u201D'); entities.Add ("bdquo", '\u201E'); entities.Add ("dagger", '\u2020'); entities.Add ("Dagger", '\u2021'); entities.Add ("permil", '\u2030'); entities.Add ("lsaquo", '\u2039'); entities.Add ("rsaquo", '\u203A'); entities.Add ("euro", '\u20AC'); } public HttpUtility () { } #endregion // Constructors #region Methods public static void HtmlAttributeEncode (string s, TextWriter output) { output.Write(HtmlAttributeEncode(s)); } public static string HtmlAttributeEncode (string s) { if (null == s) return null; bool needEncode = false; for (int i = 0; i < s.Length; i++) { if (s [i] == '&' || s [i] == '"' || s [i] == '<') { needEncode = true; break; } } if (!needEncode) return s; StringBuilder output = new StringBuilder (); int len = s.Length; for (int i = 0; i < len; i++) switch (s [i]) { case '&' : output.Append ("&"); break; case '"' : output.Append ("""); break; case '<': output.Append ("<"); break; default: output.Append (s [i]); break; } return output.ToString(); } public static string UrlDecode (string str) { return UrlDecode(str, Encoding.UTF8); } static char [] GetChars (MemoryStream b, Encoding e) { return e.GetChars (b.GetBuffer (), 0, (int) b.Length); } static void WriteCharBytes (IList buf, char ch, Encoding e) { if (ch > 255) { foreach (byte b in e.GetBytes (new char[] { ch })) buf.Add (b); } else buf.Add ((byte)ch); } public static string UrlDecode (string s, Encoding e) { if (null == s) return null; if (s.IndexOf ('%') == -1 && s.IndexOf ('+') == -1) return s; if (e == null) e = Encoding.UTF8; long len = s.Length; #if NET_2_0 var bytes = new List (); #else ArrayList bytes = new ArrayList (); #endif int xchar; char ch; for (int i = 0; i < len; i++) { ch = s [i]; if (ch == '%' && i + 2 < len && s [i + 1] != '%') { if (s [i + 1] == 'u' && i + 5 < len) { // unicode hex sequence xchar = GetChar (s, i + 2, 4); if (xchar != -1) { WriteCharBytes (bytes, (char)xchar, e); i += 5; } else WriteCharBytes (bytes, '%', e); } else if ((xchar = GetChar (s, i + 1, 2)) != -1) { WriteCharBytes (bytes, (char)xchar, e); i += 2; } else { WriteCharBytes (bytes, '%', e); } continue; } if (ch == '+') WriteCharBytes (bytes, ' ', e); else WriteCharBytes (bytes, ch, e); } #if NET_2_0 byte[] buf = bytes.ToArray (); #else byte[] buf = (byte[])bytes.ToArray (typeof (byte)); #endif bytes = null; return e.GetString (buf); } public static string UrlDecode (byte [] bytes, Encoding e) { if (bytes == null) return null; return UrlDecode (bytes, 0, bytes.Length, e); } static int GetInt (byte b) { char c = (char) b; if (c >= '0' && c <= '9') return c - '0'; if (c >= 'a' && c <= 'f') return c - 'a' + 10; if (c >= 'A' && c <= 'F') return c - 'A' + 10; return -1; } static int GetChar (byte [] bytes, int offset, int length) { int value = 0; int end = length + offset; for (int i = offset; i < end; i++) { int current = GetInt (bytes [i]); if (current == -1) return -1; value = (value << 4) + current; } return value; } static int GetChar (string str, int offset, int length) { int val = 0; int end = length + offset; for (int i = offset; i < end; i++) { char c = str [i]; if (c > 127) return -1; int current = GetInt ((byte) c); if (current == -1) return -1; val = (val << 4) + current; } return val; } public static string UrlDecode (byte [] bytes, int offset, int count, Encoding e) { if (bytes == null) return null; if (count == 0) return String.Empty; if (bytes == null) throw new ArgumentNullException ("bytes"); if (offset < 0 || offset > bytes.Length) throw new ArgumentOutOfRangeException ("offset"); if (count < 0 || offset + count > bytes.Length) throw new ArgumentOutOfRangeException ("count"); StringBuilder output = new StringBuilder (); MemoryStream acc = new MemoryStream (); int end = count + offset; int xchar; for (int i = offset; i < end; i++) { if (bytes [i] == '%' && i + 2 < count && bytes [i + 1] != '%') { if (bytes [i + 1] == (byte) 'u' && i + 5 < end) { if (acc.Length > 0) { output.Append (GetChars (acc, e)); acc.SetLength (0); } xchar = GetChar (bytes, i + 2, 4); if (xchar != -1) { output.Append ((char) xchar); i += 5; continue; } } else if ((xchar = GetChar (bytes, i + 1, 2)) != -1) { acc.WriteByte ((byte) xchar); i += 2; continue; } } if (acc.Length > 0) { output.Append (GetChars (acc, e)); acc.SetLength (0); } if (bytes [i] == '+') { output.Append (' '); } else { output.Append ((char) bytes [i]); } } if (acc.Length > 0) { output.Append (GetChars (acc, e)); } acc = null; return output.ToString (); } public static byte [] UrlDecodeToBytes (byte [] bytes) { if (bytes == null) return null; return UrlDecodeToBytes (bytes, 0, bytes.Length); } public static byte [] UrlDecodeToBytes (string str) { return UrlDecodeToBytes (str, Encoding.UTF8); } public static byte [] UrlDecodeToBytes (string str, Encoding e) { if (str == null) return null; if (e == null) throw new ArgumentNullException ("e"); return UrlDecodeToBytes (e.GetBytes (str)); } public static byte [] UrlDecodeToBytes (byte [] bytes, int offset, int count) { if (bytes == null) return null; if (count == 0) return new byte [0]; int len = bytes.Length; if (offset < 0 || offset >= len) throw new ArgumentOutOfRangeException("offset"); if (count < 0 || offset > len - count) throw new ArgumentOutOfRangeException("count"); MemoryStream result = new MemoryStream (); int end = offset + count; for (int i = offset; i < end; i++){ char c = (char) bytes [i]; if (c == '+') { c = ' '; } else if (c == '%' && i < end - 2) { int xchar = GetChar (bytes, i + 1, 2); if (xchar != -1) { c = (char) xchar; i += 2; } } result.WriteByte ((byte) c); } return result.ToArray (); } public static string UrlEncode(string str) { return UrlEncode(str, Encoding.UTF8); } public static string UrlEncode (string s, Encoding Enc) { if (s == null) return null; if (s == "") return ""; bool needEncode = false; int len = s.Length; for (int i = 0; i < len; i++) { char c = s [i]; if ((c < '0') || (c < 'A' && c > '9') || (c > 'Z' && c < 'a') || (c > 'z')) { if (NotEncoded (c)) continue; needEncode = true; break; } } if (!needEncode) return s; // avoided GetByteCount call byte [] bytes = new byte[Enc.GetMaxByteCount(s.Length)]; int realLen = Enc.GetBytes (s, 0, s.Length, bytes, 0); return Encoding.ASCII.GetString (UrlEncodeToBytes (bytes, 0, realLen)); } public static string UrlEncode (byte [] bytes) { if (bytes == null) return null; if (bytes.Length == 0) return ""; return Encoding.ASCII.GetString (UrlEncodeToBytes (bytes, 0, bytes.Length)); } public static string UrlEncode (byte [] bytes, int offset, int count) { if (bytes == null) return null; if (bytes.Length == 0) return ""; return Encoding.ASCII.GetString (UrlEncodeToBytes (bytes, offset, count)); } public static byte [] UrlEncodeToBytes (string str) { return UrlEncodeToBytes (str, Encoding.UTF8); } public static byte [] UrlEncodeToBytes (string str, Encoding e) { if (str == null) return null; if (str == "") return new byte [0]; byte [] bytes = e.GetBytes (str); return UrlEncodeToBytes (bytes, 0, bytes.Length); } public static byte [] UrlEncodeToBytes (byte [] bytes) { if (bytes == null) return null; if (bytes.Length == 0) return new byte [0]; return UrlEncodeToBytes (bytes, 0, bytes.Length); } static char [] hexChars = "0123456789abcdef".ToCharArray (); static bool NotEncoded (char c) { return (c == '!' || c == '\'' || c == '(' || c == ')' || c == '*' || c == '-' || c == '.' || c == '_'); } static void UrlEncodeChar (char c, Stream result, bool isUnicode) { if (c > 255) { //FIXME: what happens when there is an internal error? //if (!isUnicode) // throw new ArgumentOutOfRangeException ("c", c, "c must be less than 256"); int idx; int i = (int) c; result.WriteByte ((byte)'%'); result.WriteByte ((byte)'u'); idx = i >> 12; result.WriteByte ((byte)hexChars [idx]); idx = (i >> 8) & 0x0F; result.WriteByte ((byte)hexChars [idx]); idx = (i >> 4) & 0x0F; result.WriteByte ((byte)hexChars [idx]); idx = i & 0x0F; result.WriteByte ((byte)hexChars [idx]); return; } if (c > ' ' && NotEncoded (c)) { result.WriteByte ((byte)c); return; } if (c==' ') { result.WriteByte ((byte)'+'); return; } if ( (c < '0') || (c < 'A' && c > '9') || (c > 'Z' && c < 'a') || (c > 'z')) { if (isUnicode && c > 127) { result.WriteByte ((byte)'%'); result.WriteByte ((byte)'u'); result.WriteByte ((byte)'0'); result.WriteByte ((byte)'0'); } else result.WriteByte ((byte)'%'); int idx = ((int) c) >> 4; result.WriteByte ((byte)hexChars [idx]); idx = ((int) c) & 0x0F; result.WriteByte ((byte)hexChars [idx]); } else result.WriteByte ((byte)c); } public static byte [] UrlEncodeToBytes (byte [] bytes, int offset, int count) { if (bytes == null) return null; int len = bytes.Length; if (len == 0) return new byte [0]; if (offset < 0 || offset >= len) throw new ArgumentOutOfRangeException("offset"); if (count < 0 || count > len - offset) throw new ArgumentOutOfRangeException("count"); MemoryStream result = new MemoryStream (count); int end = offset + count; for (int i = offset; i < end; i++) UrlEncodeChar ((char)bytes [i], result, false); return result.ToArray(); } public static string UrlEncodeUnicode (string str) { if (str == null) return null; return Encoding.ASCII.GetString (UrlEncodeUnicodeToBytes (str)); } public static byte [] UrlEncodeUnicodeToBytes (string str) { if (str == null) return null; if (str == "") return new byte [0]; MemoryStream result = new MemoryStream (str.Length); foreach (char c in str){ UrlEncodeChar (c, result, true); } return result.ToArray (); } /// /// Decodes an HTML-encoded string and returns the decoded string. /// /// The HTML string to decode. /// The decoded text. public static string HtmlDecode (string s) { if (s == null) throw new ArgumentNullException ("s"); if (s.IndexOf ('&') == -1) return s; StringBuilder entity = new StringBuilder (); StringBuilder output = new StringBuilder (); int len = s.Length; // 0 -> nothing, // 1 -> right after '&' // 2 -> between '&' and ';' but no '#' // 3 -> '#' found after '&' and getting numbers int state = 0; int number = 0; bool have_trailing_digits = false; for (int i = 0; i < len; i++) { char c = s [i]; if (state == 0) { if (c == '&') { entity.Append (c); state = 1; } else { output.Append (c); } continue; } if (c == '&') { state = 1; if (have_trailing_digits) { entity.Append (number.ToString (Helpers.InvariantCulture)); have_trailing_digits = false; } output.Append (entity.ToString ()); entity.Length = 0; entity.Append ('&'); continue; } if (state == 1) { if (c == ';') { state = 0; output.Append (entity.ToString ()); output.Append (c); entity.Length = 0; } else { number = 0; if (c != '#') { state = 2; } else { state = 3; } entity.Append (c); } } else if (state == 2) { entity.Append (c); if (c == ';') { string key = entity.ToString (); if (key.Length > 1 && Entities.ContainsKey (key.Substring (1, key.Length - 2))) key = Entities [key.Substring (1, key.Length - 2)].ToString (); output.Append (key); state = 0; entity.Length = 0; } } else if (state == 3) { if (c == ';') { if (number > 65535) { output.Append ("&#"); output.Append (number.ToString (Helpers.InvariantCulture)); output.Append (";"); } else { output.Append ((char) number); } state = 0; entity.Length = 0; have_trailing_digits = false; } else if (Char.IsDigit (c)) { number = number * 10 + ((int) c - '0'); have_trailing_digits = true; } else { state = 2; if (have_trailing_digits) { entity.Append (number.ToString (Helpers.InvariantCulture)); have_trailing_digits = false; } entity.Append (c); } } } if (entity.Length > 0) { output.Append (entity.ToString ()); } else if (have_trailing_digits) { output.Append (number.ToString (Helpers.InvariantCulture)); } return output.ToString (); } /// /// Decodes an HTML-encoded string and sends the resulting output to a TextWriter output stream. /// /// The HTML string to decode /// The TextWriter output stream containing the decoded string. public static void HtmlDecode(string s, TextWriter output) { if (s != null) output.Write (HtmlDecode (s)); } /// /// HTML-encodes a string and returns the encoded string. /// /// The text string to encode. /// The HTML-encoded text. public static string HtmlEncode (string s) { if (s == null) return null; bool needEncode = false; for (int i = 0; i < s.Length; i++) { char c = s [i]; if (c == '&' || c == '"' || c == '<' || c == '>' || c > 159) { needEncode = true; break; } } if (!needEncode) return s; StringBuilder output = new StringBuilder (); int len = s.Length; for (int i = 0; i < len; i++) switch (s [i]) { case '&' : output.Append ("&"); break; case '>' : output.Append (">"); break; case '<' : output.Append ("<"); break; case '"' : output.Append ("""); break; default: // MS starts encoding with &# from 160 and stops at 255. // We don't do that. One reason is the 65308/65310 unicode // characters that look like '<' and '>'. #if TARGET_JVM if (s [i] > 159 && s [i] < 256) { #else if (s [i] > 159) { #endif output.Append ("&#"); output.Append (((int) s [i]).ToString (Helpers.InvariantCulture)); output.Append (";"); } else { output.Append (s [i]); } break; } return output.ToString (); } /// /// HTML-encodes a string and sends the resulting output to a TextWriter output stream. /// /// The string to encode. /// The TextWriter output stream containing the encoded string. public static void HtmlEncode(string s, TextWriter output) { if (s != null) output.Write (HtmlEncode (s)); } #if NET_1_1 public static string UrlPathEncode (string s) { if (s == null || s.Length == 0) return s; MemoryStream result = new MemoryStream (); int length = s.Length; for (int i = 0; i < length; i++) { UrlPathEncodeChar (s [i], result); } return Encoding.ASCII.GetString (result.ToArray ()); } static void UrlPathEncodeChar (char c, Stream result) { #if NET_2_0 if (c < 33 || c > 126) { #else if (c > 127) { #endif byte [] bIn = Encoding.UTF8.GetBytes (c.ToString ()); for (int i = 0; i < bIn.Length; i++) { result.WriteByte ((byte) '%'); int idx = ((int) bIn [i]) >> 4; result.WriteByte ((byte) hexChars [idx]); idx = ((int) bIn [i]) & 0x0F; result.WriteByte ((byte) hexChars [idx]); } } else if (c == ' ') { result.WriteByte ((byte) '%'); result.WriteByte ((byte) '2'); result.WriteByte ((byte) '0'); } else result.WriteByte ((byte) c); } #endif #if NET_2_0 class HttpQSCollection : NameValueCollection { public override string ToString () { int count = Count; if (count == 0) return ""; StringBuilder sb = new StringBuilder (); string [] keys = AllKeys; for (int i = 0; i < count; i++) { sb.AppendFormat ("{0}={1}&", keys [i], this [keys [i]]); } if (sb.Length > 0) sb.Length--; return sb.ToString (); } } public static NameValueCollection ParseQueryString (string query) { return ParseQueryString (query, Encoding.UTF8); } public static NameValueCollection ParseQueryString (string query, Encoding encoding) { if (query == null) throw new ArgumentNullException ("query"); if (encoding == null) throw new ArgumentNullException ("encoding"); if (query.Length == 0 || (query.Length == 1 && query[0] == '?')) return new NameValueCollection (); if (query[0] == '?') query = query.Substring (1); NameValueCollection result = new HttpQSCollection (); ParseQueryString (query, encoding, result); return result; } #endif internal static void ParseQueryString (string query, Encoding encoding, NameValueCollection result) { if (query.Length == 0) return; string decoded = HtmlDecode (query); int decodedLength = decoded.Length; int namePos = 0; bool first = true; while (namePos <= decodedLength) { int valuePos = -1, valueEnd = -1; for (int q = namePos; q < decodedLength; q++) { if (valuePos == -1 && decoded [q] == '=') { valuePos = q + 1; } else if (decoded [q] == '&') { valueEnd = q; break; } } if (first) { first = false; if (decoded [namePos] == '?') namePos++; } string name, value; if (valuePos == -1) { name = null; valuePos = namePos; } else { name = UrlDecode (decoded.Substring (namePos, valuePos - namePos - 1), encoding); } if (valueEnd < 0) { namePos = -1; valueEnd = decoded.Length; } else { namePos = valueEnd + 1; } value = UrlDecode (decoded.Substring (valuePos, valueEnd - valuePos), encoding); result.Add (name, value); if (namePos == -1) break; } } #endregion // Methods } } hyena-0.5/missing0000755000175000001440000002557711147724431014222 0ustar00gabeusers00000000000000#! /bin/sh # Common stub for a few missing GNU programs while installing. scriptversion=2006-05-10.23 # Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006 # Free Software Foundation, Inc. # Originally by Fran,cois Pinard , 1996. # 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, 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., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. if test $# -eq 0; then echo 1>&2 "Try \`$0 --help' for more information" exit 1 fi run=: sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p' sed_minuso='s/.* -o \([^ ]*\).*/\1/p' # In the cases where this matters, `missing' is being run in the # srcdir already. if test -f configure.ac; then configure_ac=configure.ac else configure_ac=configure.in fi msg="missing on your system" case $1 in --run) # Try to run requested program, and just exit if it succeeds. run= shift "$@" && exit 0 # Exit code 63 means version mismatch. This often happens # when the user try to use an ancient version of a tool on # a file that requires a minimum version. In this case we # we should proceed has if the program had been absent, or # if --run hadn't been passed. if test $? = 63; then run=: msg="probably too old" fi ;; -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an error status if there is no known handling for PROGRAM. Options: -h, --help display this help and exit -v, --version output version information and exit --run try to run the given command, and emulate it if it fails Supported PROGRAM values: aclocal touch file \`aclocal.m4' autoconf touch file \`configure' autoheader touch file \`config.h.in' autom4te touch the output file, or create a stub one automake touch all \`Makefile.in' files bison create \`y.tab.[ch]', if possible, from existing .[ch] flex create \`lex.yy.c', if possible, from existing .c help2man touch the output file lex create \`lex.yy.c', if possible, from existing .c makeinfo touch the output file tar try tar, gnutar, gtar, then tar without non-portable flags yacc create \`y.tab.[ch]', if possible, from existing .[ch] Send bug reports to ." exit $? ;; -v|--v|--ve|--ver|--vers|--versi|--versio|--version) echo "missing $scriptversion (GNU Automake)" exit $? ;; -*) echo 1>&2 "$0: Unknown \`$1' option" echo 1>&2 "Try \`$0 --help' for more information" exit 1 ;; esac # Now exit if we have it, but it failed. Also exit now if we # don't have it and --version was passed (most likely to detect # the program). case $1 in lex|yacc) # Not GNU programs, they don't have --version. ;; tar) if test -n "$run"; then echo 1>&2 "ERROR: \`tar' requires --run" exit 1 elif test "x$2" = "x--version" || test "x$2" = "x--help"; then exit 1 fi ;; *) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 elif test "x$2" = "x--version" || test "x$2" = "x--help"; then # Could not run --version or --help. This is probably someone # running `$TOOL --version' or `$TOOL --help' to check whether # $TOOL exists and not knowing $TOOL uses missing. exit 1 fi ;; esac # If it does not exist, or fails to run (possibly an outdated version), # try to emulate it. case $1 in aclocal*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`acinclude.m4' or \`${configure_ac}'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." touch aclocal.m4 ;; autoconf) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`${configure_ac}'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." touch configure ;; autoheader) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`acconfig.h' or \`${configure_ac}'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` test -z "$files" && files="config.h" touch_files= for f in $files; do case $f in *:*) touch_files="$touch_files "`echo "$f" | sed -e 's/^[^:]*://' -e 's/:.*//'`;; *) touch_files="$touch_files $f.in";; esac done touch $touch_files ;; automake*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." find . -type f -name Makefile.am -print | sed 's/\.am$/.in/' | while read f; do touch "$f"; done ;; autom4te) echo 1>&2 "\ WARNING: \`$1' is needed, but is $msg. You might have modified some files without having the proper tools for further handling them. You can get \`$1' as part of \`Autoconf' from any GNU archive site." file=`echo "$*" | sed -n "$sed_output"` test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` if test -f "$file"; then touch $file else test -z "$file" || exec >$file echo "#! /bin/sh" echo "# Created by GNU Automake missing as a replacement of" echo "# $ $@" echo "exit 0" chmod +x $file exit 1 fi ;; bison|yacc) echo 1>&2 "\ WARNING: \`$1' $msg. You should only need it if you modified a \`.y' file. You may need the \`Bison' package in order for those modifications to take effect. You can get \`Bison' from any GNU archive site." rm -f y.tab.c y.tab.h if test $# -ne 1; then eval LASTARG="\${$#}" case $LASTARG in *.y) SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` if test -f "$SRCFILE"; then cp "$SRCFILE" y.tab.c fi SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` if test -f "$SRCFILE"; then cp "$SRCFILE" y.tab.h fi ;; esac fi if test ! -f y.tab.h; then echo >y.tab.h fi if test ! -f y.tab.c; then echo 'main() { return 0; }' >y.tab.c fi ;; lex|flex) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified a \`.l' file. You may need the \`Flex' package in order for those modifications to take effect. You can get \`Flex' from any GNU archive site." rm -f lex.yy.c if test $# -ne 1; then eval LASTARG="\${$#}" case $LASTARG in *.l) SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` if test -f "$SRCFILE"; then cp "$SRCFILE" lex.yy.c fi ;; esac fi if test ! -f lex.yy.c; then echo 'main() { return 0; }' >lex.yy.c fi ;; help2man) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified a dependency of a manual page. You may need the \`Help2man' package in order for those modifications to take effect. You can get \`Help2man' from any GNU archive site." file=`echo "$*" | sed -n "$sed_output"` test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` if test -f "$file"; then touch $file else test -z "$file" || exec >$file echo ".ab help2man is required to generate this page" exit 1 fi ;; makeinfo) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified a \`.texi' or \`.texinfo' file, or any other file indirectly affecting the aspect of the manual. The spurious call might also be the consequence of using a buggy \`make' (AIX, DU, IRIX). You might want to install the \`Texinfo' package or the \`GNU make' package. Grab either from any GNU archive site." # The file to touch is that specified with -o ... file=`echo "$*" | sed -n "$sed_output"` test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` if test -z "$file"; then # ... or it is the one specified with @setfilename ... infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` file=`sed -n ' /^@setfilename/{ s/.* \([^ ]*\) *$/\1/ p q }' $infile` # ... or it is derived from the source name (dir/f.texi becomes f.info) test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info fi # If the file does not exist, the user really needs makeinfo; # let's fail without touching anything. test -f $file || exit 1 touch $file ;; tar) shift # We have already tried tar in the generic part. # Look for gnutar/gtar before invocation to avoid ugly error # messages. if (gnutar --version > /dev/null 2>&1); then gnutar "$@" && exit 0 fi if (gtar --version > /dev/null 2>&1); then gtar "$@" && exit 0 fi firstarg="$1" if shift; then case $firstarg in *o*) firstarg=`echo "$firstarg" | sed s/o//` tar "$firstarg" "$@" && exit 0 ;; esac case $firstarg in *h*) firstarg=`echo "$firstarg" | sed s/h//` tar "$firstarg" "$@" && exit 0 ;; esac fi echo 1>&2 "\ WARNING: I can't seem to be able to run \`tar' with the given arguments. You may want to install GNU tar or Free paxutils, or check the command line arguments." exit 1 ;; *) echo 1>&2 "\ WARNING: \`$1' is needed, and is $msg. You might have modified some files without having the proper tools for further handling them. Check the \`README' file, it often tells you about the needed prerequisites for installing this package. You may also peek at any GNU archive site, in case some other package would contain this missing \`$1' program." exit 1 ;; esac exit 0 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-end: "$" # End: hyena-0.5/install-sh0000755000175000001440000003246411147724431014620 0ustar00gabeusers00000000000000#!/bin/sh # install - install a program, script, or datafile scriptversion=2006-12-25.00 # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the # following copyright and license. # # Copyright (C) 1994 X Consortium # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name of the X Consortium shall not # be used in advertising or otherwise to promote the sale, use or other deal- # ings in this Software without prior written authorization from the X Consor- # tium. # # # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. nl=' ' IFS=" "" $nl" # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit=${DOITPROG-} if test -z "$doit"; then doit_exec=exec else doit_exec=$doit fi # Put in absolute file names if you don't have them in your path; # or use environment vars. chgrpprog=${CHGRPPROG-chgrp} chmodprog=${CHMODPROG-chmod} chownprog=${CHOWNPROG-chown} cmpprog=${CMPPROG-cmp} cpprog=${CPPROG-cp} mkdirprog=${MKDIRPROG-mkdir} mvprog=${MVPROG-mv} rmprog=${RMPROG-rm} stripprog=${STRIPPROG-strip} posix_glob='?' initialize_posix_glob=' test "$posix_glob" != "?" || { if (set -f) 2>/dev/null; then posix_glob= else posix_glob=: fi } ' posix_mkdir= # Desired mode of installed file. mode=0755 chgrpcmd= chmodcmd=$chmodprog chowncmd= mvcmd=$mvprog rmcmd="$rmprog -f" stripcmd= src= dst= dir_arg= dst_arg= copy_on_change=false no_target_directory= usage="\ Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE or: $0 [OPTION]... SRCFILES... DIRECTORY or: $0 [OPTION]... -t DIRECTORY SRCFILES... or: $0 [OPTION]... -d DIRECTORIES... In the 1st form, copy SRCFILE to DSTFILE. In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. In the 4th, create DIRECTORIES. Options: --help display this help and exit. --version display version info and exit. -c (ignored) -C install only if different (preserve the last data modification time) -d create directories instead of installing files. -g GROUP $chgrpprog installed files to GROUP. -m MODE $chmodprog installed files to MODE. -o USER $chownprog installed files to USER. -s $stripprog installed files. -t DIRECTORY install into DIRECTORY. -T report an error if DSTFILE is a directory. Environment variables override the default commands: CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG " while test $# -ne 0; do case $1 in -c) ;; -C) copy_on_change=true;; -d) dir_arg=true;; -g) chgrpcmd="$chgrpprog $2" shift;; --help) echo "$usage"; exit $?;; -m) mode=$2 case $mode in *' '* | *' '* | *' '* | *'*'* | *'?'* | *'['*) echo "$0: invalid mode: $mode" >&2 exit 1;; esac shift;; -o) chowncmd="$chownprog $2" shift;; -s) stripcmd=$stripprog;; -t) dst_arg=$2 shift;; -T) no_target_directory=true;; --version) echo "$0 $scriptversion"; exit $?;; --) shift break;; -*) echo "$0: invalid option: $1" >&2 exit 1;; *) break;; esac shift done if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then # When -d is used, all remaining arguments are directories to create. # When -t is used, the destination is already specified. # Otherwise, the last argument is the destination. Remove it from $@. for arg do if test -n "$dst_arg"; then # $@ is not empty: it contains at least $arg. set fnord "$@" "$dst_arg" shift # fnord fi shift # arg dst_arg=$arg done fi if test $# -eq 0; then if test -z "$dir_arg"; then echo "$0: no input file specified." >&2 exit 1 fi # It's OK to call `install-sh -d' without argument. # This can happen when creating conditional directories. exit 0 fi if test -z "$dir_arg"; then trap '(exit $?); exit' 1 2 13 15 # Set umask so as not to create temps with too-generous modes. # However, 'strip' requires both read and write access to temps. case $mode in # Optimize common cases. *644) cp_umask=133;; *755) cp_umask=22;; *[0-7]) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw='% 200' fi cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; *) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw=,u+rw fi cp_umask=$mode$u_plus_rw;; esac fi for src do # Protect names starting with `-'. case $src in -*) src=./$src;; esac if test -n "$dir_arg"; then dst=$src dstdir=$dst test -d "$dstdir" dstdir_status=$? else # Waiting for this to be detected by the "$cpprog $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if test ! -f "$src" && test ! -d "$src"; then echo "$0: $src does not exist." >&2 exit 1 fi if test -z "$dst_arg"; then echo "$0: no destination specified." >&2 exit 1 fi dst=$dst_arg # Protect names starting with `-'. case $dst in -*) dst=./$dst;; esac # If destination is a directory, append the input filename; won't work # if double slashes aren't ignored. if test -d "$dst"; then if test -n "$no_target_directory"; then echo "$0: $dst_arg: Is a directory" >&2 exit 1 fi dstdir=$dst dst=$dstdir/`basename "$src"` dstdir_status=0 else # Prefer dirname, but fall back on a substitute if dirname fails. dstdir=` (dirname "$dst") 2>/dev/null || expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$dst" : 'X\(//\)[^/]' \| \ X"$dst" : 'X\(//\)$' \| \ X"$dst" : 'X\(/\)' \| . 2>/dev/null || echo X"$dst" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q' ` test -d "$dstdir" dstdir_status=$? fi fi obsolete_mkdir_used=false if test $dstdir_status != 0; then case $posix_mkdir in '') # Create intermediate dirs using mode 755 as modified by the umask. # This is like FreeBSD 'install' as of 1997-10-28. umask=`umask` case $stripcmd.$umask in # Optimize common cases. *[2367][2367]) mkdir_umask=$umask;; .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; *[0-7]) mkdir_umask=`expr $umask + 22 \ - $umask % 100 % 40 + $umask % 20 \ - $umask % 10 % 4 + $umask % 2 `;; *) mkdir_umask=$umask,go-w;; esac # With -d, create the new directory with the user-specified mode. # Otherwise, rely on $mkdir_umask. if test -n "$dir_arg"; then mkdir_mode=-m$mode else mkdir_mode= fi posix_mkdir=false case $umask in *[123567][0-7][0-7]) # POSIX mkdir -p sets u+wx bits regardless of umask, which # is incompatible with FreeBSD 'install' when (umask & 300) != 0. ;; *) tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 if (umask $mkdir_umask && exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 then if test -z "$dir_arg" || { # Check for POSIX incompatibilities with -m. # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or # other-writeable bit of parent directory when it shouldn't. # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. ls_ld_tmpdir=`ls -ld "$tmpdir"` case $ls_ld_tmpdir in d????-?r-*) different_mode=700;; d????-?--*) different_mode=755;; *) false;; esac && $mkdirprog -m$different_mode -p -- "$tmpdir" && { ls_ld_tmpdir_1=`ls -ld "$tmpdir"` test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" } } then posix_mkdir=: fi rmdir "$tmpdir/d" "$tmpdir" else # Remove any dirs left behind by ancient mkdir implementations. rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null fi trap '' 0;; esac;; esac if $posix_mkdir && ( umask $mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" ) then : else # The umask is ridiculous, or mkdir does not conform to POSIX, # or it failed possibly due to a race condition. Create the # directory the slow way, step by step, checking for races as we go. case $dstdir in /*) prefix='/';; -*) prefix='./';; *) prefix='';; esac eval "$initialize_posix_glob" oIFS=$IFS IFS=/ $posix_glob set -f set fnord $dstdir shift $posix_glob set +f IFS=$oIFS prefixes= for d do test -z "$d" && continue prefix=$prefix$d if test -d "$prefix"; then prefixes= else if $posix_mkdir; then (umask=$mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break # Don't fail if two instances are running concurrently. test -d "$prefix" || exit 1 else case $prefix in *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; *) qprefix=$prefix;; esac prefixes="$prefixes '$qprefix'" fi fi prefix=$prefix/ done if test -n "$prefixes"; then # Don't fail if two instances are running concurrently. (umask $mkdir_umask && eval "\$doit_exec \$mkdirprog $prefixes") || test -d "$dstdir" || exit 1 obsolete_mkdir_used=true fi fi fi if test -n "$dir_arg"; then { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 else # Make a couple of temp file names in the proper directory. dsttmp=$dstdir/_inst.$$_ rmtmp=$dstdir/_rm.$$_ # Trap to clean up those temp files at exit. trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 # Copy the file name to the temp name. (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && # and set any options; do chmod last to preserve setuid bits. # # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $cpprog $src $dsttmp" command. # { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && # If -C, don't bother to copy if it wouldn't change the file. if $copy_on_change && old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && eval "$initialize_posix_glob" && $posix_glob set -f && set X $old && old=:$2:$4:$5:$6 && set X $new && new=:$2:$4:$5:$6 && $posix_glob set +f && test "$old" = "$new" && $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 then rm -f "$dsttmp" else # Rename the file to the real destination. $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || # The rename failed, perhaps because mv can't rename something else # to itself, or perhaps because mv is so ancient that it does not # support -f. { # Now remove or move aside any old file at destination location. # We try this two ways since rm can't unlink itself on some # systems and the destination file might be busy for other # reasons. In this case, the final cleanup might fail but the new # file should still install successfully. { test ! -f "$dst" || $doit $rmcmd -f "$dst" 2>/dev/null || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } } || { echo "$0: cannot unlink or rename $dst" >&2 (exit 1); exit 1 } } && # Now rename the file to the real destination. $doit $mvcmd "$dsttmp" "$dst" } fi || exit 1 trap '' 0 fi done # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-end: "$" # End: hyena-0.5/Makefile.in0000644000175000001440000004731611453151000014645 0ustar00gabeusers00000000000000# Makefile.in generated by automake 1.10.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : subdir = . DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in $(top_srcdir)/configure COPYING NEWS \ install-sh missing ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/build/m4/shamrock/expansions.m4 \ $(top_srcdir)/build/m4/shamrock/mono.m4 \ $(top_srcdir)/build/m4/shamrock/programs.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ html-recursive info-recursive install-data-recursive \ install-dvi-recursive install-exec-recursive \ install-html-recursive install-info-recursive \ install-pdf-recursive install-ps-recursive install-recursive \ installcheck-recursive installdirs-recursive pdf-recursive \ ps-recursive uninstall-recursive RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) am__remove_distdir = \ { test ! -d $(distdir) \ || { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \ && rm -fr $(distdir); }; } DIST_ARCHIVES = $(distdir).tar.gz $(distdir).tar.bz2 GZIP_ENV = --best distuninstallcheck_listfiles = find . -type f -print distcleancheck_listfiles = find . -type f -print ACLOCAL = @ACLOCAL@ ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ GLIBSHARP_CFLAGS = @GLIBSHARP_CFLAGS@ GLIBSHARP_LIBS = @GLIBSHARP_LIBS@ GTKSHARP_A11Y_CFLAGS = @GTKSHARP_A11Y_CFLAGS@ GTKSHARP_A11Y_LIBS = @GTKSHARP_A11Y_LIBS@ GTKSHARP_CFLAGS = @GTKSHARP_CFLAGS@ GTKSHARP_LIBS = @GTKSHARP_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MCS = @MCS@ MKDIR_P = @MKDIR_P@ MONO = @MONO@ MONO_MODULE_CFLAGS = @MONO_MODULE_CFLAGS@ MONO_MODULE_LIBS = @MONO_MODULE_LIBS@ NUNIT_CFLAGS = @NUNIT_CFLAGS@ NUNIT_LIBS = @NUNIT_LIBS@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ am__leading_dot = @am__leading_dot@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ expanded_bindir = @expanded_bindir@ expanded_datadir = @expanded_datadir@ expanded_libdir = @expanded_libdir@ host_alias = @host_alias@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = \ build \ Hyena \ Mono.Data.Sqlite \ Hyena.Data.Sqlite \ Hyena.Gui @ENABLE_TESTS_TRUE@TEST_ASSEMBLIES = \ @ENABLE_TESTS_TRUE@ Hyena.dll \ @ENABLE_TESTS_TRUE@ Hyena.Data.Sqlite.dll \ @ENABLE_TESTS_TRUE@ Hyena.Gui.dll @ENABLE_TESTS_TRUE@ENV_OPTIONS = TZ=America/Chicago LC_ALL=it_IT LANG=it_IT @ENABLE_TESTS_TRUE@NUNIT_CONSOLE = $$(echo $$(which nunit-console2 || which nunit-console)) @ENABLE_TESTS_TRUE@RUNNER = for asm in $${TEST_ASSEMBLIES}; do echo -e "\033[1mRunning tests on $${asm}...\033[0m"; $(ENV_OPTIONS) $(NUNIT_CONSOLE) -nologo -noshadow $$asm; done MAINTAINERCLEANFILES = \ compile \ INSTALL \ config.h.in \ aclocal.m4 \ ltmain.sh \ Makefile.in \ depcomp \ missing \ install-sh \ configure \ config.sub \ config.guess \ intltool-extract.in \ intltool-merge.in \ intltool-update.in \ mkinstalldirs all: all-recursive .SUFFIXES: am--refresh: @: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ echo ' cd $(srcdir) && $(AUTOMAKE) --foreign '; \ cd $(srcdir) && $(AUTOMAKE) --foreign \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --foreign Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ echo ' $(SHELL) ./config.status'; \ $(SHELL) ./config.status;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(srcdir) && $(AUTOCONF) $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) # This directory's subdirectories are mostly independent; you can cd # into them and run `make' without going through this Makefile. # To change the values of `make' variables: instead of editing Makefiles, # (1) if the variable is set in `config.status', edit `config.status' # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. $(RECURSIVE_TARGETS): @failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" $(RECURSIVE_CLEAN_TARGETS): @failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) $(am__remove_distdir) test -d $(distdir) || mkdir $(distdir) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ distdir=`$(am__cd) $(distdir) && pwd`; \ top_distdir=`$(am__cd) $(top_distdir) && pwd`; \ (cd $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$top_distdir" \ distdir="$$distdir/$$subdir" \ am__remove_distdir=: \ am__skip_length_check=: \ distdir) \ || exit 1; \ fi; \ done -find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r $(distdir) dist-gzip: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__remove_distdir) dist-bzip2: distdir tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2 $(am__remove_distdir) dist-lzma: distdir tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma $(am__remove_distdir) dist-tarZ: distdir tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z $(am__remove_distdir) dist-shar: distdir shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz $(am__remove_distdir) dist-zip: distdir -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) $(am__remove_distdir) dist dist-all: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2 $(am__remove_distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another # tarfile. distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lzma*) \ unlzma -c $(distdir).tar.lzma | $(am__untar) ;;\ *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ esac chmod -R a-w $(distdir); chmod a+w $(distdir) mkdir $(distdir)/_build mkdir $(distdir)/_inst chmod a-w $(distdir) dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && cd $(distdir)/_build \ && ../configure --srcdir=.. --prefix="$$dc_install_base" \ $(DISTCHECK_CONFIGURE_FLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ && $(MAKE) $(AM_MAKEFLAGS) check \ && $(MAKE) $(AM_MAKEFLAGS) install \ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ && $(MAKE) $(AM_MAKEFLAGS) uninstall \ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ distuninstallcheck \ && chmod -R a-w "$$dc_install_base" \ && ({ \ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ } || { rm -rf "$$dc_destdir"; exit 1; }) \ && rm -rf "$$dc_destdir" \ && $(MAKE) $(AM_MAKEFLAGS) dist \ && rm -rf $(DIST_ARCHIVES) \ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck $(am__remove_distdir) @(echo "$(distdir) archives ready for distribution: "; \ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' distuninstallcheck: @cd $(distuninstallcheck_dir) \ && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \ || { echo "ERROR: files left after uninstall:" ; \ if test -n "$(DESTDIR)"; then \ echo " (check DESTDIR support)"; \ fi ; \ $(distuninstallcheck_listfiles) ; \ exit 1; } >&2 distcleancheck: distclean @if test '$(srcdir)' = . ; then \ echo "ERROR: distcleancheck can only run from a VPATH build" ; \ exit 1 ; \ fi @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left in build directory after distclean:" ; \ $(distcleancheck_listfiles) ; \ exit 1; } >&2 check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) clean: clean-recursive clean-am: clean-generic clean-local mostlyclean-am distclean: distclean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-exec-am: install-html: install-html-recursive install-info: install-info-recursive install-man: install-pdf: install-pdf-recursive install-ps: install-ps-recursive installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) install-am \ install-strip .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ all all-am am--refresh check check-am clean clean-generic \ clean-local ctags ctags-recursive dist dist-all dist-bzip2 \ dist-gzip dist-lzma dist-shar dist-tarZ dist-zip distcheck \ distclean distclean-generic distclean-tags distcleancheck \ distdir distuninstallcheck dvi dvi-am html html-am info \ info-am install install-am install-data install-data-am \ install-dvi install-dvi-am install-exec install-exec-am \ install-html install-html-am install-info install-info-am \ install-man install-pdf install-pdf-am install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ pdf-am ps ps-am tags tags-recursive uninstall uninstall-am clean-local: rm -rf $(top_builddir)/bin @ENABLE_TESTS_TRUE@test: @ENABLE_TESTS_TRUE@ @pushd bin &>/dev/null; \ @ENABLE_TESTS_TRUE@ export TEST_ASSEMBLIES="$(TEST_ASSEMBLIES)"; $(RUNNER); \ @ENABLE_TESTS_TRUE@ popd &>/dev/null; @ENABLE_TESTS_FALSE@test: @ENABLE_TESTS_FALSE@ echo "Tests not enabled. Pass --enable-tests to configure or ./autogen.sh" # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: hyena-0.5/build/0000777000175000001440000000000011453151001013671 5ustar00gabeusers00000000000000hyena-0.5/build/GObjectIntPtrCtorVerifier.cs0000644000175000001440000000207111377073562021242 0ustar00gabeusers00000000000000using System; using System.Reflection; public static class GObjectIntPtrCtorVerifier { public static void Main (string [] args) { foreach (var path in args) { Verify (path); } } private static void Verify (string path) { foreach (var type in Assembly.LoadFrom (path).GetTypes ()) { if (!type.IsSubclassOf (typeof (GLib.Object))) { continue; } bool safe = false; foreach (var ctor in type.GetConstructors (BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) { var args = ctor.GetParameters (); if ((safe = (ctor.Attributes & (MethodAttributes.Public | MethodAttributes.Family)) != 0 && args != null && args.Length == 1 && args[0].ParameterType == typeof (IntPtr))) { break; } } if (!safe) { Console.WriteLine (type); } } } } hyena-0.5/build/build.mk0000644000175000001440000000013511377073562015340 0ustar00gabeusers00000000000000include $(top_srcdir)/build/build.environment.mk include $(top_srcdir)/build/build.rules.mk hyena-0.5/build/DllMapVerifier.cs0000644000175000001440000002017611377073562017113 0ustar00gabeusers00000000000000using System; using System.IO; using System.Xml; using System.Text; using System.Collections.Generic; public static class DllMapVerifier { private struct DllImportRef { public DllImportRef (string name, int line, int column) { Name = name; Line = line; Column = column; } public string Name; public int Line; public int Column; } private static Dictionary> dll_imports = new Dictionary> (); private static List ignore_dlls = new List (); private static List config_dlls = null; public static int Main (string [] args) { LoadConfigDlls (args[0]); foreach (string file in args) { LoadDllImports (file); } return VerifyDllImports (args[0]) ? 0 : 1; } private static bool VerifyDllImports (string configFile) { int total_unmapped_count = 0; foreach (KeyValuePair> dll_import in dll_imports) { int file_unmapped_count = 0; foreach (DllImportRef dll_import_ref in dll_import.Value) { if (config_dlls != null && config_dlls.Contains (dll_import_ref.Name)) { continue; } if (file_unmapped_count++ == 0) { Console.Error.WriteLine ("Unmapped DLLs in file: {0}", dll_import.Key); } Console.Error.WriteLine (" + {0} : {1},{2}", dll_import_ref.Name, dll_import_ref.Line, dll_import_ref.Column); } total_unmapped_count += file_unmapped_count; } if (total_unmapped_count > 0) { Console.Error.WriteLine (); Console.Error.WriteLine (" If any DllImport above is explicitly allowed to be unmapped,"); Console.Error.WriteLine (" add an 'willfully unmapped' comment to the inside of the attribute:"); Console.Error.WriteLine (); Console.Error.WriteLine (" [DllImport (\"libX11.so.6\") /* willfully unmapped */]"); Console.Error.WriteLine (); } if (total_unmapped_count > 0 && config_dlls == null) { Console.Error.WriteLine ("No config file for DLL mapping was found ({0})", configFile); } return total_unmapped_count == 0; } private static void LoadDllImports (string csFile) { if (csFile.StartsWith ("-i")) { ignore_dlls.Add (csFile.Substring (2)); return; } if (Path.GetExtension (csFile) == ".cs" && File.Exists (csFile)) { List dll_import_refs = null; foreach (DllImportRef dll_import in ParseFileForDllImports (csFile)) { if (ignore_dlls.Contains (dll_import.Name)) { continue; } if (dll_import_refs == null) { dll_import_refs = new List (); } dll_import_refs.Add (dll_import); } if (dll_import_refs != null) { dll_imports.Add (csFile, dll_import_refs); } } } private static void LoadConfigDlls (string configFile) { try { XmlTextReader config = new XmlTextReader (configFile); config_dlls = new List (); while (config.Read ()) { if (config.NodeType == XmlNodeType.Element && config.Name == "dllmap") { string dll = config.GetAttribute ("dll"); if (!config_dlls.Contains (dll)) { config_dlls.Add (dll); } } } } catch { } } #region DllImport parser private static StreamReader reader; private static int reader_line; private static int reader_col; private static IEnumerable ParseFileForDllImports (string file) { reader_line = 1; reader_col = 1; using (reader = new StreamReader (file)) { char c; bool in_paren = false; bool in_attr = false; bool in_dll_attr = false; bool in_string = false; bool in_comment = false; int dll_line = 1, dll_col = 1; string dll_string = null; string dll_comment = null; while ((c = (char)reader.Peek ()) != Char.MaxValue) { switch (c) { case ' ': case '\t': Read (); break; case '[': in_attr = true; dll_string = null; dll_comment = null; dll_line = reader_line; dll_col = reader_col; Read (); break; case '(': Read (); in_paren = true; break; case ')': Read (); in_paren = false; break; case '"': Read (); if (dll_string == null && in_dll_attr && in_paren && !in_string) { in_string = true; } break; case '/': Read (); if ((char)reader.Peek () == '*') { Read (); if (in_dll_attr && !in_comment) { in_comment = true; } } break; case ']': if (in_dll_attr && dll_string != null && dll_comment != "willfully unmapped") { yield return new DllImportRef (dll_string, dll_line, dll_col); } in_attr = false; in_dll_attr = false; Read (); break; default: if (!in_dll_attr && in_attr && ReadDllAttribute ()) { in_dll_attr = true; } else if (in_dll_attr && in_string) { dll_string = ReadDllString (); in_string = false; } else if (in_dll_attr && in_comment) { dll_comment = ReadDllComment (); in_comment = false; } else { Read (); } break; } } } } private static bool ReadDllAttribute () { return Read () == 'D' && Read () == 'l' && Read () == 'l' && Read () == 'I' && Read () == 'm' && Read () == 'p' && Read () == 'o' && Read () == 'r' && Read () == 't'; } private static string ReadDllString () { StringBuilder builder = new StringBuilder (32); while (true) { char c = Read (); if (Char.IsLetterOrDigit (c) || c == '.' || c == '-' || c == '_') { builder.Append (c); } else { break; } } return builder.ToString (); } private static string ReadDllComment () { StringBuilder builder = new StringBuilder (); char lc = Char.MaxValue; while (true) { char c = Read (); if (c == Char.MaxValue || (c == '/' && lc == '*')) { break; } else if (lc != Char.MaxValue) { builder.Append (lc); } lc = c; } return builder.ToString ().Trim (); } private static char Read () { char c = (char)reader.Read (); if (c == '\n') { reader_line++; reader_col = 1; } else { reader_col++; } return c; } #endregion } hyena-0.5/build/Makefile.in0000644000175000001440000004122411453150777015760 0ustar00gabeusers00000000000000# Makefile.in generated by automake 1.10.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : @GCONF_SCHEMAS_INSTALL_TRUE@am__append_1 = $(GCONF_SCHEMA_EXTRACTOR_ASSEMBLY) subdir = build DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/build/m4/shamrock/expansions.m4 \ $(top_srcdir)/build/m4/shamrock/mono.m4 \ $(top_srcdir)/build/m4/shamrock/programs.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = am__installdirs = "$(DESTDIR)$(bansheedir)" bansheeSCRIPT_INSTALL = $(INSTALL_SCRIPT) SCRIPTS = $(banshee_SCRIPTS) SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ html-recursive info-recursive install-data-recursive \ install-dvi-recursive install-exec-recursive \ install-html-recursive install-info-recursive \ install-pdf-recursive install-ps-recursive install-recursive \ installcheck-recursive installdirs-recursive pdf-recursive \ ps-recursive uninstall-recursive RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ GLIBSHARP_CFLAGS = @GLIBSHARP_CFLAGS@ GLIBSHARP_LIBS = @GLIBSHARP_LIBS@ GTKSHARP_A11Y_CFLAGS = @GTKSHARP_A11Y_CFLAGS@ GTKSHARP_A11Y_LIBS = @GTKSHARP_A11Y_LIBS@ GTKSHARP_CFLAGS = @GTKSHARP_CFLAGS@ GTKSHARP_LIBS = @GTKSHARP_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MCS = @MCS@ MKDIR_P = @MKDIR_P@ MONO = @MONO@ MONO_MODULE_CFLAGS = @MONO_MODULE_CFLAGS@ MONO_MODULE_LIBS = @MONO_MODULE_LIBS@ NUNIT_CFLAGS = @NUNIT_CFLAGS@ NUNIT_LIBS = @NUNIT_LIBS@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ am__leading_dot = @am__leading_dot@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ expanded_bindir = @expanded_bindir@ expanded_datadir = @expanded_datadir@ expanded_libdir = @expanded_libdir@ host_alias = @host_alias@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = m4 pkg-config GCONF_SCHEMA_EXTRACTOR_ASSEMBLY = gconf-schema-extractor.exe TRANSLATOR_EXTRACTOR_ASSEMBLY = translator-extractor.exe DLL_MAP_VERIFIER_ASSEMBLY = dll-map-verifier.exe ADDIN_XML_STRING_EXTRACTOR_ASSEMBLY = addin-xml-string-extractor.exe GOBJECT_INTPTR_CTOR_VERIFIER_ASSEMBLY = gobject-intptr-ctor-verifier.exe ALL_TARGETS = $(DLL_MAP_VERIFIER_ASSEMBLY) \ $(ADDIN_XML_STRING_EXTRACTOR_ASSEMBLY) \ $(GOBJECT_INTPTR_CTOR_VERIFIER_ASSEMBLY) $(am__append_1) #ALL_TARGETS += $(TRANSLATOR_EXTRACTOR_ASSEMBLY) @GCONF_SCHEMAS_INSTALL_TRUE@bansheedir = $(pkglibdir) @GCONF_SCHEMAS_INSTALL_TRUE@banshee_SCRIPTS = $(GCONF_SCHEMA_EXTRACTOR_ASSEMBLY) EXTRA_DIST = \ icon-theme-installer \ private-icon-theme-installer \ GConfSchemaExtractor.cs \ TranslatorExtractor.cs \ DllMapVerifier.cs \ AddinXmlStringExtractor.cs \ GObjectIntPtrCtorVerifier.cs \ dll-map-makefile-verifier \ gconf-schema-rules CLEANFILES = *.exe *.mdb MAINTAINERCLEANFILES = Makefile.in all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign build/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --foreign build/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh install-bansheeSCRIPTS: $(banshee_SCRIPTS) @$(NORMAL_INSTALL) test -z "$(bansheedir)" || $(MKDIR_P) "$(DESTDIR)$(bansheedir)" @list='$(banshee_SCRIPTS)'; for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ if test -f $$d$$p; then \ f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \ echo " $(bansheeSCRIPT_INSTALL) '$$d$$p' '$(DESTDIR)$(bansheedir)/$$f'"; \ $(bansheeSCRIPT_INSTALL) "$$d$$p" "$(DESTDIR)$(bansheedir)/$$f"; \ else :; fi; \ done uninstall-bansheeSCRIPTS: @$(NORMAL_UNINSTALL) @list='$(banshee_SCRIPTS)'; for p in $$list; do \ f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \ echo " rm -f '$(DESTDIR)$(bansheedir)/$$f'"; \ rm -f "$(DESTDIR)$(bansheedir)/$$f"; \ done # This directory's subdirectories are mostly independent; you can cd # into them and run `make' without going through this Makefile. # To change the values of `make' variables: instead of editing Makefiles, # (1) if the variable is set in `config.status', edit `config.status' # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. $(RECURSIVE_TARGETS): @failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" $(RECURSIVE_CLEAN_TARGETS): @failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ distdir=`$(am__cd) $(distdir) && pwd`; \ top_distdir=`$(am__cd) $(top_distdir) && pwd`; \ (cd $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$top_distdir" \ distdir="$$distdir/$$subdir" \ am__remove_distdir=: \ am__skip_length_check=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile $(SCRIPTS) installdirs: installdirs-recursive installdirs-am: for dir in "$(DESTDIR)$(bansheedir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) clean: clean-recursive clean-am: clean-generic mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive info: info-recursive info-am: install-data-am: install-bansheeSCRIPTS install-dvi: install-dvi-recursive install-exec-am: install-html: install-html-recursive install-info: install-info-recursive install-man: install-pdf: install-pdf-recursive install-ps: install-ps-recursive installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-bansheeSCRIPTS .MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) install-am \ install-strip .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ all all-am check check-am clean clean-generic ctags \ ctags-recursive distclean distclean-generic distclean-tags \ distdir dvi dvi-am html html-am info info-am install \ install-am install-bansheeSCRIPTS install-data install-data-am \ install-dvi install-dvi-am install-exec install-exec-am \ install-html install-html-am install-info install-info-am \ install-man install-pdf install-pdf-am install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ pdf-am ps ps-am tags tags-recursive uninstall uninstall-am \ uninstall-bansheeSCRIPTS @GCONF_SCHEMAS_INSTALL_TRUE@$(GCONF_SCHEMA_EXTRACTOR_ASSEMBLY): GConfSchemaExtractor.cs @GCONF_SCHEMAS_INSTALL_TRUE@ $(MCS) -out:$@ $< all: $(ALL_TARGETS) # $(TRANSLATOR_EXTRACTOR_ASSEMBLY): TranslatorExtractor.cs # if [ "x$(top_srcdir)" = "x$(top_builddir)" ]; then \ # $(MCS) -out:$@ $< && LC_ALL=en_US.UTF-8 $(MONO) $@ $(top_builddir)/po > \ # $(top_srcdir)/src/Core/Banshee.Core/Resources/translators.xml; \ # fi; $(DLL_MAP_VERIFIER_ASSEMBLY): DllMapVerifier.cs $(MCS) -out:$@ $< $(ADDIN_XML_STRING_EXTRACTOR_ASSEMBLY): AddinXmlStringExtractor.cs $(MCS) -r:System.Xml -out:$@ $< $(GOBJECT_INTPTR_CTOR_VERIFIER_ASSEMBLY): GObjectIntPtrCtorVerifier.cs $(MCS) $(GLIBSHARP_LIBS) -out:$@ $< # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: hyena-0.5/build/icon-theme-installer0000755000175000001440000001217511377073562017670 0ustar00gabeusers00000000000000#!/usr/bin/env bash # icon-theme-installer # Copyright (C) 2006 Novell, Inc. # Written by Aaron Bockover # Licensed under the MIT/X11 license # # This script is meant to be invoked from within a Makefile/Makefile.am # in the install-data-local and uninstall-data sections. It handles the # task of properly installing icons into the icon theme. It requires a # few arguments to set up its environment, and a list of files to be # installed. The format of the file list is critical: # # , # # apps,music-player-banshee.svg # apps,music-player-banshee-16.png # apps,music-player-banshee-22.png # # is the icon theme category, for instance, apps, devices, # actions, emblems... # # must have a basename in the form of: # # proper-theme-name[-]. # # Where should be either nothing, which will default to scalable # or \-[0-9]{2}, which will expand to x. For example: # # music-player-banshee-16.png # # The here is -16 and will expand to 16x16 per the icon theme spec # # What follows is an example Makefile.am for icon theme installation: # # --------------- # theme=hicolor # themedir=$(datadir)/icons/$(theme) # theme_icons = \ # apps,music-player-banshee.svg \ # apps,music-player-banshee-16.png \ # apps,music-player-banshee-22.png \ # apps,music-player-banshee-24.png \ # apps,music-player-banshee-32.png # # install_icon_exec = $(top_srcdir)/build/icon-theme-installer -t $(theme) -s $(srcdir) -d "x$(DESTDIR)" -b $(themedir) -m "$(mkinstalldirs)" -x "$(INSTALL_DATA)" # install-data-local: # $(install_icon_exec) -i $(theme_icons) # # uninstall-hook: # $(install_icon_exec) -u $(theme_icons) # # MAINTAINERCLEANFILES = Makefile.in # EXTRA_DIST = $(wildcard *.svg *.png) # --------------- # # Arguments to this program: # # -i : Install # -u : Uninstall # -t : Theme name (hicolor) # -b : Theme installation dest directory [x$(DESTDIR)] - Always prefix # this argument with x; it will be stripped but will act as a # placeholder for zero $DESTDIRs (only set by packagers) # -d : Theme installation directory [$(hicolordir)] # -s : Source directory [$(srcdir)] # -m : Command to exec for directory creation [$(mkinstalldirs)] # -x : Command to exec for single file installation [$(INSTALL_DATA)] # : All remainging should be category,filename pairs while getopts "iut:b:d:s:m:x:" flag; do case "$flag" in i) INSTALL=yes ;; u) UNINSTALL=yes ;; t) THEME_NAME=$OPTARG ;; d) INSTALL_DEST_DIR=${OPTARG##x} ;; b) INSTALL_BASE_DIR=$OPTARG ;; s) SRC_DIR=$OPTARG ;; m) MKINSTALLDIRS_EXEC=$OPTARG ;; x) INSTALL_DATA_EXEC=$OPTARG ;; esac done shift $(($OPTIND - 1)) if test "x$INSTALL" = "xyes" -a "x$UNINSTALL" = "xyes"; then echo "Cannot pass both -i and -u" exit 1 elif test "x$INSTALL" = "x" -a "x$UNINSTALL" = "x"; then echo "Must path either -i or -u" exit 1 fi if test -z "$THEME_NAME"; then echo "Theme name required (-t hicolor)" exit 1 fi if test -z "$INSTALL_BASE_DIR"; then echo "Base theme directory required [-d \$(hicolordir)]" exit 1 fi if test ! -x $(echo "$MKINSTALLDIRS_EXEC" | cut -f1 -d' '); then echo "Cannot find '$MKINSTALLDIRS_EXEC'; You probably want to pass -m \$(mkinstalldirs)" exit 1 fi if test ! -x $(echo "$INSTALL_DATA_EXEC" | cut -f1 -d' '); then echo "Cannot find '$INSTALL_DATA_EXEC'; You probably want to pass -x \$(INSTALL_DATA)" exit 1 fi if test -z "$SRC_DIR"; then SRC_DIR=. fi for icon in $@; do size=$(echo $icon | sed s/[^0-9]*//g) category=$(echo $icon | cut -d, -f1) build_name=$(echo $icon | cut -d, -f2) install_name=$(echo $build_name | sed "s/[0-9]//g; s/-\././") install_name=$(basename $install_name) if test -z $size; then size=scalable; else size=${size}x${size}; fi install_dir=${INSTALL_DEST_DIR}${INSTALL_BASE_DIR}/$size/$category install_path=$install_dir/$install_name if test "x$INSTALL" = "xyes"; then echo "Installing $size $install_name into $THEME_NAME icon theme" $($MKINSTALLDIRS_EXEC $install_dir) || { echo "Failed to create directory $install_dir" exit 1 } $($INSTALL_DATA_EXEC $SRC_DIR/$build_name $install_path) || { echo "Failed to install $SRC_DIR/$build_name into $install_path" exit 1 } if test ! -e $install_path; then echo "Failed to install $SRC_DIR/$build_name into $install_path" exit 1 fi else if test -e $install_path; then echo "Removing $size $install_name from $THEME_NAME icon theme" rm $install_path || { echo "Failed to remove $install_path" exit 1 } fi fi done gtk_update_icon_cache_bin="$((which gtk-update-icon-cache || echo /opt/gnome/bin/gtk-update-icon-cache)2>/dev/null)" gtk_update_icon_cache="$gtk_update_icon_cache_bin -f -t $INSTALL_BASE_DIR" if test -z "$INSTALL_DEST_DIR"; then if test -x $gtk_update_icon_cache_bin; then echo "Updating GTK icon cache" $gtk_update_icon_cache else echo "*** Icon cache not updated. Could not execute $gtk_update_icon_cache_bin" fi else echo "*** Icon cache not updated. After (un)install, run this:" echo "*** $gtk_update_icon_cache" fi hyena-0.5/build/build.rules.mk0000644000175000001440000000602511416414453016465 0ustar00gabeusers00000000000000UNIQUE_FILTER_PIPE = tr [:space:] \\n | sort | uniq BUILD_DATA_DIR = $(top_builddir)/bin/share/$(PACKAGE) SOURCES_BUILD = $(addprefix $(srcdir)/, $(SOURCES)) dnl SOURCES_BUILD += $(top_srcdir)/src/AssemblyInfo.cs RESOURCES_EXPANDED = $(addprefix $(srcdir)/, $(RESOURCES)) RESOURCES_BUILD = $(foreach resource, $(RESOURCES_EXPANDED), \ -resource:$(resource),$(notdir $(resource))) INSTALL_ICONS = $(top_srcdir)/build/private-icon-theme-installer "$(mkinstalldirs)" "$(INSTALL_DATA)" THEME_ICONS_SOURCE = $(wildcard $(srcdir)/ThemeIcons/*/*/*.png) $(wildcard $(srcdir)/ThemeIcons/scalable/*/*.svg) THEME_ICONS_RELATIVE = $(subst $(srcdir)/ThemeIcons/, , $(THEME_ICONS_SOURCE)) ASSEMBLY_EXTENSION = $(strip $(patsubst library, dll, $(TARGET))) ASSEMBLY_FILE = $(top_builddir)/bin/$(ASSEMBLY).$(ASSEMBLY_EXTENSION) INSTALL_DIR_RESOLVED = $(firstword $(subst , $(DEFAULT_INSTALL_DIR), $(INSTALL_DIR))) if ENABLE_TESTS LINK += " $(NUNIT_LIBS)" ENABLE_TESTS_FLAG = "-define:ENABLE_TESTS" endif if ENABLE_ATK ENABLE_ATK_FLAG = "-define:ENABLE_ATK" endif FILTERED_LINK = $(shell echo "$(LINK)" | $(UNIQUE_FILTER_PIPE)) DEP_LINK = $(shell echo "$(LINK)" | $(UNIQUE_FILTER_PIPE) | sed s,-r:,,g | grep '$(top_builddir)/bin/') OUTPUT_FILES = \ $(ASSEMBLY_FILE) \ $(ASSEMBLY_FILE).mdb moduledir = $(INSTALL_DIR_RESOLVED) module_SCRIPTS = $(OUTPUT_FILES) all: $(ASSEMBLY_FILE) theme-icons run: @pushd $(top_builddir); \ make run; \ popd; test: @pushd $(top_builddir)/tests; \ make $(ASSEMBLY); \ popd; build-debug: @echo $(DEP_LINK) $(ASSEMBLY_FILE).mdb: $(ASSEMBLY_FILE) $(ASSEMBLY_FILE): $(SOURCES_BUILD) $(RESOURCES_EXPANDED) $(DEP_LINK) @mkdir -p $(top_builddir)/bin @if [ ! "x$(ENABLE_RELEASE)" = "xyes" ]; then \ $(top_srcdir)/build/dll-map-makefile-verifier $(srcdir)/Makefile.am $(srcdir)/$(notdir $@.config) && \ $(MONO) $(top_builddir)/build/dll-map-verifier.exe $(srcdir)/$(notdir $@.config) -iwinmm -ilibbanshee -ilibbnpx11 -ilibc -ilibc.so.6 -iintl -ilibmtp.dll -ilibigemacintegration.dylib -iCFRelease $(SOURCES_BUILD); \ fi; $(MCS) \ $(GMCS_FLAGS) \ $(ASSEMBLY_BUILD_FLAGS) \ -nowarn:0278 -nowarn:0078 $$warn \ -define:HAVE_GTK_2_10 -define:NET_2_0 \ -debug -target:$(TARGET) -out:$@ \ $(BUILD_DEFINES) $(ENABLE_TESTS_FLAG) $(ENABLE_ATK_FLAG) \ $(FILTERED_LINK) $(RESOURCES_BUILD) $(SOURCES_BUILD) @if [ -e $(srcdir)/$(notdir $@.config) ]; then \ cp $(srcdir)/$(notdir $@.config) $(top_builddir)/bin; \ fi; @if [ ! -z "$(EXTRA_BUNDLE)" ]; then \ cp $(EXTRA_BUNDLE) $(top_builddir)/bin; \ fi; theme-icons: $(THEME_ICONS_SOURCE) @$(INSTALL_ICONS) -il "$(BUILD_DATA_DIR)" "$(srcdir)" $(THEME_ICONS_RELATIVE) install-data-local: $(THEME_ICONS_SOURCE) @$(INSTALL_ICONS) -i "$(DESTDIR)$(pkgdatadir)" "$(srcdir)" $(THEME_ICONS_RELATIVE) uninstall-local: $(THEME_ICONS_SOURCE) @$(INSTALL_ICONS) -u "$(DESTDIR)$(pkgdatadir)" "$(srcdir)" $(THEME_ICONS_RELATIVE) EXTRA_DIST = $(SOURCES_BUILD) $(RESOURCES_EXPANDED) $(THEME_ICONS_SOURCE) CLEANFILES = $(OUTPUT_FILES) DISTCLEANFILES = *.pidb MAINTAINERCLEANFILES = Makefile.in hyena-0.5/build/pkg-config/0000777000175000001440000000000011453151001015715 5ustar00gabeusers00000000000000hyena-0.5/build/pkg-config/Makefile.in0000644000175000001440000002417011453151000017761 0ustar00gabeusers00000000000000# Makefile.in generated by automake 1.10.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : subdir = build/pkg-config DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/build/m4/shamrock/expansions.m4 \ $(top_srcdir)/build/m4/shamrock/mono.m4 \ $(top_srcdir)/build/m4/shamrock/programs.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = SOURCES = DIST_SOURCES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = `echo $$p | sed -e 's|^.*/||'`; am__installdirs = "$(DESTDIR)$(pkgconfigdir)" pkgconfigDATA_INSTALL = $(INSTALL_DATA) DATA = $(pkgconfig_DATA) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ GLIBSHARP_CFLAGS = @GLIBSHARP_CFLAGS@ GLIBSHARP_LIBS = @GLIBSHARP_LIBS@ GTKSHARP_A11Y_CFLAGS = @GTKSHARP_A11Y_CFLAGS@ GTKSHARP_A11Y_LIBS = @GTKSHARP_A11Y_LIBS@ GTKSHARP_CFLAGS = @GTKSHARP_CFLAGS@ GTKSHARP_LIBS = @GTKSHARP_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MCS = @MCS@ MKDIR_P = @MKDIR_P@ MONO = @MONO@ MONO_MODULE_CFLAGS = @MONO_MODULE_CFLAGS@ MONO_MODULE_LIBS = @MONO_MODULE_LIBS@ NUNIT_CFLAGS = @NUNIT_CFLAGS@ NUNIT_LIBS = @NUNIT_LIBS@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ am__leading_dot = @am__leading_dot@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ expanded_bindir = @expanded_bindir@ expanded_datadir = @expanded_datadir@ expanded_libdir = @expanded_libdir@ host_alias = @host_alias@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ @HYENA_PKG_CONFIG_TRUE@pkgconfigdir = $(libdir)/pkgconfig @HYENA_PKG_CONFIG_TRUE@pkgconfig_in_files = $(wildcard hyena*.pc.in) @HYENA_PKG_CONFIG_TRUE@pkgconfig_DATA = $(pkgconfig_in_files:.pc.in=.pc) @HYENA_PKG_CONFIG_TRUE@EXTRA_DIST = $(pkgconfig_in_files) @HYENA_PKG_CONFIG_TRUE@CLEANFILES = $(pkgconfig_DATA) @HYENA_PKG_CONFIG_TRUE@MAINTAINERCLEANFILES = Makefile.in all: all-am .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign build/pkg-config/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --foreign build/pkg-config/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh install-pkgconfigDATA: $(pkgconfig_DATA) @$(NORMAL_INSTALL) test -z "$(pkgconfigdir)" || $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" @list='$(pkgconfig_DATA)'; for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ f=$(am__strip_dir) \ echo " $(pkgconfigDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(pkgconfigdir)/$$f'"; \ $(pkgconfigDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(pkgconfigdir)/$$f"; \ done uninstall-pkgconfigDATA: @$(NORMAL_UNINSTALL) @list='$(pkgconfig_DATA)'; for p in $$list; do \ f=$(am__strip_dir) \ echo " rm -f '$(DESTDIR)$(pkgconfigdir)/$$f'"; \ rm -f "$(DESTDIR)$(pkgconfigdir)/$$f"; \ done tags: TAGS TAGS: ctags: CTAGS CTAGS: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(DATA) installdirs: for dir in "$(DESTDIR)$(pkgconfigdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) clean: clean-am clean-am: clean-generic mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am info: info-am info-am: install-data-am: install-pkgconfigDATA install-dvi: install-dvi-am install-exec-am: install-html: install-html-am install-info: install-info-am install-man: install-pdf: install-pdf-am install-ps: install-ps-am installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-pkgconfigDATA .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic distclean \ distclean-generic distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-pkgconfigDATA install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic pdf pdf-am ps ps-am uninstall \ uninstall-am uninstall-pkgconfigDATA @HYENA_PKG_CONFIG_TRUE@%.pc: %.pc.in @HYENA_PKG_CONFIG_TRUE@ sed "s,\@VERSION\@,$(VERSION),g; s,\@prefix\@,$(prefix),g; s,\@libdir\@,$(libdir),g; s,\@PACKAGE\@,$(PACKAGE),g" < $< > $@ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: hyena-0.5/build/pkg-config/hyena.data.sqlite.pc.in0000644000175000001440000000062611416420067022174 0ustar00gabeusers00000000000000prefix=@prefix@ libdir=@libdir@ Assemblies=${libdir}/@PACKAGE@/Hyena.Data.Sqlite.dll ${libdir}/@PACKAGE@/Mono.Data.Sqlite.dll Files=${libdir}/@PACKAGE@/Hyena.Data.Sqlite.dll.mdb ${libdir}/@PACKAGE@/Mono.Data.Sqlite.dll.mdb Name: Hyena.Data.Sqlite Description: Hyena.Data.Sqlite Version: @VERSION@ Requires: Libs: -r:${libdir}/@PACKAGE@/Hyena.Data.Sqlite.dll -r:${libdir}/@PACKAGE@/Mono.Data.Sqlite.dll hyena-0.5/build/pkg-config/hyena.gui.pc.in0000644000175000001440000000042511416420067020544 0ustar00gabeusers00000000000000prefix=@prefix@ libdir=@libdir@ Assemblies=${libdir}/@PACKAGE@/Hyena.Gui.dll Files=${libdir}/@PACKAGE@/Hyena.Gui.dll.config ${libdir}/@PACKAGE@/Hyena.Gui.dll.mdb Name: Hyena.Gui Description: Hyena.Gui Version: @VERSION@ Requires: Libs: -r:${libdir}/@PACKAGE@/Hyena.Gui.dll hyena-0.5/build/pkg-config/Makefile.am0000644000175000001440000000061711417122630017757 0ustar00gabeusers00000000000000if HYENA_PKG_CONFIG pkgconfigdir = $(libdir)/pkgconfig pkgconfig_in_files = $(wildcard hyena*.pc.in) pkgconfig_DATA = $(pkgconfig_in_files:.pc.in=.pc) %.pc: %.pc.in sed "s,\@VERSION\@,$(VERSION),g; s,\@prefix\@,$(prefix),g; s,\@libdir\@,$(libdir),g; s,\@PACKAGE\@,$(PACKAGE),g" < $< > $@ EXTRA_DIST = $(pkgconfig_in_files) CLEANFILES = $(pkgconfig_DATA) MAINTAINERCLEANFILES = Makefile.in endif hyena-0.5/build/pkg-config/hyena.pc.in0000644000175000001440000000037511452701564017771 0ustar00gabeusers00000000000000prefix=@prefix@ libdir=@libdir@ Assemblies=${libdir}/@PACKAGE@/Hyena.dll Files=${libdir}/@PACKAGE@/Hyena.dll.config ${libdir}/@PACKAGE@/Hyena.dll.mdb Name: Hyena Description: Hyena Version: @VERSION@ Requires: Libs: -r:${libdir}/@PACKAGE@/Hyena.dll hyena-0.5/build/dll-map-makefile-verifier0000755000175000001440000000040511377073562020550 0ustar00gabeusers00000000000000#!/usr/bin/env bash if [ -f $2 ]; then # Lame, but better than nothing grep $(basename $2) $1 | grep module_SCRIPTS &>/dev/null || { echo "Assembly has corresponding .config file, but it was not found in module_SCRIPTS in Makefile.am" 2>&1 exit 1 } fi hyena-0.5/build/TranslatorExtractor.cs0000644000175000001440000001104111377073562020262 0ustar00gabeusers00000000000000// // Licensed under same license as Banshee // Copyright (C) 2006 Novell, Inc. // Written by Aaron Bockover // // This tool extracts translator information from .po files // to generate information for display in the about dialog // using System; using System.IO; using System.Collections.Generic; using System.Text.RegularExpressions; public class TranslatorExtractor { public static void Main(string [] args) { Console.WriteLine(""); Console.WriteLine(""); Console.WriteLine(""); foreach(string filename in Directory.GetFiles(args.Length == 0 ? "." : args[0], "*.po")) { using(FileStream stream = new FileStream(filename, FileMode.Open, FileAccess.Read)) { using(StreamReader reader = new StreamReader(stream)) { ParseFile(filename, reader); } } } Console.WriteLine(""); } private static void ParseFile(string file, TextReader reader) { Dictionary names = new Dictionary(); string language_code = Path.GetFileNameWithoutExtension(file); string language_name = null; bool past_plural_forms = false; while(true) { string line = reader.ReadLine(); if(line == null || (line.StartsWith("#:") && past_plural_forms)) { break; } else if(line.StartsWith("\"Plural-Forms:")) { past_plural_forms = true; } try { Match match = Regex.Match(line, ".*#(.*)<(.*)>(.*,.*|[ \n]*$)"); if(!match.Success) { match = Regex.Match(line, ".*\\\"Last-Translator:(.*)<(.*)>.*"); if(!match.Success) { match = Regex.Match(line, ".*\\\"Language-Team:(.*)<.*>.*"); if(!match.Success) { continue; } language_name = match.Groups[1].Value.Trim(); int pos = language_name.IndexOf('('); if(pos > 0) { language_name = language_name.Substring(0, pos).Trim(); } pos = language_name.IndexOf("GNOME"); if(pos > 0) { language_name = language_name.Substring(0, pos).Trim(); } } } string name = match.Groups[1].Value.Trim(); string email = match.Groups[2].Value.Trim(); if(name == String.Empty || email == String.Empty || name == "FIRST AUTHOR") { continue; } else if(name.StartsWith("Maintainer:")) { name = name.Substring(11).Trim(); } if(!names.ContainsKey(email)) { bool skip = false; foreach(string iter_name in names.Values) { if(String.Compare(iter_name, name, true) == 0) { skip = true; break; } } if(!skip) { names.Add(email, name); } } } catch { continue; } } // hack for banshee, remove if used elsewhere if(language_code == "sr") { return; } else if(language_code == "sr@latin") { language_code = "sr"; } // end special // override language names from extracted switch(language_code) { case "ca": language_name = "Catalan"; break; case "zh_CN": language_name = "Simplified Chinese"; break; case "es": language_name = "Spanish"; break; case "fr": language_name = "French"; break; default: break; } Console.WriteLine(" ", language_code, language_name); List sorted_names = new List (names.Values); sorted_names.Sort (); foreach(string name in sorted_names) { Console.WriteLine(" {0}", name.Replace("\"", """)); } Console.WriteLine(" "); } } hyena-0.5/build/build.environment.mk0000644000175000001440000000034211377073562017703 0ustar00gabeusers00000000000000# Initializers MONO_BASE_PATH = MONO_ADDINS_PATH = # Install Paths DEFAULT_INSTALL_DIR = $(pkglibdir) DIR_BIN = $(top_builddir)/bin # Cute hack to replace a space with something colon:= : empty:= space:= $(empty) $(empty) hyena-0.5/build/Makefile.am0000644000175000001440000000314011436010340015720 0ustar00gabeusers00000000000000SUBDIRS = m4 pkg-config GCONF_SCHEMA_EXTRACTOR_ASSEMBLY = gconf-schema-extractor.exe TRANSLATOR_EXTRACTOR_ASSEMBLY = translator-extractor.exe DLL_MAP_VERIFIER_ASSEMBLY = dll-map-verifier.exe ADDIN_XML_STRING_EXTRACTOR_ASSEMBLY = addin-xml-string-extractor.exe GOBJECT_INTPTR_CTOR_VERIFIER_ASSEMBLY = gobject-intptr-ctor-verifier.exe ALL_TARGETS = $(DLL_MAP_VERIFIER_ASSEMBLY) $(ADDIN_XML_STRING_EXTRACTOR_ASSEMBLY) $(GOBJECT_INTPTR_CTOR_VERIFIER_ASSEMBLY) #ALL_TARGETS += $(TRANSLATOR_EXTRACTOR_ASSEMBLY) if GCONF_SCHEMAS_INSTALL bansheedir = $(pkglibdir) banshee_SCRIPTS = $(GCONF_SCHEMA_EXTRACTOR_ASSEMBLY) ALL_TARGETS += $(GCONF_SCHEMA_EXTRACTOR_ASSEMBLY) $(GCONF_SCHEMA_EXTRACTOR_ASSEMBLY): GConfSchemaExtractor.cs $(MCS) -out:$@ $< endif all: $(ALL_TARGETS) # $(TRANSLATOR_EXTRACTOR_ASSEMBLY): TranslatorExtractor.cs # if [ "x$(top_srcdir)" = "x$(top_builddir)" ]; then \ # $(MCS) -out:$@ $< && LC_ALL=en_US.UTF-8 $(MONO) $@ $(top_builddir)/po > \ # $(top_srcdir)/src/Core/Banshee.Core/Resources/translators.xml; \ # fi; $(DLL_MAP_VERIFIER_ASSEMBLY): DllMapVerifier.cs $(MCS) -out:$@ $< $(ADDIN_XML_STRING_EXTRACTOR_ASSEMBLY): AddinXmlStringExtractor.cs $(MCS) -r:System.Xml -out:$@ $< $(GOBJECT_INTPTR_CTOR_VERIFIER_ASSEMBLY): GObjectIntPtrCtorVerifier.cs $(MCS) $(GLIBSHARP_LIBS) -out:$@ $< EXTRA_DIST = \ icon-theme-installer \ private-icon-theme-installer \ GConfSchemaExtractor.cs \ TranslatorExtractor.cs \ DllMapVerifier.cs \ AddinXmlStringExtractor.cs \ GObjectIntPtrCtorVerifier.cs \ dll-map-makefile-verifier \ gconf-schema-rules CLEANFILES = *.exe *.mdb MAINTAINERCLEANFILES = Makefile.in hyena-0.5/build/GConfSchemaExtractor.cs0000644000175000001440000001275611377073562020264 0ustar00gabeusers00000000000000using System; using System.IO; using System.Text; using System.Text.RegularExpressions; using System.Collections.Generic; using System.Reflection; public class GConfSchemaExtractor { private static Dictionary entries = new Dictionary(); private static int schema_count = 0; public static void Main(string [] args) { Assembly asm = Assembly.LoadFrom(args[0]); foreach(Type type in asm.GetTypes()) { foreach(FieldInfo field in type.GetFields()) { if(field.FieldType.IsGenericType && field.FieldType.GetGenericTypeDefinition().Name.StartsWith("SchemaEntry")) { if(field.Name == "Zero") { continue; } object schema = field.GetValue(null); AddSchemaEntry(schema.GetType().GetField("DefaultValue").GetValue(schema), GetString(schema, "Namespace"), GetString(schema, "Key"), GetString(schema, "ShortDescription"), GetString(schema, "LongDescription") ); } } } if(schema_count > 0) { StringBuilder final = new StringBuilder(); final.Append("\n"); final.Append("\n"); final.Append(" \n"); List keys = new List(entries.Keys); keys.Sort(); foreach(string key in keys) { final.Append(entries[key]); } final.Append(" \n"); final.Append("\n"); using(StreamWriter writer = new StreamWriter(args[1])) { writer.Write(final.ToString()); } } } private static string GetString(object o, string name) { FieldInfo field = o.GetType().GetField(name); return (string)field.GetValue(o); } private static string GetValueString(Type type, object o, out string gctype) { if(type == typeof(bool)) { gctype = "bool"; return o == null ? null : o.ToString().ToLower(); } else if(type == typeof(int)) { gctype = "int"; } else if(type == typeof(float) || type == typeof(double)) { gctype = "float"; } else if(type == typeof(string)) { gctype = "string"; } else { throw new Exception("Unsupported type '" + type + "'"); } return o == null ? null : o.ToString(); } private static void AddSchemaEntry(object value, string namespce, string key, string short_desc, string long_desc) { schema_count++; string full_key = CreateKey(namespce, key); bool list = value.GetType().IsArray; Type type = list ? Type.GetTypeArray((object [])value)[0] : value.GetType(); string str_val = null; string str_type = null; if(list) { if(value == null || ((object [])value).Length == 0) { GetValueString(type, null, out str_type); str_val = "[]"; } else { str_val = "["; object [] arr = (object [])value; for(int i = 0; i < arr.Length; i++) { str_val += GetValueString(type, arr[i], out str_type).Replace(",", "\\,"); if(i < arr.Length - 1) { str_val += ","; } } str_val += "]"; } } else { str_val = GetValueString(type, value, out str_type); } StringBuilder builder = new StringBuilder(); builder.AppendFormat(" \n"); builder.AppendFormat(" /schemas{0}\n", full_key); builder.AppendFormat(" {0}\n", full_key); builder.AppendFormat(" banshee\n"); if(!list) { builder.AppendFormat(" {0}\n", str_type); } else { builder.AppendFormat(" list\n"); builder.AppendFormat(" {0}\n", str_type); } builder.AppendFormat(" {0}\n", str_val); builder.AppendFormat(" \n"); builder.AppendFormat(" {0}\n", short_desc); builder.AppendFormat(" {0}\n", long_desc); builder.AppendFormat(" \n"); builder.AppendFormat(" \n"); entries.Add(full_key, builder); } private static string CamelCaseToUnderCase(string s) { string undercase = String.Empty; string [] tokens = Regex.Split(s, "([A-Z]{1}[a-z]+)"); for(int i = 0; i < tokens.Length; i++) { if(tokens[i] == String.Empty) { continue; } undercase += tokens[i].ToLower(); if(i < tokens.Length - 2) { undercase += "_"; } } return undercase; } private static string CreateKey(string namespce, string key) { return namespce == null ? "/apps/banshee/" + CamelCaseToUnderCase(key) : "/apps/banshee/" + CamelCaseToUnderCase(namespce.Replace(".", "/")) + "/" + CamelCaseToUnderCase(key); } } hyena-0.5/build/AddinXmlStringExtractor.cs0000644000175000001440000000261711377073562021031 0ustar00gabeusers00000000000000using System; using System.Xml.XPath; using System.Collections.Generic; public static class AddinXmlStringExtract { public static void Main (string [] args) { var queries = new [] { "/Addin/@name", "/Addin/@description", "/Addin/@category" }; Console.WriteLine (@"// Generated - Do Not Edit! internal static class AddinXmlStringCatalog { private static void Strings () {"); var paths = new List (args); paths.Sort (); foreach (var path in paths) { Console.WriteLine (" // {0}", path); var xpath = new XPathDocument (path); var nav = xpath.CreateNavigator (); foreach (var query in queries) { var iter = nav.Select (query); while (iter.MoveNext ()) { var value = iter.Current.Value.Trim (); if (String.IsNullOrEmpty (value) || value[0] == '@' || (iter.Current.Name == "category" && value.StartsWith ("required:"))) { continue; } Console.WriteLine (@" Catalog.GetString (@""{0}"");", value.Replace (@"""", @"""""")); } } Console.WriteLine (); } Console.WriteLine (" }\n}"); } } hyena-0.5/build/gconf-schema-rules0000644000175000001440000000106711377073562017322 0ustar00gabeusers00000000000000schema_in_files = $(ASSEMBLY_GCONF_SCHEMA) schemadir = $(GCONF_SCHEMA_FILE_DIR) schema_DATA = $(schema_in_files:.schemas.in=.schemas) $(srcdir)/$(ASSEMBLY_GCONF_SCHEMA): $(ASSEMBLY) if test -w $@ -o \( ! -e $@ -a -w $(srcdir) \); then \ BANSHEE_DISABLE_GCONF=1 MONO_PATH=$(MONO_BASE_PATH) $(MONO) $(top_builddir)/build/gconf-schema-extractor.exe $< $(srcdir)/$@; \ fi @INTLTOOL_SCHEMAS_RULE@ if GCONF_SCHEMAS_INSTALL install-data-local: if [ -z "$(DESTDIR)" ]; then \ GCONF_CONFIG_SOURCE="" $(GCONFTOOL) --makefile-install-rule $(schema_DATA); \ fi endif hyena-0.5/build/m4/0000777000175000001440000000000011453151001014211 5ustar00gabeusers00000000000000hyena-0.5/build/m4/Makefile.in0000644000175000001440000002065211453150777016302 0ustar00gabeusers00000000000000# Makefile.in generated by automake 1.10.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : subdir = build/m4 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/build/m4/shamrock/expansions.m4 \ $(top_srcdir)/build/m4/shamrock/mono.m4 \ $(top_srcdir)/build/m4/shamrock/programs.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = SOURCES = DIST_SOURCES = DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ GLIBSHARP_CFLAGS = @GLIBSHARP_CFLAGS@ GLIBSHARP_LIBS = @GLIBSHARP_LIBS@ GTKSHARP_A11Y_CFLAGS = @GTKSHARP_A11Y_CFLAGS@ GTKSHARP_A11Y_LIBS = @GTKSHARP_A11Y_LIBS@ GTKSHARP_CFLAGS = @GTKSHARP_CFLAGS@ GTKSHARP_LIBS = @GTKSHARP_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MCS = @MCS@ MKDIR_P = @MKDIR_P@ MONO = @MONO@ MONO_MODULE_CFLAGS = @MONO_MODULE_CFLAGS@ MONO_MODULE_LIBS = @MONO_MODULE_LIBS@ NUNIT_CFLAGS = @NUNIT_CFLAGS@ NUNIT_LIBS = @NUNIT_LIBS@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ am__leading_dot = @am__leading_dot@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ expanded_bindir = @expanded_bindir@ expanded_datadir = @expanded_datadir@ expanded_libdir = @expanded_libdir@ host_alias = @host_alias@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ EXTRA_DIST = \ $(srcdir)/shamrock/*.m4 MAINTAINERCLEANFILES = Makefile.in all: all-am .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign build/m4/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --foreign build/m4/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh tags: TAGS TAGS: ctags: CTAGS CTAGS: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) clean: clean-am clean-am: clean-generic mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-exec-am: install-html: install-html-am install-info: install-info-am install-man: install-pdf: install-pdf-am install-ps: install-ps-am installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic distclean \ distclean-generic distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic pdf pdf-am ps ps-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: hyena-0.5/build/m4/shamrock/0000777000175000001440000000000011453151001016020 5ustar00gabeusers00000000000000hyena-0.5/build/m4/shamrock/monodoc.m40000644000175000001440000000146511377073562017746 0ustar00gabeusers00000000000000AC_DEFUN([SHAMROCK_CHECK_MONODOC], [ AC_ARG_ENABLE(docs, AC_HELP_STRING([--disable-docs], [Do not build documentation]), , enable_docs=yes) if test "x$enable_docs" = "xyes"; then AC_PATH_PROG(MONODOCER, monodocer, no) if test "x$MONODOCER" = "xno"; then AC_MSG_ERROR([You need to install monodoc, or pass --disable-docs to configure to skip documentation installation]) fi AC_PATH_PROG(MDASSEMBLER, mdassembler, no) if test "x$MDASSEMBLER" = "xno"; then AC_MSG_ERROR([You need to install mdassembler, or pass --disable-docs to configure to skip documentation installation]) fi DOCDIR=`$PKG_CONFIG monodoc --variable=sourcesdir` AC_SUBST(DOCDIR) AM_CONDITIONAL(BUILD_DOCS, true) else AC_MSG_NOTICE([not building ${PACKAGE} API documentation]) AM_CONDITIONAL(BUILD_DOCS, false) fi ]) hyena-0.5/build/m4/shamrock/nunit.m40000644000175000001440000000141511377073562017440 0ustar00gabeusers00000000000000AC_DEFUN([SHAMROCK_CHECK_NUNIT], [ NUNIT_REQUIRED=2.4.7 AC_ARG_ENABLE(tests, AC_HELP_STRING([--enable-tests], [Enable NUnit tests]), enable_tests=$enableval, enable_tests="no") if test "x$enable_tests" = "xno"; then do_tests=no AM_CONDITIONAL(ENABLE_TESTS, false) else PKG_CHECK_MODULES(NUNIT, nunit >= $NUNIT_REQUIRED, do_tests="yes", do_tests="no") AC_SUBST(NUNIT_LIBS) AM_CONDITIONAL(ENABLE_TESTS, test "x$do_tests" = "xyes") if test "x$do_tests" = "xno"; then PKG_CHECK_MODULES(NUNIT, mono-nunit >= 2.4, do_tests="yes", do_tests="no") AC_SUBST(NUNIT_LIBS) AM_CONDITIONAL(ENABLE_TESTS, test "x$do_tests" = "xyes") if test "x$do_tests" = "xno"; then AC_MSG_WARN([Could not find nunit: tests will not be available]) fi fi fi ]) hyena-0.5/build/m4/shamrock/util.m40000644000175000001440000000024311377073562017256 0ustar00gabeusers00000000000000AC_DEFUN([SHAMROCK_CONCAT], [ $1="$$1 $$2" ]) AC_DEFUN([SHAMROCK_CONCAT_MODULE], [ SHAMROCK_CONCAT($1_CFLAGS, $2_CFLAGS) SHAMROCK_CONCAT($1_LIBS, $2_LIBS) ]) hyena-0.5/build/m4/shamrock/expansions.m40000644000175000001440000000146611377073562020500 0ustar00gabeusers00000000000000AC_DEFUN([SHAMROCK_EXPAND_LIBDIR], [ expanded_libdir=`( case $prefix in NONE) prefix=$ac_default_prefix ;; *) ;; esac case $exec_prefix in NONE) exec_prefix=$prefix ;; *) ;; esac eval echo $libdir )` AC_SUBST(expanded_libdir) ]) AC_DEFUN([SHAMROCK_EXPAND_BINDIR], [ expanded_bindir=`( case $prefix in NONE) prefix=$ac_default_prefix ;; *) ;; esac case $exec_prefix in NONE) exec_prefix=$prefix ;; *) ;; esac eval echo $bindir )` AC_SUBST(expanded_bindir) ]) AC_DEFUN([SHAMROCK_EXPAND_DATADIR], [ case $prefix in NONE) prefix=$ac_default_prefix ;; *) ;; esac case $exec_prefix in NONE) exec_prefix=$prefix ;; *) ;; esac expanded_datadir=`(eval echo $datadir)` expanded_datadir=`(eval echo $expanded_datadir)` AC_SUBST(expanded_datadir) ]) hyena-0.5/build/m4/shamrock/mono.m40000644000175000001440000000256211377073562017257 0ustar00gabeusers00000000000000AC_DEFUN([SHAMROCK_FIND_MONO_1_0_COMPILER], [ SHAMROCK_FIND_PROGRAM_OR_BAIL(MCS, mcs) ]) AC_DEFUN([SHAMROCK_FIND_MONO_2_0_COMPILER], [ SHAMROCK_FIND_PROGRAM_OR_BAIL(MCS, gmcs) ]) AC_DEFUN([SHAMROCK_FIND_MONO_4_0_COMPILER], [ SHAMROCK_FIND_PROGRAM_OR_BAIL(MCS, dmcs) ]) AC_DEFUN([SHAMROCK_FIND_MONO_RUNTIME], [ SHAMROCK_FIND_PROGRAM_OR_BAIL(MONO, mono) ]) AC_DEFUN([SHAMROCK_CHECK_MONO_MODULE], [ PKG_CHECK_MODULES(MONO_MODULE, mono >= $1) ]) AC_DEFUN([SHAMROCK_CHECK_MONO_MODULE_NOBAIL], [ PKG_CHECK_MODULES(MONO_MODULE, mono >= $1, HAVE_MONO_MODULE=yes, HAVE_MONO_MODULE=no) AC_SUBST(HAVE_MONO_MODULE) ]) AC_DEFUN([_SHAMROCK_CHECK_MONO_GAC_ASSEMBLIES], [ for asm in $(echo "$*" | cut -d, -f2- | sed 's/\,/ /g') do AC_MSG_CHECKING([for Mono $1 GAC for $asm.dll]) if test \ -e "$($PKG_CONFIG --variable=libdir mono)/mono/$1/$asm.dll" -o \ -e "$($PKG_CONFIG --variable=prefix mono)/lib/mono/$1/$asm.dll"; \ then \ AC_MSG_RESULT([found]) else AC_MSG_RESULT([not found]) AC_MSG_ERROR([missing required Mono $1 assembly: $asm.dll]) fi done ]) AC_DEFUN([SHAMROCK_CHECK_MONO_1_0_GAC_ASSEMBLIES], [ _SHAMROCK_CHECK_MONO_GAC_ASSEMBLIES(1.0, $*) ]) AC_DEFUN([SHAMROCK_CHECK_MONO_2_0_GAC_ASSEMBLIES], [ _SHAMROCK_CHECK_MONO_GAC_ASSEMBLIES(2.0, $*) ]) AC_DEFUN([SHAMROCK_CHECK_MONO_4_0_GAC_ASSEMBLIES], [ _SHAMROCK_CHECK_MONO_GAC_ASSEMBLIES(4.0, $*) ]) hyena-0.5/build/m4/shamrock/i18n.m40000644000175000001440000000053611377073562017065 0ustar00gabeusers00000000000000AC_DEFUN([SHAMROCK_CONFIGURE_I18N], [ ALL_LINGUAS=`grep -v '^#' $srcdir/po/LINGUAS | $SED ':a;N;$!ba;s/\n/ /g; s/[ ]+/ /g' | xargs` GETTEXT_PACKAGE=$1 AC_SUBST(GETTEXT_PACKAGE) AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE, "$GETTEXT_PACKAGE", [Gettext Package]) AM_GLIB_GNU_GETTEXT AC_SUBST([CONFIG_STATUS_DEPENDENCIES],['$(top_srcdir)/po/LINGUAS']) ]) hyena-0.5/build/m4/shamrock/programs.m40000644000175000001440000000036111377073562020134 0ustar00gabeusers00000000000000AC_DEFUN([SHAMROCK_FIND_PROGRAM], [ AC_PATH_PROG($1, $2, $3) AC_SUBST($1) ]) AC_DEFUN([SHAMROCK_FIND_PROGRAM_OR_BAIL], [ SHAMROCK_FIND_PROGRAM($1, $2, no) if test "x$$1" = "xno"; then AC_MSG_ERROR([You need to install '$2']) fi ]) hyena-0.5/build/m4/Makefile.am0000644000175000001440000000011511377073562016262 0ustar00gabeusers00000000000000EXTRA_DIST = \ $(srcdir)/shamrock/*.m4 MAINTAINERCLEANFILES = Makefile.in hyena-0.5/build/private-icon-theme-installer0000755000175000001440000000115111377073562021330 0ustar00gabeusers00000000000000#!/usr/bin/env bash mkinstalldirs=$1; shift install_data=$1; shift action=$1; shift dest_dir=$1; shift src_dir=$1; shift for icon in $@; do dest_dir_build="${dest_dir}/icons/hicolor/$(dirname ${icon})" if [[ ${action} == "-i" || ${action} == "-il" ]]; then src_file="${src_dir}/ThemeIcons/${icon}" $mkinstalldirs "${dest_dir_build}" &>/dev/null if [[ ${action} == "-i" ]]; then echo "Installing private icon theme icon: ${icon}" fi $install_data "${src_file}" "${dest_dir_build}" else echo "Uninstalling private icon theme icon: ${icon}" rm -f "${dest_dir_build}/$(basename ${icon})" fi done hyena-0.5/README0000644000175000001440000000345611406520207013464 0ustar00gabeusers00000000000000This is a library of useful GUI and non-GUI C# code, originally used in Banshee. NOTE ** It is not API stable, and so is not installed to the GAC.** There are three ways to use Hyena in your app: 1) Require it as an external dep; copy its .dll files into your project Applications using it should make a local copy of whatever components you use. That is, you should consider Hyena a build-time dependency, not a run-time, since at run-time your app will contain a copy of Hyena. There are variables defined in the pkg-config files that contain assemblies and files needed for a given component of Hyena (eg hyena, hyena.data.sqlite, and hyena.gui). pkg-config --variable=Assemblies hyena pkg-config --variable=Files hyena You can look at PDF Mod for an example of how to use Hyena: http://git.gnome.org/cgit/pdfmod/tree/configure.ac http://git.gnome.org/cgit/pdfmod/tree/Makefile.am http://git.gnome.org/cgit/pdfmod/tree/src/Makefile.am 2) Include it as a submodule in your git repo This is advantageous if you want to closely track and maybe contribute back to Hyena. It also means developers don't have to install Hyena themselves from packages or git. git submodule add git://git.gnome.org/hyena lib/Hyena git submodule update --init git add .gitmodules Then you'll need to add Hyena to your build system. See Banshee's setup: http://git.gnome.org/cgit/banshee/tree/configure.ac http://git.gnome.org/cgit/banshee/tree/Makefile.am You can also include the appropriate .csproj in your .sln. Set them to build under the 'Submodule' configuration, and the binaries will get outputted to ../../bin from the Hyena checkout directory. 3) Bundle the .dll files in your project It's an expedient, but not good form for FOSS projects. hyena-0.5/aclocal.m40000644000175000001440000006762311453150776014466 0ustar00gabeusers00000000000000# generated automatically by aclocal 1.10.1 -*- Autoconf -*- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, # 2005, 2006, 2007, 2008 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl m4_if(AC_AUTOCONF_VERSION, [2.63],, [m4_warning([this file was generated for autoconf 2.63. You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically `autoreconf'.])]) # pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- # # Copyright © 2004 Scott James Remnant . # # 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. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # PKG_PROG_PKG_CONFIG([MIN-VERSION]) # ---------------------------------- AC_DEFUN([PKG_PROG_PKG_CONFIG], [m4_pattern_forbid([^_?PKG_[A-Z_]+$]) m4_pattern_allow([^PKG_CONFIG(_PATH)?$]) AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])dnl if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) fi if test -n "$PKG_CONFIG"; then _pkg_min_version=m4_default([$1], [0.9.0]) AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) PKG_CONFIG="" fi fi[]dnl ])# PKG_PROG_PKG_CONFIG # PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) # # Check to see whether a particular set of modules exists. Similar # to PKG_CHECK_MODULES(), but does not set variables or print errors. # # # Similar to PKG_CHECK_MODULES, make sure that the first instance of # this or PKG_CHECK_MODULES is called, or make sure to call # PKG_CHECK_EXISTS manually # -------------------------------------------------------------- AC_DEFUN([PKG_CHECK_EXISTS], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl if test -n "$PKG_CONFIG" && \ AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then m4_ifval([$2], [$2], [:]) m4_ifvaln([$3], [else $3])dnl fi]) # _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) # --------------------------------------------- m4_define([_PKG_CONFIG], [if test -n "$$1"; then pkg_cv_[]$1="$$1" elif test -n "$PKG_CONFIG"; then PKG_CHECK_EXISTS([$3], [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`], [pkg_failed=yes]) else pkg_failed=untried fi[]dnl ])# _PKG_CONFIG # _PKG_SHORT_ERRORS_SUPPORTED # ----------------------------- AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], [AC_REQUIRE([PKG_PROG_PKG_CONFIG]) if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi[]dnl ])# _PKG_SHORT_ERRORS_SUPPORTED # PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], # [ACTION-IF-NOT-FOUND]) # # # Note that if there is a possibility the first call to # PKG_CHECK_MODULES might not happen, you should be sure to include an # explicit call to PKG_PROG_PKG_CONFIG in your configure.ac # # # -------------------------------------------------------------- AC_DEFUN([PKG_CHECK_MODULES], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl pkg_failed=no AC_MSG_CHECKING([for $1]) _PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) _PKG_CONFIG([$1][_LIBS], [libs], [$2]) m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS and $1[]_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details.]) if test $pkg_failed = yes; then _PKG_SHORT_ERRORS_SUPPORTED if test $_pkg_short_errors_supported = yes; then $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "$2" 2>&1` else $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors "$2" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD ifelse([$4], , [AC_MSG_ERROR(dnl [Package requirements ($2) were not met: $$1_PKG_ERRORS Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. _PKG_TEXT ])], [AC_MSG_RESULT([no]) $4]) elif test $pkg_failed = untried; then ifelse([$4], , [AC_MSG_FAILURE(dnl [The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. _PKG_TEXT To get pkg-config, see .])], [$4]) else $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS $1[]_LIBS=$pkg_cv_[]$1[]_LIBS AC_MSG_RESULT([yes]) ifelse([$3], , :, [$3]) fi[]dnl ])# PKG_CHECK_MODULES # Copyright (C) 2002, 2003, 2005, 2006, 2007 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_AUTOMAKE_VERSION(VERSION) # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version='1.10' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. m4_if([$1], [1.10.1], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) # _AM_AUTOCONF_VERSION(VERSION) # ----------------------------- # aclocal traces this macro to find the Autoconf version. # This is a private macro too. Using m4_define simplifies # the logic in aclocal, which can simply ignore this definition. m4_define([_AM_AUTOCONF_VERSION], []) # AM_SET_CURRENT_AUTOMAKE_VERSION # ------------------------------- # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AC_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], [AM_AUTOMAKE_VERSION([1.10.1])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(AC_AUTOCONF_VERSION)]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- # Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets # $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to # `$srcdir', `$srcdir/..', or `$srcdir/../..'. # # Of course, Automake must honor this variable whenever it calls a # tool from the auxiliary directory. The problem is that $srcdir (and # therefore $ac_aux_dir as well) can be either absolute or relative, # depending on how configure is run. This is pretty annoying, since # it makes $ac_aux_dir quite unusable in subdirectories: in the top # source directory, any form will work fine, but in subdirectories a # relative path needs to be adjusted first. # # $ac_aux_dir/missing # fails when called from a subdirectory if $ac_aux_dir is relative # $top_srcdir/$ac_aux_dir/missing # fails if $ac_aux_dir is absolute, # fails when called from a subdirectory in a VPATH build with # a relative $ac_aux_dir # # The reason of the latter failure is that $top_srcdir and $ac_aux_dir # are both prefixed by $srcdir. In an in-source build this is usually # harmless because $srcdir is `.', but things will broke when you # start a VPATH build or use an absolute $srcdir. # # So we could use something similar to $top_srcdir/$ac_aux_dir/missing, # iff we strip the leading $srcdir from $ac_aux_dir. That would be: # am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` # and then we would define $MISSING as # MISSING="\${SHELL} $am_aux_dir/missing" # This will work as long as MISSING is not called from configure, because # unfortunately $(top_srcdir) has no meaning in configure. # However there are other variables, like CC, which are often used in # configure, and could therefore not use this "fixed" $ac_aux_dir. # # Another solution, used here, is to always expand $ac_aux_dir to an # absolute PATH. The drawback is that using absolute paths prevent a # configured tree to be moved without reconfiguration. AC_DEFUN([AM_AUX_DIR_EXPAND], [dnl Rely on autoconf to set up CDPATH properly. AC_PREREQ([2.50])dnl # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` ]) # AM_CONDITIONAL -*- Autoconf -*- # Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 8 # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- # Define a conditional. AC_DEFUN([AM_CONDITIONAL], [AC_PREREQ(2.52)dnl ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl AC_SUBST([$1_TRUE])dnl AC_SUBST([$1_FALSE])dnl _AM_SUBST_NOTMAKE([$1_TRUE])dnl _AM_SUBST_NOTMAKE([$1_FALSE])dnl if $2; then $1_TRUE= $1_FALSE='#' else $1_TRUE='#' $1_FALSE= fi AC_CONFIG_COMMANDS_PRE( [if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then AC_MSG_ERROR([[conditional "$1" was never defined. Usually this means the macro was only invoked conditionally.]]) fi])]) # Do all the work for Automake. -*- Autoconf -*- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, # 2005, 2006, 2008 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 13 # This macro actually does too much. Some checks are only needed if # your package does certain things. But this isn't really a big deal. # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) # AM_INIT_AUTOMAKE([OPTIONS]) # ----------------------------------------------- # The call with PACKAGE and VERSION arguments is the old style # call (pre autoconf-2.50), which is being phased out. PACKAGE # and VERSION should now be passed to AC_INIT and removed from # the call to AM_INIT_AUTOMAKE. # We support both call styles for the transition. After # the next Automake release, Autoconf can make the AC_INIT # arguments mandatory, and then we can depend on a new Autoconf # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], [AC_PREREQ([2.60])dnl dnl Autoconf wants to disallow AM_ names. We explicitly allow dnl the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl # test to see if srcdir already configured if test -f $srcdir/config.status; then AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi AC_SUBST([CYGPATH_W]) # Define the identity of the package. dnl Distinguish between old-style and new-style calls. m4_ifval([$2], [m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], [_AM_SET_OPTIONS([$1])dnl dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,, [m4_fatal([AC_INIT should be called with package and version arguments])])dnl AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl _AM_IF_OPTION([no-define],, [AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl # Some tools Automake needs. AC_REQUIRE([AM_SANITY_CHECK])dnl AC_REQUIRE([AC_ARG_PROGRAM])dnl AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) AM_MISSING_PROG(AUTOCONF, autoconf) AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) AM_MISSING_PROG(AUTOHEADER, autoheader) AM_MISSING_PROG(MAKEINFO, makeinfo) AM_PROG_INSTALL_SH AM_PROG_INSTALL_STRIP AC_REQUIRE([AM_PROG_MKDIR_P])dnl # We need awk for the "check" target. The system "awk" is bad on # some platforms. AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AM_SET_LEADING_DOT])dnl _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], [_AM_PROG_TAR([v7])])]) _AM_IF_OPTION([no-dependencies],, [AC_PROVIDE_IFELSE([AC_PROG_CC], [_AM_DEPENDENCIES(CC)], [define([AC_PROG_CC], defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], [_AM_DEPENDENCIES(CXX)], [define([AC_PROG_CXX], defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJC], [_AM_DEPENDENCIES(OBJC)], [define([AC_PROG_OBJC], defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl ]) ]) # When config.status generates a header, we must update the stamp-h file. # This file resides in the same directory as the config header # that is generated. The stamp files are numbered to have different names. # Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the # loop where config.status creates the headers, so we can generate # our stamp files there. AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], [# Compute $1's index in $config_headers. _am_arg=$1 _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) # Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_SH # ------------------ # Define $install_sh. AC_DEFUN([AM_PROG_INSTALL_SH], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl install_sh=${install_sh-"\$(SHELL) $am_aux_dir/install-sh"} AC_SUBST(install_sh)]) # Copyright (C) 2003, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 2 # Check whether the underlying file-system supports filenames # with a leading dot. For instance MS-DOS doesn't. AC_DEFUN([AM_SET_LEADING_DOT], [rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null AC_SUBST([am__leading_dot])]) # Add --enable-maintainer-mode option to configure. -*- Autoconf -*- # From Jim Meyering # Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 4 AC_DEFUN([AM_MAINTAINER_MODE], [AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) dnl maintainer-mode is disabled by default AC_ARG_ENABLE(maintainer-mode, [ --enable-maintainer-mode enable make rules and dependencies not useful (and sometimes confusing) to the casual installer], USE_MAINTAINER_MODE=$enableval, USE_MAINTAINER_MODE=no) AC_MSG_RESULT([$USE_MAINTAINER_MODE]) AM_CONDITIONAL(MAINTAINER_MODE, [test $USE_MAINTAINER_MODE = yes]) MAINT=$MAINTAINER_MODE_TRUE AC_SUBST(MAINT)dnl ] ) AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE]) # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- # Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 5 # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ AC_DEFUN([AM_MISSING_PROG], [AC_REQUIRE([AM_MISSING_HAS_RUN]) $1=${$1-"${am_missing_run}$2"} AC_SUBST($1)]) # AM_MISSING_HAS_RUN # ------------------ # Define MISSING if not defined so far and test if it supports --run. # If it does, set am_missing_run to use it, otherwise, to nothing. AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([missing])dnl test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" # Use eval to expand $SHELL if eval "$MISSING --run true"; then am_missing_run="$MISSING --run " else am_missing_run= AC_MSG_WARN([`missing' script is too old or missing]) fi ]) # Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_MKDIR_P # --------------- # Check for `mkdir -p'. AC_DEFUN([AM_PROG_MKDIR_P], [AC_PREREQ([2.60])dnl AC_REQUIRE([AC_PROG_MKDIR_P])dnl dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P, dnl while keeping a definition of mkdir_p for backward compatibility. dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile. dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of dnl Makefile.ins that do not define MKDIR_P, so we do our own dnl adjustment using top_builddir (which is defined more often than dnl MKDIR_P). AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl case $mkdir_p in [[\\/$]]* | ?:[[\\/]]*) ;; */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; esac ]) # Helper functions for option handling. -*- Autoconf -*- # Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 3 # _AM_MANGLE_OPTION(NAME) # ----------------------- AC_DEFUN([_AM_MANGLE_OPTION], [[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) # _AM_SET_OPTION(NAME) # ------------------------------ # Set option NAME. Presently that only means defining a flag for this option. AC_DEFUN([_AM_SET_OPTION], [m4_define(_AM_MANGLE_OPTION([$1]), 1)]) # _AM_SET_OPTIONS(OPTIONS) # ---------------------------------- # OPTIONS is a space-separated list of Automake options. AC_DEFUN([_AM_SET_OPTIONS], [AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) # _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) # ------------------------------------------- # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) # Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_RUN_LOG(COMMAND) # ------------------- # Run COMMAND, save the exit status in ac_status, and log it. # (This has been adapted from Autoconf's _AC_RUN_LOG macro.) AC_DEFUN([AM_RUN_LOG], [{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD (exit $ac_status); }]) # Check to make sure that the build environment is sane. -*- Autoconf -*- # Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 4 # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) # Just in case sleep 1 echo timestamp > conftest.file # Do `set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` if test "$[*]" = "X"; then # -L didn't work. set X `ls -t $srcdir/configure conftest.file` fi rm -f conftest.file if test "$[*]" != "X $srcdir/configure conftest.file" \ && test "$[*]" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken alias in your environment]) fi test "$[2]" = conftest.file ) then # Ok. : else AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi AC_MSG_RESULT(yes)]) # Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_STRIP # --------------------- # One issue with vendor `install' (even GNU) is that you can't # specify the program used to strip binaries. This is especially # annoying in cross-compiling environments, where the build's strip # is unlikely to handle the host's binaries. # Fortunately install-sh will honor a STRIPPROG variable, so we # always use install-sh in `make install-strip', and initialize # STRIPPROG with the value of the STRIP variable (set by the user). AC_DEFUN([AM_PROG_INSTALL_STRIP], [AC_REQUIRE([AM_PROG_INSTALL_SH])dnl # Installed binaries are usually stripped using `strip' when the user # run `make install-strip'. However `strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the `STRIP' environment variable to overrule this program. dnl Don't test for $cross_compiling = yes, because it might be `maybe'. if test "$cross_compiling" != no; then AC_CHECK_TOOL([STRIP], [strip], :) fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) # Copyright (C) 2006 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_SUBST_NOTMAKE(VARIABLE) # --------------------------- # Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. # This macro is traced by Automake. AC_DEFUN([_AM_SUBST_NOTMAKE]) # Check how to create a tarball. -*- Autoconf -*- # Copyright (C) 2004, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 2 # _AM_PROG_TAR(FORMAT) # -------------------- # Check how to create a tarball in format FORMAT. # FORMAT should be one of `v7', `ustar', or `pax'. # # Substitute a variable $(am__tar) that is a command # writing to stdout a FORMAT-tarball containing the directory # $tardir. # tardir=directory && $(am__tar) > result.tar # # Substitute a variable $(am__untar) that extract such # a tarball read from stdin. # $(am__untar) < result.tar AC_DEFUN([_AM_PROG_TAR], [# Always define AMTAR for backward compatibility. AM_MISSING_PROG([AMTAR], [tar]) m4_if([$1], [v7], [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'], [m4_case([$1], [ustar],, [pax],, [m4_fatal([Unknown tar format])]) AC_MSG_CHECKING([how to create a $1 tar archive]) # Loop over all known methods to create a tar archive until one works. _am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' _am_tools=${am_cv_prog_tar_$1-$_am_tools} # Do not fold the above two line into one, because Tru64 sh and # Solaris sh will not grok spaces in the rhs of `-'. for _am_tool in $_am_tools do case $_am_tool in gnutar) for _am_tar in tar gnutar gtar; do AM_RUN_LOG([$_am_tar --version]) && break done am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' am__untar="$_am_tar -xf -" ;; plaintar) # Must skip GNU tar: if it does not support --format= it doesn't create # ustar tarball either. (tar --version) >/dev/null 2>&1 && continue am__tar='tar chf - "$$tardir"' am__tar_='tar chf - "$tardir"' am__untar='tar xf -' ;; pax) am__tar='pax -L -x $1 -w "$$tardir"' am__tar_='pax -L -x $1 -w "$tardir"' am__untar='pax -r' ;; cpio) am__tar='find "$$tardir" -print | cpio -o -H $1 -L' am__tar_='find "$tardir" -print | cpio -o -H $1 -L' am__untar='cpio -i -H $1 -d' ;; none) am__tar=false am__tar_=false am__untar=false ;; esac # If the value was cached, stop now. We just wanted to have am__tar # and am__untar set. test -n "${am_cv_prog_tar_$1}" && break # tar/untar a dummy directory, and stop if the command works rm -rf conftest.dir mkdir conftest.dir echo GrepMe > conftest.dir/file AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) rm -rf conftest.dir if test -s conftest.tar; then AM_RUN_LOG([$am__untar /dev/null 2>&1 && break fi done rm -rf conftest.dir AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) AC_MSG_RESULT([$am_cv_prog_tar_$1])]) AC_SUBST([am__tar]) AC_SUBST([am__untar]) ]) # _AM_PROG_TAR m4_include([build/m4/shamrock/expansions.m4]) m4_include([build/m4/shamrock/mono.m4]) m4_include([build/m4/shamrock/programs.m4]) hyena-0.5/Makefile.am0000644000175000001440000000173211416416740014642 0ustar00gabeusers00000000000000 SUBDIRS = \ build \ Hyena \ Mono.Data.Sqlite \ Hyena.Data.Sqlite \ Hyena.Gui clean-local: rm -rf $(top_builddir)/bin if ENABLE_TESTS TEST_ASSEMBLIES = \ Hyena.dll \ Hyena.Data.Sqlite.dll \ Hyena.Gui.dll ENV_OPTIONS = TZ=America/Chicago LC_ALL=it_IT LANG=it_IT NUNIT_CONSOLE = $$(echo $$(which nunit-console2 || which nunit-console)) RUNNER = for asm in $${TEST_ASSEMBLIES}; do echo -e "\033[1mRunning tests on $${asm}...\033[0m"; $(ENV_OPTIONS) $(NUNIT_CONSOLE) -nologo -noshadow $$asm; done test: @pushd bin &>/dev/null; \ export TEST_ASSEMBLIES="$(TEST_ASSEMBLIES)"; $(RUNNER); \ popd &>/dev/null; else test: echo "Tests not enabled. Pass --enable-tests to configure or ./autogen.sh" endif MAINTAINERCLEANFILES = \ compile \ INSTALL \ config.h.in \ aclocal.m4 \ ltmain.sh \ Makefile.in \ depcomp \ missing \ install-sh \ configure \ config.sub \ config.guess \ intltool-extract.in \ intltool-merge.in \ intltool-update.in \ mkinstalldirs hyena-0.5/configure.ac0000644000175000001440000000645311453150644015100 0ustar00gabeusers00000000000000dnl Warning: This is an automatically generated file, do not edit! dnl Process this file with autoconf to produce a configure script. AC_PREREQ([2.54]) AC_INIT([hyena], [0.5]) AM_INIT_AUTOMAKE([foreign dist-bzip2 tar-ustar]) AM_MAINTAINER_MODE AC_SUBST([ACLOCAL_AMFLAGS], ["-I build/m4/shamrock \${ACLOCAL_FLAGS}"]) dnl pkg-config AC_PATH_PROG(PKG_CONFIG, pkg-config, no) if test "x$PKG_CONFIG" = "xno"; then AC_MSG_ERROR([You need to install pkg-config]) fi SHAMROCK_EXPAND_LIBDIR SHAMROCK_EXPAND_BINDIR SHAMROCK_EXPAND_DATADIR AC_PROG_INSTALL AC_ARG_ENABLE(debug, AC_HELP_STRING([--enable-debug], [Use 'DEBUG' Configuration [default=YES]]), enable_debug=yes, enable_debug=no) AM_CONDITIONAL(ENABLE_DEBUG, test x$enable_debug = xyes) if test "x$enable_debug" = "xyes" ; then CONFIG_REQUESTED="yes" fi AC_ARG_ENABLE(release, AC_HELP_STRING([--enable-release], [Use 'RELEASE' Configuration [default=NO]]), enable_release=yes, enable_release=no) AM_CONDITIONAL(ENABLE_RELEASE, test x$enable_release = xyes) if test "x$enable_release" = "xyes" ; then CONFIG_REQUESTED="yes" fi AC_ARG_ENABLE(windows, AC_HELP_STRING([--enable-windows], [Use 'WINDOWS' Configuration [default=NO]]), enable_windows=yes, enable_windows=no) AM_CONDITIONAL(ENABLE_WINDOWS, test x$enable_windows = xyes) if test "x$enable_windows" = "xyes" ; then CONFIG_REQUESTED="yes" fi if test -z "$CONFIG_REQUESTED" ; then AM_CONDITIONAL(ENABLE_DEBUG, true) enable_debug=yes fi dnl Mono and gmcs SHAMROCK_CHECK_MONO_MODULE(1.9.1) SHAMROCK_FIND_MONO_2_0_COMPILER SHAMROCK_FIND_MONO_RUNTIME SHAMROCK_CHECK_MONO_2_0_GAC_ASSEMBLIES([ System.Data Mono.Cairo Mono.Posix ICSharpCode.SharpZipLib ]) dnl package checks, common for all configs PKG_CHECK_MODULES([GTKSHARP], [gtk-sharp-2.0]) PKG_CHECK_MODULES([GLIBSHARP], [glib-sharp-2.0]) dnl See if Gtk# is recent enought to enable managed widget a11y PKG_CHECK_MODULES(GTKSHARP_A11Y, gtk-sharp-2.0 >= 2.12.10, gtksharp_with_a11y=yes, gtksharp_with_a11y=no) AM_CONDITIONAL(ENABLE_ATK, test "x$gtksharp_with_a11y" = "xyes") AM_CONDITIONAL(GCONF_SCHEMAS_INSTALL, false) AM_CONDITIONAL(HYENA_PKG_CONFIG, true) dnl Check for nunit NUNIT_REQUIRED=2.4.7 AC_ARG_ENABLE(tests, AC_HELP_STRING([--enable-tests], [Enable NUnit tests]), enable_tests=$enableval, enable_tests="no") if test "x$enable_tests" = "xno"; then do_tests=no AM_CONDITIONAL(ENABLE_TESTS, false) else PKG_CHECK_MODULES(NUNIT, nunit >= $NUNIT_REQUIRED, do_tests="yes", do_tests="no") AC_SUBST(NUNIT_LIBS) AM_CONDITIONAL(ENABLE_TESTS, test "x$do_tests" = "xyes") if test "x$do_tests" = "xno"; then PKG_CHECK_MODULES(NUNIT, mono-nunit >= 2.4, do_tests="yes", do_tests="no") AC_SUBST(NUNIT_LIBS) AM_CONDITIONAL(ENABLE_TESTS, test "x$do_tests" = "xyes") if test "x$do_tests" = "xno"; then AC_MSG_WARN([Could not find nunit: tests will not be available]) fi fi fi dnl package checks, per config AC_CONFIG_FILES([ Makefile build/Makefile build/m4/Makefile build/pkg-config/Makefile Mono.Data.Sqlite/Makefile Hyena/Makefile Hyena.Data.Sqlite/Makefile Hyena.Gui/Makefile ]) cat <= ${NUNIT_REQUIRED}) Custom a11y: ${gtksharp_with_a11y} (requires gtk-sharp >= 2.12.10) EOF AC_OUTPUT hyena-0.5/Mono.Data.Sqlite/0000777000175000001440000000000011453151002015613 5ustar00gabeusers00000000000000hyena-0.5/Mono.Data.Sqlite/Makefile.in0000644000175000001440000003415011453150777017701 0ustar00gabeusers00000000000000# Makefile.in generated by automake 1.10.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(top_srcdir)/build/build.environment.mk \ $(top_srcdir)/build/build.mk \ $(top_srcdir)/build/build.rules.mk @ENABLE_TESTS_TRUE@am__append_1 = " $(NUNIT_LIBS)" subdir = Mono.Data.Sqlite ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/build/m4/shamrock/expansions.m4 \ $(top_srcdir)/build/m4/shamrock/mono.m4 \ $(top_srcdir)/build/m4/shamrock/programs.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = am__installdirs = "$(DESTDIR)$(moduledir)" moduleSCRIPT_INSTALL = $(INSTALL_SCRIPT) SCRIPTS = $(module_SCRIPTS) DIST_SOURCES = DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ GLIBSHARP_CFLAGS = @GLIBSHARP_CFLAGS@ GLIBSHARP_LIBS = @GLIBSHARP_LIBS@ GTKSHARP_A11Y_CFLAGS = @GTKSHARP_A11Y_CFLAGS@ GTKSHARP_A11Y_LIBS = @GTKSHARP_A11Y_LIBS@ GTKSHARP_CFLAGS = @GTKSHARP_CFLAGS@ GTKSHARP_LIBS = @GTKSHARP_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MCS = @MCS@ MKDIR_P = @MKDIR_P@ MONO = @MONO@ MONO_MODULE_CFLAGS = @MONO_MODULE_CFLAGS@ MONO_MODULE_LIBS = @MONO_MODULE_LIBS@ NUNIT_CFLAGS = @NUNIT_CFLAGS@ NUNIT_LIBS = @NUNIT_LIBS@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ am__leading_dot = @am__leading_dot@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ expanded_bindir = @expanded_bindir@ expanded_datadir = @expanded_datadir@ expanded_libdir = @expanded_libdir@ host_alias = @host_alias@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ ASSEMBLY = Mono.Data.Sqlite TARGET = library LINK = -r:System -r:System.Data -r:System.Transactions $(am__append_1) ASSEMBLY_BUILD_FLAGS = -unsafe -d:MONO_BACKWARD_COMPAT SOURCES = \ Mono.Data.Sqlite/SQLite3.cs \ Mono.Data.Sqlite/SQLite3_UTF16.cs \ Mono.Data.Sqlite/SQLiteBase.cs \ Mono.Data.Sqlite/SQLiteCommand.cs \ Mono.Data.Sqlite/SQLiteCommandBuilder.cs \ Mono.Data.Sqlite/SQLiteConnection.cs \ Mono.Data.Sqlite/SQLiteConnectionStringBuilder.cs \ Mono.Data.Sqlite/SQLiteConvert.cs \ Mono.Data.Sqlite/SQLiteDataAdapter.cs \ Mono.Data.Sqlite/SQLiteDataReader.cs \ Mono.Data.Sqlite/SqliteDataSourceEnumerator.cs \ Mono.Data.Sqlite/SQLiteEnlistment.cs \ Mono.Data.Sqlite/SQLiteException.cs \ Mono.Data.Sqlite/SQLiteFactory.cs \ Mono.Data.Sqlite/SQLiteFunction.cs \ Mono.Data.Sqlite/SQLiteFunctionAttribute.cs \ Mono.Data.Sqlite/SQLiteMetaDataCollectionNames.cs \ Mono.Data.Sqlite/SQLiteParameter.cs \ Mono.Data.Sqlite/SQLiteParameterCollection.cs \ Mono.Data.Sqlite/SQLiteStatement.cs \ Mono.Data.Sqlite/SQLiteTransaction.cs \ Mono.Data.Sqlite/SR.Designer.cs \ Mono.Data.Sqlite/UnsafeNativeMethods.cs # Initializers MONO_BASE_PATH = MONO_ADDINS_PATH = # Install Paths DEFAULT_INSTALL_DIR = $(pkglibdir) DIR_BIN = $(top_builddir)/bin # Cute hack to replace a space with something colon := : empty := space := $(empty) $(empty) UNIQUE_FILTER_PIPE = tr [:space:] \\n | sort | uniq BUILD_DATA_DIR = $(top_builddir)/bin/share/$(PACKAGE) SOURCES_BUILD = $(addprefix $(srcdir)/, $(SOURCES)) RESOURCES_EXPANDED = $(addprefix $(srcdir)/, $(RESOURCES)) RESOURCES_BUILD = $(foreach resource, $(RESOURCES_EXPANDED), \ -resource:$(resource),$(notdir $(resource))) INSTALL_ICONS = $(top_srcdir)/build/private-icon-theme-installer "$(mkinstalldirs)" "$(INSTALL_DATA)" THEME_ICONS_SOURCE = $(wildcard $(srcdir)/ThemeIcons/*/*/*.png) $(wildcard $(srcdir)/ThemeIcons/scalable/*/*.svg) THEME_ICONS_RELATIVE = $(subst $(srcdir)/ThemeIcons/, , $(THEME_ICONS_SOURCE)) ASSEMBLY_EXTENSION = $(strip $(patsubst library, dll, $(TARGET))) ASSEMBLY_FILE = $(top_builddir)/bin/$(ASSEMBLY).$(ASSEMBLY_EXTENSION) INSTALL_DIR_RESOLVED = $(firstword $(subst , $(DEFAULT_INSTALL_DIR), $(INSTALL_DIR))) @ENABLE_TESTS_TRUE@ENABLE_TESTS_FLAG = "-define:ENABLE_TESTS" @ENABLE_ATK_TRUE@ENABLE_ATK_FLAG = "-define:ENABLE_ATK" FILTERED_LINK = $(shell echo "$(LINK)" | $(UNIQUE_FILTER_PIPE)) DEP_LINK = $(shell echo "$(LINK)" | $(UNIQUE_FILTER_PIPE) | sed s,-r:,,g | grep '$(top_builddir)/bin/') OUTPUT_FILES = \ $(ASSEMBLY_FILE) \ $(ASSEMBLY_FILE).mdb moduledir = $(INSTALL_DIR_RESOLVED) module_SCRIPTS = $(OUTPUT_FILES) EXTRA_DIST = $(SOURCES_BUILD) $(RESOURCES_EXPANDED) $(THEME_ICONS_SOURCE) CLEANFILES = $(OUTPUT_FILES) DISTCLEANFILES = *.pidb MAINTAINERCLEANFILES = Makefile.in all: all-am .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/build/build.mk $(top_srcdir)/build/build.environment.mk $(top_srcdir)/build/build.rules.mk $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Mono.Data.Sqlite/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --foreign Mono.Data.Sqlite/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh install-moduleSCRIPTS: $(module_SCRIPTS) @$(NORMAL_INSTALL) test -z "$(moduledir)" || $(MKDIR_P) "$(DESTDIR)$(moduledir)" @list='$(module_SCRIPTS)'; for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ if test -f $$d$$p; then \ f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \ echo " $(moduleSCRIPT_INSTALL) '$$d$$p' '$(DESTDIR)$(moduledir)/$$f'"; \ $(moduleSCRIPT_INSTALL) "$$d$$p" "$(DESTDIR)$(moduledir)/$$f"; \ else :; fi; \ done uninstall-moduleSCRIPTS: @$(NORMAL_UNINSTALL) @list='$(module_SCRIPTS)'; for p in $$list; do \ f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \ echo " rm -f '$(DESTDIR)$(moduledir)/$$f'"; \ rm -f "$(DESTDIR)$(moduledir)/$$f"; \ done tags: TAGS TAGS: ctags: CTAGS CTAGS: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(SCRIPTS) installdirs: for dir in "$(DESTDIR)$(moduledir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) clean: clean-am clean-am: clean-generic mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am info: info-am info-am: install-data-am: install-data-local install-moduleSCRIPTS install-dvi: install-dvi-am install-exec-am: install-html: install-html-am install-info: install-info-am install-man: install-pdf: install-pdf-am install-ps: install-ps-am installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-local uninstall-moduleSCRIPTS .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic distclean \ distclean-generic distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am \ install-data-local install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-moduleSCRIPTS install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ pdf-am ps ps-am uninstall uninstall-am uninstall-local \ uninstall-moduleSCRIPTS dnl SOURCES_BUILD += $(top_srcdir)/src/AssemblyInfo.cs all: $(ASSEMBLY_FILE) theme-icons run: @pushd $(top_builddir); \ make run; \ popd; test: @pushd $(top_builddir)/tests; \ make $(ASSEMBLY); \ popd; build-debug: @echo $(DEP_LINK) $(ASSEMBLY_FILE).mdb: $(ASSEMBLY_FILE) $(ASSEMBLY_FILE): $(SOURCES_BUILD) $(RESOURCES_EXPANDED) $(DEP_LINK) @mkdir -p $(top_builddir)/bin @if [ ! "x$(ENABLE_RELEASE)" = "xyes" ]; then \ $(top_srcdir)/build/dll-map-makefile-verifier $(srcdir)/Makefile.am $(srcdir)/$(notdir $@.config) && \ $(MONO) $(top_builddir)/build/dll-map-verifier.exe $(srcdir)/$(notdir $@.config) -iwinmm -ilibbanshee -ilibbnpx11 -ilibc -ilibc.so.6 -iintl -ilibmtp.dll -ilibigemacintegration.dylib -iCFRelease $(SOURCES_BUILD); \ fi; $(MCS) \ $(GMCS_FLAGS) \ $(ASSEMBLY_BUILD_FLAGS) \ -nowarn:0278 -nowarn:0078 $$warn \ -define:HAVE_GTK_2_10 -define:NET_2_0 \ -debug -target:$(TARGET) -out:$@ \ $(BUILD_DEFINES) $(ENABLE_TESTS_FLAG) $(ENABLE_ATK_FLAG) \ $(FILTERED_LINK) $(RESOURCES_BUILD) $(SOURCES_BUILD) @if [ -e $(srcdir)/$(notdir $@.config) ]; then \ cp $(srcdir)/$(notdir $@.config) $(top_builddir)/bin; \ fi; @if [ ! -z "$(EXTRA_BUNDLE)" ]; then \ cp $(EXTRA_BUNDLE) $(top_builddir)/bin; \ fi; theme-icons: $(THEME_ICONS_SOURCE) @$(INSTALL_ICONS) -il "$(BUILD_DATA_DIR)" "$(srcdir)" $(THEME_ICONS_RELATIVE) install-data-local: $(THEME_ICONS_SOURCE) @$(INSTALL_ICONS) -i "$(DESTDIR)$(pkgdatadir)" "$(srcdir)" $(THEME_ICONS_RELATIVE) uninstall-local: $(THEME_ICONS_SOURCE) @$(INSTALL_ICONS) -u "$(DESTDIR)$(pkgdatadir)" "$(srcdir)" $(THEME_ICONS_RELATIVE) # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: hyena-0.5/Mono.Data.Sqlite/Makefile.am0000644000175000001440000000217511402517164017661 0ustar00gabeusers00000000000000ASSEMBLY = Mono.Data.Sqlite TARGET = library LINK = -r:System -r:System.Data -r:System.Transactions ASSEMBLY_BUILD_FLAGS = -unsafe -d:MONO_BACKWARD_COMPAT SOURCES = \ Mono.Data.Sqlite/SQLite3.cs \ Mono.Data.Sqlite/SQLite3_UTF16.cs \ Mono.Data.Sqlite/SQLiteBase.cs \ Mono.Data.Sqlite/SQLiteCommand.cs \ Mono.Data.Sqlite/SQLiteCommandBuilder.cs \ Mono.Data.Sqlite/SQLiteConnection.cs \ Mono.Data.Sqlite/SQLiteConnectionStringBuilder.cs \ Mono.Data.Sqlite/SQLiteConvert.cs \ Mono.Data.Sqlite/SQLiteDataAdapter.cs \ Mono.Data.Sqlite/SQLiteDataReader.cs \ Mono.Data.Sqlite/SqliteDataSourceEnumerator.cs \ Mono.Data.Sqlite/SQLiteEnlistment.cs \ Mono.Data.Sqlite/SQLiteException.cs \ Mono.Data.Sqlite/SQLiteFactory.cs \ Mono.Data.Sqlite/SQLiteFunction.cs \ Mono.Data.Sqlite/SQLiteFunctionAttribute.cs \ Mono.Data.Sqlite/SQLiteMetaDataCollectionNames.cs \ Mono.Data.Sqlite/SQLiteParameter.cs \ Mono.Data.Sqlite/SQLiteParameterCollection.cs \ Mono.Data.Sqlite/SQLiteStatement.cs \ Mono.Data.Sqlite/SQLiteTransaction.cs \ Mono.Data.Sqlite/SR.Designer.cs \ Mono.Data.Sqlite/UnsafeNativeMethods.cs include $(top_srcdir)/build/build.mk hyena-0.5/Mono.Data.Sqlite/Mono.Data.Sqlite/0000777000175000001440000000000011453151002020633 5ustar00gabeusers00000000000000hyena-0.5/Mono.Data.Sqlite/Mono.Data.Sqlite/UnsafeNativeMethods.cs0000644000175000001440000003001011377104476025106 0ustar00gabeusers00000000000000// // Mono.Data.Sqlite.UnsafeNativeMethods.cs // // Author(s): // Robert Simpson (robert@blackcastlesoft.com) // // Adapted and modified for the Mono Project by // Marek Habersack (grendello@gmail.com) // // // Copyright (C) 2006 Novell, Inc (http://www.novell.com) // Copyright (C) 2007 Marek Habersack // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // /******************************************************** * ADO.NET 2.0 Data Provider for Sqlite Version 3.X * Written by Robert Simpson (robert@blackcastlesoft.com) * * Released to the public domain, use at your own risk! ********************************************************/ #if NET_2_0 namespace Mono.Data.Sqlite { using System; using System.Security; using System.Runtime.InteropServices; #if !PLATFORM_COMPACTFRAMEWORK [SuppressUnmanagedCodeSecurity] #endif internal sealed class UnsafeNativeMethods { private const string SQLITE_DLL = "sqlite3"; private UnsafeNativeMethods() { } [DllImport(SQLITE_DLL)] internal static extern void sqlite3_sleep(uint dwMilliseconds); [DllImport(SQLITE_DLL)] internal static extern IntPtr sqlite3_libversion(); [DllImport(SQLITE_DLL)] internal static extern void sqlite3_free(IntPtr p); [DllImport(SQLITE_DLL)] internal static extern int sqlite3_open(byte[] utf8Filename, out IntPtr db); [DllImport(SQLITE_DLL)] internal static extern void sqlite3_interrupt(IntPtr db); [DllImport(SQLITE_DLL)] internal static extern int sqlite3_close(IntPtr db); [DllImport(SQLITE_DLL)] internal static extern int sqlite3_exec(IntPtr db, byte[] strSql, IntPtr pvCallback, IntPtr pvParam, out IntPtr errMsg, out int len); [DllImport(SQLITE_DLL)] internal static extern IntPtr sqlite3_errmsg(IntPtr db); [DllImport(SQLITE_DLL)] internal static extern int sqlite3_changes(IntPtr db); [DllImport(SQLITE_DLL)] internal static extern int sqlite3_busy_timeout(IntPtr db, int ms); [DllImport(SQLITE_DLL)] internal static extern int sqlite3_prepare_v2(IntPtr db, IntPtr pSql, int nBytes, out IntPtr stmt, out IntPtr ptrRemain); [DllImport(SQLITE_DLL)] internal static extern int sqlite3_prepare(IntPtr db, IntPtr pSql, int nBytes, out IntPtr stmt, out IntPtr ptrRemain); [DllImport(SQLITE_DLL)] internal static extern int sqlite3_bind_blob(IntPtr stmt, int index, Byte[] value, int nSize, IntPtr nTransient); [DllImport(SQLITE_DLL)] internal static extern int sqlite3_bind_double(IntPtr stmt, int index, double value); [DllImport(SQLITE_DLL)] internal static extern int sqlite3_bind_int(IntPtr stmt, int index, int value); [DllImport(SQLITE_DLL)] internal static extern int sqlite3_bind_int64(IntPtr stmt, int index, long value); [DllImport(SQLITE_DLL)] internal static extern int sqlite3_bind_null(IntPtr stmt, int index); [DllImport(SQLITE_DLL)] internal static extern int sqlite3_bind_text(IntPtr stmt, int index, byte[] value, int nlen, IntPtr pvReserved); [DllImport(SQLITE_DLL)] internal static extern int sqlite3_bind_parameter_count(IntPtr stmt); [DllImport(SQLITE_DLL)] internal static extern IntPtr sqlite3_bind_parameter_name(IntPtr stmt, int index); [DllImport(SQLITE_DLL)] internal static extern int sqlite3_bind_parameter_index(IntPtr stmt, byte[] strName); [DllImport(SQLITE_DLL)] internal static extern int sqlite3_column_count(IntPtr stmt); [DllImport(SQLITE_DLL)] internal static extern IntPtr sqlite3_column_name(IntPtr stmt, int index); [DllImport(SQLITE_DLL)] internal static extern IntPtr sqlite3_column_decltype(IntPtr stmt, int index); [DllImport(SQLITE_DLL)] internal static extern int sqlite3_step(IntPtr stmt); [DllImport(SQLITE_DLL)] internal static extern double sqlite3_column_double(IntPtr stmt, int index); [DllImport(SQLITE_DLL)] internal static extern int sqlite3_column_int(IntPtr stmt, int index); [DllImport(SQLITE_DLL)] internal static extern Int64 sqlite3_column_int64(IntPtr stmt, int index); [DllImport(SQLITE_DLL)] internal static extern IntPtr sqlite3_column_text(IntPtr stmt, int index); [DllImport(SQLITE_DLL)] internal static extern IntPtr sqlite3_column_blob(IntPtr stmt, int index); [DllImport(SQLITE_DLL)] internal static extern int sqlite3_column_bytes(IntPtr stmt, int index); [DllImport(SQLITE_DLL)] internal static extern TypeAffinity sqlite3_column_type(IntPtr stmt, int index); [DllImport(SQLITE_DLL)] internal static extern int sqlite3_finalize(IntPtr stmt); [DllImport(SQLITE_DLL)] internal static extern int sqlite3_reset(IntPtr stmt); [DllImport(SQLITE_DLL)] internal static extern int sqlite3_create_collation(IntPtr db, byte[] strName, int eTextRep, IntPtr ctx, SqliteCollation fcompare); [DllImport(SQLITE_DLL)] internal static extern int sqlite3_create_function(IntPtr db, byte[] strName, int nArgs, int eTextRep, IntPtr app, SqliteCallback func, SqliteCallback fstep, SqliteFinalCallback ffinal); [DllImport(SQLITE_DLL)] internal static extern int sqlite3_aggregate_count(IntPtr context); [DllImport(SQLITE_DLL)] internal static extern IntPtr sqlite3_value_blob(IntPtr p); [DllImport(SQLITE_DLL)] internal static extern int sqlite3_value_bytes(IntPtr p); [DllImport(SQLITE_DLL)] internal static extern double sqlite3_value_double(IntPtr p); [DllImport(SQLITE_DLL)] internal static extern int sqlite3_value_int(IntPtr p); [DllImport(SQLITE_DLL)] internal static extern Int64 sqlite3_value_int64(IntPtr p); [DllImport(SQLITE_DLL)] internal static extern IntPtr sqlite3_value_text(IntPtr p); [DllImport(SQLITE_DLL)] internal static extern TypeAffinity sqlite3_value_type(IntPtr p); [DllImport(SQLITE_DLL)] internal static extern void sqlite3_result_blob(IntPtr context, byte[] value, int nSize, IntPtr pvReserved); [DllImport(SQLITE_DLL)] internal static extern void sqlite3_result_double(IntPtr context, double value); [DllImport(SQLITE_DLL)] internal static extern void sqlite3_result_error(IntPtr context, byte[] strErr, int nLen); [DllImport(SQLITE_DLL)] internal static extern void sqlite3_result_int(IntPtr context, int value); [DllImport(SQLITE_DLL)] internal static extern void sqlite3_result_int64(IntPtr context, Int64 value); [DllImport(SQLITE_DLL)] internal static extern void sqlite3_result_null(IntPtr context); [DllImport(SQLITE_DLL)] internal static extern void sqlite3_result_text(IntPtr context, byte[] value, int nLen, IntPtr pvReserved); [DllImport(SQLITE_DLL)] internal static extern IntPtr sqlite3_aggregate_context(IntPtr context, int nBytes); [DllImport(SQLITE_DLL)] internal static extern int sqlite3_table_column_metadata(IntPtr db, byte[] dbName, byte[] tblName, byte[] colName, out IntPtr ptrDataType, out IntPtr ptrCollSeq, out int notNull, out int primaryKey, out int autoInc); [DllImport(SQLITE_DLL)] internal static extern IntPtr sqlite3_column_database_name(IntPtr stmt, int index); [DllImport(SQLITE_DLL)] internal static extern IntPtr sqlite3_column_database_name16(IntPtr stmt, int index); [DllImport(SQLITE_DLL)] internal static extern IntPtr sqlite3_column_table_name(IntPtr stmt, int index); [DllImport(SQLITE_DLL)] internal static extern IntPtr sqlite3_column_table_name16(IntPtr stmt, int index); [DllImport(SQLITE_DLL)] internal static extern IntPtr sqlite3_column_origin_name(IntPtr stmt, int index); [DllImport(SQLITE_DLL)] internal static extern IntPtr sqlite3_column_origin_name16(IntPtr stmt, int index); [DllImport(SQLITE_DLL)] internal static extern IntPtr sqlite3_column_text16(IntPtr stmt, int index); [DllImport(SQLITE_DLL, CharSet = CharSet.Unicode)] internal static extern int sqlite3_open16(string utf16Filename, out IntPtr db); [DllImport(SQLITE_DLL)] internal static extern IntPtr sqlite3_errmsg16(IntPtr db); [DllImport(SQLITE_DLL, CharSet = CharSet.Unicode)] internal static extern int sqlite3_prepare16_v2(IntPtr db, IntPtr pSql, int sqlLen, out IntPtr stmt, out IntPtr ptrRemain); [DllImport(SQLITE_DLL, CharSet = CharSet.Unicode)] internal static extern int sqlite3_bind_text16(IntPtr stmt, int index, string value, int nlen, int nTransient); [DllImport(SQLITE_DLL)] internal static extern IntPtr sqlite3_column_name16(IntPtr stmt, int index); [DllImport(SQLITE_DLL)] internal static extern IntPtr sqlite3_column_decltype16(IntPtr stmt, int index, out int len); [DllImport(SQLITE_DLL, CharSet = CharSet.Unicode)] internal static extern int sqlite3_create_collation16(IntPtr db, string strName, int eTextRep, IntPtr ctx, SqliteCollation fcompare); [DllImport(SQLITE_DLL, CharSet = CharSet.Unicode)] internal static extern int sqlite3_create_function16(IntPtr db, string strName, int nArgs, int eTextRep, IntPtr app, SqliteCallback func, SqliteCallback funcstep, SqliteFinalCallback funcfinal); [DllImport(SQLITE_DLL)] internal static extern IntPtr sqlite3_value_text16(IntPtr p); [DllImport(SQLITE_DLL, CharSet = CharSet.Unicode)] internal static extern void sqlite3_result_error16(IntPtr context, string strName, int nLen); [DllImport(SQLITE_DLL, CharSet = CharSet.Unicode)] internal static extern void sqlite3_result_text16(IntPtr context, string strName, int nLen, IntPtr pvReserved); [DllImport(SQLITE_DLL, CharSet = CharSet.Unicode, SetLastError = true)] internal static extern int sqlite3_encryptfile(string fileName); [DllImport(SQLITE_DLL, CharSet = CharSet.Unicode, SetLastError = true)] internal static extern int sqlite3_decryptfile(string fileName); [DllImport(SQLITE_DLL, CharSet = CharSet.Unicode, SetLastError = true)] internal static extern int sqlite3_encryptedstatus(string fileName, out int fileStatus); [DllImport(SQLITE_DLL, CharSet = CharSet.Unicode, SetLastError = true)] internal static extern int sqlite3_compressfile(string fileName); [DllImport(SQLITE_DLL, CharSet = CharSet.Unicode, SetLastError = true)] internal static extern int sqlite3_decompressfile(string fileName); [DllImport(SQLITE_DLL)] internal static extern int sqlite3_key(IntPtr db, byte[] key, int keylen); [DllImport(SQLITE_DLL)] internal static extern int sqlite3_rekey(IntPtr db, byte[] key, int keylen); [DllImport(SQLITE_DLL)] internal static extern IntPtr sqlite3_update_hook(IntPtr db, SqliteUpdateCallback func); [DllImport(SQLITE_DLL)] internal static extern IntPtr sqlite3_commit_hook(IntPtr db, SqliteCommitCallback func); [DllImport(SQLITE_DLL)] internal static extern IntPtr sqlite3_rollback_hook(IntPtr db, SqliteRollbackCallback func); [DllImport(SQLITE_DLL)] internal static extern int sqlite3_cursor_rowid(IntPtr stmt, int cursor, out long rowid); [DllImport(SQLITE_DLL)] internal static extern int sqlite3_table_cursor(IntPtr stmt, int db, int tableRootPage); [DllImport(SQLITE_DLL)] internal static extern long sqlite3_last_insert_rowid(IntPtr db); } } #endif hyena-0.5/Mono.Data.Sqlite/Mono.Data.Sqlite/SQLiteTransaction.cs0000644000175000001440000001326311377104476024554 0ustar00gabeusers00000000000000// // Mono.Data.Sqlite.SQLiteTransaction.cs // // Author(s): // Robert Simpson (robert@blackcastlesoft.com) // // Adapted and modified for the Mono Project by // Marek Habersack (grendello@gmail.com) // // // Copyright (C) 2006 Novell, Inc (http://www.novell.com) // Copyright (C) 2007 Marek Habersack // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // /******************************************************** * ADO.NET 2.0 Data Provider for Sqlite Version 3.X * Written by Robert Simpson (robert@blackcastlesoft.com) * * Released to the public domain, use at your own risk! ********************************************************/ #if NET_2_0 namespace Mono.Data.Sqlite { using System; using System.Data; using System.Data.Common; /// /// Sqlite implementation of DbTransaction. /// public sealed class SqliteTransaction : DbTransaction { /// /// The connection to which this transaction is bound /// internal SqliteConnection _cnn; internal long _version; // Matches the version of the connection /// /// Constructs the transaction object, binding it to the supplied connection /// /// The connection to open a transaction on /// TRUE to defer the writelock, or FALSE to lock immediately internal SqliteTransaction(SqliteConnection connection, bool deferredLock) { _cnn = connection; _version = _cnn._version; if (_cnn._transactionLevel++ == 0) { try { using (SqliteCommand cmd = _cnn.CreateCommand()) { if (!deferredLock) cmd.CommandText = "BEGIN IMMEDIATE"; else cmd.CommandText = "BEGIN"; cmd.ExecuteNonQuery(); } } catch (SqliteException) { _cnn._transactionLevel--; _cnn = null; throw; } } } /// /// Commits the current transaction. /// public override void Commit() { IsValid(true); if (--_cnn._transactionLevel == 0) { try { using (SqliteCommand cmd = _cnn.CreateCommand()) { cmd.CommandText = "COMMIT"; cmd.ExecuteNonQuery(); } } finally { _cnn = null; } } else { _cnn = null; } } /// /// Returns the underlying connection to which this transaction applies. /// public new SqliteConnection Connection { get { return _cnn; } } /// /// Forwards to the local Connection property /// protected override DbConnection DbConnection { get { return Connection; } } /// /// Disposes the transaction. If it is currently active, any changes are rolled back. /// protected override void Dispose(bool disposing) { if (IsValid(false)) Rollback(); _cnn = null; base.Dispose(disposing); } /// /// Gets the isolation level of the transaction. Sqlite only supports Serializable transactions. /// public override IsolationLevel IsolationLevel { get { return IsolationLevel.Serializable; } } /// /// Rolls back the active transaction. /// public override void Rollback() { IsValid(true); try { using (SqliteCommand cmd = _cnn.CreateCommand()) { cmd.CommandText = "ROLLBACK"; cmd.ExecuteNonQuery(); } _cnn._transactionLevel = 0; } finally { _cnn = null; } } internal bool IsValid(bool throwError) { if (_cnn == null) { if (throwError == true) throw new ArgumentNullException("No connection associated with this transaction"); else return false; } if (_cnn._transactionLevel == 0) { if (throwError == true) throw new SqliteException((int)SqliteErrorCode.Misuse, "No transaction is active on this connection"); else return false; } if (_cnn._version != _version) { if (throwError == true) throw new SqliteException((int)SqliteErrorCode.Misuse, "The connection was closed and re-opened, changes were rolled back"); else return false; } if (_cnn.State != ConnectionState.Open) { if (throwError == true) throw new SqliteException((int)SqliteErrorCode.Misuse, "Connection was closed"); else return false; } return true; } } } #endif hyena-0.5/Mono.Data.Sqlite/Mono.Data.Sqlite/SQLiteCommand.cs0000644000175000001440000004571411377104476023653 0ustar00gabeusers00000000000000// // Mono.Data.Sqlite.SQLiteCommand.cs // // Author(s): // Robert Simpson (robert@blackcastlesoft.com) // // Adapted and modified for the Mono Project by // Marek Habersack (grendello@gmail.com) // // // Copyright (C) 2006 Novell, Inc (http://www.novell.com) // Copyright (C) 2007 Marek Habersack // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // /******************************************************** * ADO.NET 2.0 Data Provider for SQLite Version 3.X * Written by Robert Simpson (robert@blackcastlesoft.com) * * Released to the public domain, use at your own risk! ********************************************************/ #if NET_2_0 namespace Mono.Data.Sqlite { using System; using System.Data; using System.Data.Common; using System.Collections.Generic; using System.ComponentModel; /// /// Sqlite implementation of DbCommand. /// #if !PLATFORM_COMPACTFRAMEWORK [Designer("Sqlite.Designer.SqliteCommandDesigner, Sqlite.Designer, Version=1.0.31.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139"), ToolboxItem(true)] #endif public sealed class SqliteCommand : DbCommand, ICloneable { /// /// The command text this command is based on /// private string _commandText; /// /// The connection the command is associated with /// private SqliteConnection _cnn; /// /// Indicates whether or not a DataReader is active on the command. /// private SqliteDataReader _activeReader; /// /// The timeout for the command, kludged because Sqlite doesn't support per-command timeout values /// internal int _commandTimeout; /// /// Designer support /// private bool _designTimeVisible; /// /// Used by DbDataAdapter to determine updating behavior /// private UpdateRowSource _updateRowSource; /// /// The collection of parameters for the command /// private SqliteParameterCollection _parameterCollection; /// /// The SQL command text, broken into individual SQL statements as they are executed /// internal List _statementList; /// /// Unprocessed SQL text that has not been executed /// internal string _remainingText; /// /// Transaction associated with this command /// private SqliteTransaction _transaction; /// /// Constructs a new SqliteCommand /// /// /// Default constructor /// public SqliteCommand() :this(null, null) { } /// /// Initializes the command with the given command text /// /// The SQL command text public SqliteCommand(string commandText) : this(commandText, null, null) { } /// /// Initializes the command with the given SQL command text and attach the command to the specified /// connection. /// /// The SQL command text /// The connection to associate with the command public SqliteCommand(string commandText, SqliteConnection connection) : this(commandText, connection, null) { } /// /// Initializes the command and associates it with the specified connection. /// /// The connection to associate with the command public SqliteCommand(SqliteConnection connection) : this(null, connection, null) { } private SqliteCommand(SqliteCommand source) : this(source.CommandText, source.Connection, source.Transaction) { CommandTimeout = source.CommandTimeout; DesignTimeVisible = source.DesignTimeVisible; UpdatedRowSource = source.UpdatedRowSource; foreach (SqliteParameter param in source._parameterCollection) { Parameters.Add(param.Clone()); } } /// /// Initializes a command with the given SQL, connection and transaction /// /// The SQL command text /// The connection to associate with the command /// The transaction the command should be associated with public SqliteCommand(string commandText, SqliteConnection connection, SqliteTransaction transaction) { _statementList = null; _activeReader = null; _commandTimeout = connection != null ? connection._busyTimeout : 30; _parameterCollection = new SqliteParameterCollection(this); _designTimeVisible = true; _updateRowSource = UpdateRowSource.FirstReturnedRecord; _transaction = null; if (commandText != null) CommandText = commandText; if (connection != null) DbConnection = connection; if (transaction != null) Transaction = transaction; } /// /// Disposes of the command and clears all member variables /// /// Whether or not the class is being explicitly or implicitly disposed protected override void Dispose(bool disposing) { base.Dispose(disposing); // If a reader is active on this command, don't destroy it completely if (_activeReader != null) { _activeReader._disposeCommand = true; return; } Connection = null; _parameterCollection.Clear(); _commandText = null; } /// /// Clears and destroys all statements currently prepared /// internal void ClearCommands() { if (_activeReader != null) _activeReader.Close(); if (_statementList == null) return; int x = _statementList.Count; for (int n = 0; n < x; n++) _statementList[n].Dispose(); _statementList = null; _parameterCollection.Unbind(); } /// /// Builds an array of prepared statements for each complete SQL statement in the command text /// internal SqliteStatement BuildNextCommand() { SqliteStatement stmt = null; try { if (_statementList == null) _remainingText = _commandText; stmt = _cnn._sql.Prepare(_remainingText, (_statementList == null) ? null : _statementList[_statementList.Count - 1], out _remainingText); if (stmt != null) { stmt._command = this; if (_statementList == null) _statementList = new List(); _statementList.Add(stmt); _parameterCollection.MapParameters(stmt); stmt.BindParameters(); } return stmt; } catch (Exception) { if (stmt != null) { if (_statementList.Contains(stmt)) _statementList.Remove(stmt); stmt.Dispose(); } // If we threw an error compiling the statement, we cannot continue on so set the remaining text to null. _remainingText = null; throw; } } internal SqliteStatement GetStatement(int index) { // Haven't built any statements yet if (_statementList == null) return BuildNextCommand(); // If we're at the last built statement and want the next unbuilt statement, then build it if (index == _statementList.Count) { if (String.IsNullOrEmpty(_remainingText) == false) return BuildNextCommand(); else return null; // No more commands } SqliteStatement stmt = _statementList[index]; stmt.BindParameters(); return stmt; } /// /// Not implemented /// public override void Cancel() { } /// /// The SQL command text associated with the command /// #if !PLATFORM_COMPACTFRAMEWORK [DefaultValue(""), RefreshProperties(RefreshProperties.All), Editor("Microsoft.VSDesigner.Data.SQL.Design.SqlCommandTextEditor, Microsoft.VSDesigner, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Drawing.Design.UITypeEditor, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")] #endif public override string CommandText { get { return _commandText; } set { if (_commandText == value) return; if (_activeReader != null) { throw new InvalidOperationException("Cannot set CommandText while a DataReader is active"); } ClearCommands(); _commandText = value; if (_cnn == null) return; } } /// /// The amount of time to wait for the connection to become available before erroring out /// #if !PLATFORM_COMPACTFRAMEWORK [DefaultValue((int)30)] #endif public override int CommandTimeout { get { return _commandTimeout; } set { _commandTimeout = value; } } /// /// The type of the command. Sqlite only supports CommandType.Text /// #if !PLATFORM_COMPACTFRAMEWORK [RefreshProperties(RefreshProperties.All), DefaultValue(CommandType.Text)] #endif public override CommandType CommandType { get { return CommandType.Text; } set { if (value != CommandType.Text) { throw new NotSupportedException(); } } } /// /// Forwards to the local CreateParameter() function /// /// protected override DbParameter CreateDbParameter() { return CreateParameter(); } /// /// Create a new parameter /// /// public new SqliteParameter CreateParameter() { return new SqliteParameter(); } /// /// The connection associated with this command /// #if !PLATFORM_COMPACTFRAMEWORK [DefaultValue((string)null), Editor("Microsoft.VSDesigner.Data.Design.DbConnectionEditor, Microsoft.VSDesigner, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Drawing.Design.UITypeEditor, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")] #endif public new SqliteConnection Connection { get { return _cnn; } set { if (_activeReader != null) throw new InvalidOperationException("Cannot set Connection while a DataReader is active"); if (_cnn != null) { ClearCommands(); _cnn.RemoveCommand(this); } _cnn = value; if (_cnn != null) _cnn.AddCommand(this); } } /// /// Forwards to the local Connection property /// protected override DbConnection DbConnection { get { return Connection; } set { Connection = (SqliteConnection)value; } } /// /// Returns the SqliteParameterCollection for the given command /// #if !PLATFORM_COMPACTFRAMEWORK [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] #endif public new SqliteParameterCollection Parameters { get { return _parameterCollection; } } /// /// Forwards to the local Parameters property /// protected override DbParameterCollection DbParameterCollection { get { return Parameters; } } /// /// The transaction associated with this command. Sqlite only supports one transaction per connection, so this property forwards to the /// command's underlying connection. /// #if !PLATFORM_COMPACTFRAMEWORK [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] #endif public new SqliteTransaction Transaction { get { return _transaction; } set { if (_cnn != null) { if (_activeReader != null) throw new InvalidOperationException("Cannot set Transaction while a DataReader is active"); if (value != null) { if (value._cnn != _cnn) throw new ArgumentException("Transaction is not associated with the command's connection"); } _transaction = value; } else if (value != null) throw new ArgumentOutOfRangeException("SqliteTransaction", "Not associated with a connection"); } } /// /// Forwards to the local Transaction property /// protected override DbTransaction DbTransaction { get { return Transaction; } set { Transaction = (SqliteTransaction)value; } } /// /// This function ensures there are no active readers, that we have a valid connection, /// that the connection is open, that all statements are prepared and all parameters are assigned /// in preparation for allocating a data reader. /// private void InitializeForReader() { if (_activeReader != null) throw new InvalidOperationException("DataReader already active on this command"); if (_cnn == null) throw new InvalidOperationException("No connection associated with this command"); if (_cnn.State != ConnectionState.Open) throw new InvalidOperationException("Database is not open"); // Map all parameters for statements already built _parameterCollection.MapParameters(null); // Set the default command timeout _cnn._sql.SetTimeout(_commandTimeout * 1000); } /// /// Creates a new SqliteDataReader to execute/iterate the array of Sqlite prepared statements /// /// The behavior the data reader should adopt /// Returns a SqliteDataReader object protected override DbDataReader ExecuteDbDataReader(CommandBehavior behavior) { return ExecuteReader(behavior); } /// /// Overrides the default behavior to return a SqliteDataReader specialization class /// /// The flags to be associated with the reader /// A SqliteDataReader public new SqliteDataReader ExecuteReader(CommandBehavior behavior) { InitializeForReader(); SqliteDataReader rd = new SqliteDataReader(this, behavior); _activeReader = rd; return rd; } /// /// Overrides the default behavior of DbDataReader to return a specialized SqliteDataReader class /// /// A SqliteDataReader public new SqliteDataReader ExecuteReader() { return ExecuteReader(CommandBehavior.Default); } /// /// Called by the SqliteDataReader when the data reader is closed. /// internal void ClearDataReader() { _activeReader = null; } /// /// Execute the command and return the number of rows inserted/updated affected by it. /// /// public override int ExecuteNonQuery() { InitializeForReader(); int nAffected = 0; int x = 0; SqliteStatement stmt; for(;;) { stmt = GetStatement(x); x++; if (stmt == null) break; _cnn._sql.Step(stmt); nAffected += _cnn._sql.Changes; _cnn._sql.Reset(stmt); } return nAffected; } /// /// Execute the command and return the first column of the first row of the resultset /// (if present), or null if no resultset was returned. /// /// The first column of the first row of the first resultset from the query public override object ExecuteScalar() { InitializeForReader(); int x = 0; object ret = null; SqliteType typ = new SqliteType(); SqliteStatement stmt; // We step through every statement in the command, but only grab the first row of the first resultset. // We keep going even after obtaining it. for (;;) { stmt = GetStatement(x); x++; if (stmt == null) break; if (_cnn._sql.Step(stmt) == true && ret == null) { ret = _cnn._sql.GetValue(stmt, 0, typ); } _cnn._sql.Reset(stmt); } return ret; } /// /// Does nothing. Commands are prepared as they are executed the first time, and kept in prepared state afterwards. /// public override void Prepare() { } /// /// Sets the method the SqliteCommandBuilder uses to determine how to update inserted or updated rows in a DataTable. /// [DefaultValue(UpdateRowSource.FirstReturnedRecord)] public override UpdateRowSource UpdatedRowSource { get { return _updateRowSource; } set { _updateRowSource = value; } } /// /// Determines if the command is visible at design time. Defaults to True. /// #if !PLATFORM_COMPACTFRAMEWORK [DesignOnly(true), Browsable(false), DefaultValue(true), EditorBrowsable(EditorBrowsableState.Never)] #endif public override bool DesignTimeVisible { get { return _designTimeVisible; } set { _designTimeVisible = value; #if !PLATFORM_COMPACTFRAMEWORK TypeDescriptor.Refresh(this); #endif } } /// /// Clones a command, including all its parameters /// /// A new SqliteCommand with the same commandtext, connection and parameters public object Clone() { return new SqliteCommand(this); } public long LastInsertRowID () { return _cnn.LastInsertRowId; } } } #endif hyena-0.5/Mono.Data.Sqlite/Mono.Data.Sqlite/SQLiteConvert.cs0000644000175000001440000004752711377104476023721 0ustar00gabeusers00000000000000// // Mono.Data.Sqlite.SQLiteConvert.cs // // Author(s): // Robert Simpson (robert@blackcastlesoft.com) // // Adapted and modified for the Mono Project by // Marek Habersack (grendello@gmail.com) // // // Copyright (C) 2006 Novell, Inc (http://www.novell.com) // Copyright (C) 2007 Marek Habersack // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // /******************************************************** * ADO.NET 2.0 Data Provider for Sqlite Version 3.X * Written by Robert Simpson (robert@blackcastlesoft.com) * * Released to the public domain, use at your own risk! ********************************************************/ #if NET_2_0 namespace Mono.Data.Sqlite { using System; using System.Data; using System.Runtime.InteropServices; using System.Collections.Generic; using System.ComponentModel; using System.Globalization; using System.Text; #if !PLATFORM_COMPACTFRAMEWORK using System.ComponentModel.Design; #endif /// /// Sqlite has very limited types, and is inherently text-based. The first 5 types below represent the sum of all types Sqlite /// understands. The DateTime extension to the spec is for internal use only. /// public enum TypeAffinity { /// /// Not used /// Uninitialized = 0, /// /// All integers in Sqlite default to Int64 /// Int64 = 1, /// /// All floating point numbers in Sqlite default to double /// Double = 2, /// /// The default data type of Sqlite is text /// Text = 3, /// /// Typically blob types are only seen when returned from a function /// Blob = 4, /// /// Null types can be returned from functions /// Null = 5, /// /// Used internally by this provider /// DateTime = 10, /// /// Used internally /// None = 11, } /// /// This implementation of Sqlite for ADO.NET can process date/time fields in databases in only one of two formats. Ticks and ISO8601. /// Ticks is inherently more accurate, but less compatible with 3rd party tools that query the database, and renders the DateTime field /// unreadable without post-processing. /// ISO8601 is more compatible, readable, fully-processable, but less accurate as it doesn't provide time down to fractions of a second. /// public enum SqliteDateFormats { /// /// Using ticks is more accurate but less compatible with other viewers and utilities that access your database. /// Ticks = 0, /// /// The default format for this provider. /// ISO8601 = 1, } /// /// Struct used internally to determine the datatype of a column in a resultset /// internal class SqliteType { /// /// The DbType of the column, or DbType.Object if it cannot be determined /// internal DbType Type; /// /// The affinity of a column, used for expressions or when Type is DbType.Object /// internal TypeAffinity Affinity; } /// /// This base class provides datatype conversion services for the Sqlite provider. /// public abstract class SqliteConvert { /// /// An array of ISO8601 datetime formats we support conversion from /// private static string[] _datetimeFormats = new string[] { "yyyy-MM-dd HH:mm:ss.fffffff", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyyMMddHHmmss", "yyyyMMddHHmm", "yyyyMMddTHHmmssfffffff", "yyyy-MM-dd", "yy-MM-dd", "yyyyMMdd", "HH:mm:ss", "HH:mm", "THHmmss", "THHmm", "yyyy-MM-dd HH:mm:ss.fff", "yyyy-MM-ddTHH:mm", "yyyy-MM-ddTHH:mm:ss", "yyyy-MM-ddTHH:mm:ss.fff", "yyyy-MM-ddTHH:mm:ss.ffffff", "HH:mm:ss.fff" }; /// /// An UTF-8 Encoding instance, so we can convert strings to and from UTF-8 /// private Encoding _utf8 = new UTF8Encoding(); /// /// The default DateTime format for this instance /// internal SqliteDateFormats _datetimeFormat; /// /// Initializes the conversion class /// /// The default date/time format to use for this instance internal SqliteConvert(SqliteDateFormats fmt) { _datetimeFormat = fmt; } #region UTF-8 Conversion Functions /// /// Converts a string to a UTF-8 encoded byte array sized to include a null-terminating character. /// /// The string to convert to UTF-8 /// A byte array containing the converted string plus an extra 0 terminating byte at the end of the array. public byte[] ToUTF8(string sourceText) { Byte[] byteArray; int nlen = _utf8.GetByteCount(sourceText) + 1; byteArray = new byte[nlen]; nlen = _utf8.GetBytes(sourceText, 0, sourceText.Length, byteArray, 0); byteArray[nlen] = 0; return byteArray; } /// /// Convert a DateTime to a UTF-8 encoded, zero-terminated byte array. /// /// /// This function is a convenience function, which first calls ToString() on the DateTime, and then calls ToUTF8() with the /// string result. /// /// The DateTime to convert. /// The UTF-8 encoded string, including a 0 terminating byte at the end of the array. public byte[] ToUTF8(DateTime dateTimeValue) { return ToUTF8(ToString(dateTimeValue)); } /// /// Converts a UTF-8 encoded IntPtr of the specified length into a .NET string /// /// The pointer to the memory where the UTF-8 string is encoded /// The number of bytes to decode /// A string containing the translated character(s) public virtual string ToString(IntPtr nativestring) { return UTF8ToString(nativestring); } /// /// Converts a UTF-8 encoded IntPtr of the specified length into a .NET string /// /// The pointer to the memory where the UTF-8 string is encoded /// The number of bytes to decode /// A string containing the translated character(s) public virtual string UTF8ToString(IntPtr nativestring) { if (nativestring == IntPtr.Zero) return null; // This assumes a single byte terminates the string. int len = 0; while (Marshal.ReadByte (nativestring, len) != 0) checked {++len;} unsafe { string s = new string ((sbyte*) nativestring, 0, len, _utf8); len = s.Length; while (len > 0 && s [len-1] == 0) --len; if (len == s.Length) return s; return s.Substring (0, len); } } #endregion #region DateTime Conversion Functions /// /// Converts a string into a DateTime, using the current DateTimeFormat specified for the connection when it was opened. /// /// /// Acceptable ISO8601 DateTime formats are: /// yyyy-MM-dd HH:mm:ss /// yyyyMMddHHmmss /// yyyyMMddTHHmmssfffffff /// yyyy-MM-dd /// yy-MM-dd /// yyyyMMdd /// HH:mm:ss /// THHmmss /// /// The string containing either a Tick value or an ISO8601-format string /// A DateTime value public DateTime ToDateTime(string dateText) { switch (_datetimeFormat) { case SqliteDateFormats.Ticks: return new DateTime(Convert.ToInt64(dateText, CultureInfo.InvariantCulture)); default: return DateTime.ParseExact(dateText, _datetimeFormats, DateTimeFormatInfo.InvariantInfo, DateTimeStyles.None); } } /// /// Converts a DateTime to a string value, using the current DateTimeFormat specified for the connection when it was opened. /// /// The DateTime value to convert /// Either a string consisting of the tick count for DateTimeFormat.Ticks, or a date/time in ISO8601 format. public string ToString(DateTime dateValue) { switch (_datetimeFormat) { case SqliteDateFormats.Ticks: return dateValue.Ticks.ToString(CultureInfo.InvariantCulture); default: return dateValue.ToString(_datetimeFormats[0], CultureInfo.InvariantCulture); } } /// /// Internal function to convert a UTF-8 encoded IntPtr of the specified length to a DateTime. /// /// /// This is a convenience function, which first calls ToString() on the IntPtr to convert it to a string, then calls /// ToDateTime() on the string to return a DateTime. /// /// A pointer to the UTF-8 encoded string /// The length in bytes of the string /// The parsed DateTime value internal DateTime ToDateTime(IntPtr ptr) { return ToDateTime(ToString(ptr)); } #endregion /// /// Smart method of splitting a string. Skips quoted elements, removes the quotes. /// /// /// This split function works somewhat like the String.Split() function in that it breaks apart a string into /// pieces and returns the pieces as an array. The primary differences are: /// /// Only one character can be provided as a separator character /// Quoted text inside the string is skipped over when searching for the separator, and the quotes are removed. /// /// Thus, if splitting the following string looking for a comma:
/// One,Two, "Three, Four", Five
///
/// The resulting array would contain
/// [0] One
/// [1] Two
/// [2] Three, Four
/// [3] Five
///
/// Note that the leading and trailing spaces were removed from each item during the split. ///
/// Source string to split apart /// Separator character /// A string array of the split up elements public static string[] Split(string source, char separator) { char[] toks = new char[2] { '\"', separator }; char[] quot = new char[1] { '\"' }; int n = 0; List ls = new List(); string s; while (source.Length > 0) { n = source.IndexOfAny(toks, n); if (n == -1) break; if (source[n] == toks[0]) { source = source.Remove(n, 1); n = source.IndexOfAny(quot, n); if (n == -1) { source = "\"" + source; break; } source = source.Remove(n, 1); } else { s = source.Substring(0, n).Trim(); source = source.Substring(n + 1).Trim(); if (s.Length > 0) ls.Add(s); n = 0; } } if (source.Length > 0) ls.Add(source); string[] ar = new string[ls.Count]; ls.CopyTo(ar, 0); return ar; } #region Type Conversions /// /// Determines the data type of a column in a statement /// /// The statement to retrieve information for /// The column to retrieve type information on /// Returns a SqliteType struct internal static SqliteType ColumnToType(SqliteStatement stmt, int i) { SqliteType typ = new SqliteType (); typ.Type = TypeNameToDbType(stmt._sql.ColumnType(stmt, i, out typ.Affinity)); return typ; } /// /// Converts a SqliteType to a .NET Type object /// /// The SqliteType to convert /// Returns a .NET Type object internal static Type SqliteTypeToType(SqliteType t) { if (t.Type != DbType.Object) return SqliteConvert.DbTypeToType(t.Type); return _typeaffinities[(int)t.Affinity]; } static Type[] _typeaffinities = { null, typeof(Int64), typeof(Double), typeof(string), typeof(byte[]), typeof(DBNull), null, null, null, null, typeof(DateTime), null, }; /// /// For a given intrinsic type, return a DbType /// /// The native type to convert /// The corresponding (closest match) DbType internal static DbType TypeToDbType(Type typ) { TypeCode tc = Type.GetTypeCode(typ); if (tc == TypeCode.Object) { if (typ == typeof(byte[])) return DbType.Binary; if (typ == typeof(Guid)) return DbType.Guid; return DbType.String; } return _typetodbtype[(int)tc]; } private static DbType[] _typetodbtype = { DbType.Object, DbType.Binary, DbType.Object, DbType.Boolean, DbType.SByte, DbType.SByte, DbType.Byte, DbType.Int16, // 7 DbType.UInt16, DbType.Int32, DbType.UInt32, DbType.Int64, // 11 DbType.UInt64, DbType.Single, DbType.Double, DbType.Decimal, DbType.DateTime, DbType.Object, DbType.String, }; /// /// Returns the ColumnSize for the given DbType /// /// The DbType to get the size of /// internal static int DbTypeToColumnSize(DbType typ) { return _dbtypetocolumnsize[(int)typ]; } private static int[] _dbtypetocolumnsize = { 2147483647, // 0 2147483647, // 1 1, // 2 1, // 3 8, // 4 8, // 5 8, // 6 8, // 7 8, // 8 16, // 9 2, 4, 8, 2147483647, 1, 4, 2147483647, 8, 2, 4, 8, 8, 2147483647, 2147483647, 2147483647, 2147483647, // 25 (Xml) }; /// /// Convert a DbType to a Type /// /// The DbType to convert from /// The closest-match .NET type internal static Type DbTypeToType(DbType typ) { return _dbtypeToType[(int)typ]; } private static Type[] _dbtypeToType = { typeof(string), // 0 typeof(byte[]), // 1 typeof(byte), // 2 typeof(bool), // 3 typeof(decimal), // 4 typeof(DateTime), // 5 typeof(DateTime), // 6 typeof(decimal), // 7 typeof(double), // 8 typeof(Guid), // 9 typeof(Int16), typeof(Int32), typeof(Int64), typeof(object), typeof(sbyte), typeof(float), typeof(string), typeof(DateTime), typeof(UInt16), typeof(UInt32), typeof(UInt64), typeof(double), typeof(string), typeof(string), typeof(string), typeof(string), // 25 (Xml) }; /// /// For a given type, return the closest-match Sqlite TypeAffinity, which only understands a very limited subset of types. /// /// The type to evaluate /// The Sqlite type affinity for that type. internal static TypeAffinity TypeToAffinity(Type typ) { TypeCode tc = Type.GetTypeCode(typ); if (tc == TypeCode.Object) { if (typ == typeof(byte[]) || typ == typeof(Guid)) return TypeAffinity.Blob; else return TypeAffinity.Text; } return _typecodeAffinities[(int)tc]; } private static TypeAffinity[] _typecodeAffinities = { TypeAffinity.Null, TypeAffinity.Blob, TypeAffinity.Null, TypeAffinity.Int64, TypeAffinity.Int64, TypeAffinity.Int64, TypeAffinity.Int64, TypeAffinity.Int64, // 7 TypeAffinity.Int64, TypeAffinity.Int64, TypeAffinity.Int64, TypeAffinity.Int64, // 11 TypeAffinity.Int64, TypeAffinity.Double, TypeAffinity.Double, TypeAffinity.Double, TypeAffinity.DateTime, TypeAffinity.Null, TypeAffinity.Text, }; /// /// For a given type name, return a closest-match .NET type /// /// The name of the type to match /// The .NET DBType the text evaluates to. internal static DbType TypeNameToDbType(string Name) { if (String.IsNullOrEmpty(Name)) return DbType.Object; DbType t; if (_typeNames.TryGetValue(Name, out t)) { return t; } else if (_typeNames.TryGetValue (Name.ToUpperInvariant (), out t)) { _typeNames[Name] = t; return t; } return DbType.Object; } #endregion // All the strings below must be uppercase private static Dictionary _typeNames = new Dictionary() { {"COUNTER", DbType.Int64}, {"AUTOINCREMENT", DbType.Int64}, {"IDENTITY", DbType.Int64}, {"LONGTEXT", DbType.String}, {"LONGCHAR", DbType.String}, {"LONGVARCHAR", DbType.String}, {"LONG", DbType.Int64}, {"TINYINT", DbType.Byte}, {"INTEGER", DbType.Int64}, {"INT", DbType.Int32}, {"VARCHAR", DbType.String}, {"NVARCHAR", DbType.String}, {"CHAR", DbType.String}, {"NCHAR", DbType.String}, {"TEXT", DbType.String}, {"NTEXT", DbType.String}, {"STRING", DbType.String}, {"DOUBLE", DbType.Double}, {"FLOAT", DbType.Double}, {"REAL", DbType.Single}, {"BIT", DbType.Boolean}, {"YESNO", DbType.Boolean}, {"LOGICAL", DbType.Boolean}, {"BOOL", DbType.Boolean}, {"NUMERIC", DbType.Decimal}, {"DECIMAL", DbType.Decimal}, {"MONEY", DbType.Decimal}, {"CURRENCY", DbType.Decimal}, {"TIME", DbType.DateTime}, {"DATE", DbType.DateTime}, {"SMALLDATE", DbType.DateTime}, {"BLOB", DbType.Binary}, {"BINARY", DbType.Binary}, {"VARBINARY", DbType.Binary}, {"IMAGE", DbType.Binary}, {"GENERAL", DbType.Binary}, {"OLEOBJECT", DbType.Binary}, {"GUID", DbType.Guid}, {"UNIQUEIDENTIFIER", DbType.Guid}, {"MEMO", DbType.String}, {"NOTE", DbType.String}, {"SMALLINT", DbType.Int16}, {"BIGINT", DbType.Int64}, }; } } #endif hyena-0.5/Mono.Data.Sqlite/Mono.Data.Sqlite/SqliteDataSourceEnumerator.cs0000644000175000001440000000461011377104476026457 0ustar00gabeusers00000000000000// // Mono.Data.Sqlite.SqliteDataSourceEnumerator.cs // // Author(s): // Chris Toshok (toshok@ximian.com) // Marek Habersack (grendello@gmail.com) // // // Copyright (C) 2006 Novell, Inc (http://www.novell.com) // Copyright (C) 2007 Marek Habersack // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // #if NET_2_0 using System; using System.Data; using System.Data.Common; namespace Mono.Data.Sqlite { public class SqliteDataSourceEnumerator : DbDataSourceEnumerator { public SqliteDataSourceEnumerator () { } public override DataTable GetDataSources () { DataTable dt = new DataTable (); DataColumn col; col = new DataColumn ("ServerName", typeof (string)); dt.Columns.Add (col); col = new DataColumn ("InstanceName", typeof (string)); dt.Columns.Add (col); col = new DataColumn ("IsClustered", typeof (bool)); dt.Columns.Add (col); col = new DataColumn ("Version", typeof (string)); dt.Columns.Add (col); col = new DataColumn ("FactoryName", typeof (string)); dt.Columns.Add (col); DataRow dr = dt.NewRow (); dr [0] = "Sqlite Embedded Database"; dr [1] = "Sqlite Default Instance"; dr [2] = false; dr [3] = "?"; dr [4] = "Mono.Data.Sqlite.SqliteConnectionFactory"; dt.Rows.Add (dr); return dt; } } } #endif hyena-0.5/Mono.Data.Sqlite/Mono.Data.Sqlite/SQLiteParameterCollection.cs0000644000175000001440000003733311377104476026227 0ustar00gabeusers00000000000000// // Mono.Data.Sqlite.SQLiteParameterCollection.cs // // Author(s): // Robert Simpson (robert@blackcastlesoft.com) // // Adapted and modified for the Mono Project by // Marek Habersack (grendello@gmail.com) // // // Copyright (C) 2006 Novell, Inc (http://www.novell.com) // Copyright (C) 2007 Marek Habersack // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // /******************************************************** * ADO.NET 2.0 Data Provider for Sqlite Version 3.X * Written by Robert Simpson (robert@blackcastlesoft.com) * * Released to the public domain, use at your own risk! ********************************************************/ #if NET_2_0 namespace Mono.Data.Sqlite { using System; using System.Data; using System.Data.Common; using System.Collections.Generic; using System.Globalization; using System.ComponentModel; using System.Reflection; /// /// Sqlite implementation of DbParameterCollection. /// #if !PLATFORM_COMPACTFRAMEWORK [Editor("Microsoft.VSDesigner.Data.Design.DBParametersEditor, Microsoft.VSDesigner, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Drawing.Design.UITypeEditor, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"), ListBindable(false)] #endif public sealed class SqliteParameterCollection : DbParameterCollection { /// /// The underlying command to which this collection belongs /// private SqliteCommand _command; /// /// The internal array of parameters in this collection /// private List _parameterList; /// /// Determines whether or not all parameters have been bound to their statement(s) /// private bool _unboundFlag; /// /// Initializes the collection /// /// The command to which the collection belongs internal SqliteParameterCollection(SqliteCommand cmd) { _command = cmd; _parameterList = new List(); _unboundFlag = true; } /// /// Returns true /// public override bool IsSynchronized { get { return true; } } /// /// Returns false /// public override bool IsFixedSize { get { return false; } } /// /// Returns false /// public override bool IsReadOnly { get { return false; } } /// /// Returns null /// public override object SyncRoot { get { return null; } } /// /// Retrieves an enumerator for the collection /// /// An enumerator for the underlying array public override System.Collections.IEnumerator GetEnumerator() { return _parameterList.GetEnumerator(); } /// /// Adds a parameter to the collection /// /// The parameter name /// The data type /// The size of the value /// The source column /// A SqliteParameter object public SqliteParameter Add(string parameterName, DbType parameterType, int parameterSize, string sourceColumn) { SqliteParameter param = new SqliteParameter(parameterName, parameterType, parameterSize, sourceColumn); Add(param); return param; } /// /// Adds a parameter to the collection /// /// The parameter name /// The data type /// The size of the value /// A SqliteParameter object public SqliteParameter Add(string parameterName, DbType parameterType, int parameterSize) { SqliteParameter param = new SqliteParameter(parameterName, parameterType, parameterSize); Add(param); return param; } /// /// Adds a parameter to the collection /// /// The parameter name /// The data type /// A SqliteParameter object public SqliteParameter Add(string parameterName, DbType parameterType) { SqliteParameter param = new SqliteParameter(parameterName, parameterType); Add(param); return param; } /// /// Adds a parameter to the collection /// /// The parameter to add /// A zero-based index of where the parameter is located in the array public int Add(SqliteParameter parameter) { int n = -1; if (parameter.ParameterName != null) { n = IndexOf(parameter.ParameterName); } if (n == -1) { n = _parameterList.Count; _parameterList.Add((SqliteParameter)parameter); } SetParameter(n, parameter); return n; } /// /// Adds a parameter to the collection /// /// The parameter to add /// A zero-based index of where the parameter is located in the array #if !PLATFORM_COMPACTFRAMEWORK [EditorBrowsable(EditorBrowsableState.Never)] #endif public override int Add(object value) { return Add((SqliteParameter)value); } /// /// Adds a named/unnamed parameter and its value to the parameter collection. /// /// Name of the parameter, or null to indicate an unnamed parameter /// The initial value of the parameter /// Returns the SqliteParameter object created during the call. public SqliteParameter AddWithValue(string parameterName, object value) { SqliteParameter param = new SqliteParameter(parameterName, value); Add(param); return param; } /// /// Adds an array of parameters to the collection /// /// The array of parameters to add public void AddRange(SqliteParameter[] values) { int x = values.Length; for (int n = 0; n < x; n++) Add(values[n]); } /// /// Adds an array of parameters to the collection /// /// The array of parameters to add public override void AddRange(Array values) { int x = values.Length; for (int n = 0; n < x; n++) Add((SqliteParameter)(values.GetValue(n))); } /// /// Clears the array and resets the collection /// public override void Clear() { _unboundFlag = true; _parameterList.Clear(); } /// /// Determines if the named parameter exists in the collection /// /// The name of the parameter to check /// True if the parameter is in the collection public override bool Contains(string parameterName) { return (IndexOf(parameterName) != -1); } /// /// Determines if the parameter exists in the collection /// /// The SqliteParameter to check /// True if the parameter is in the collection public override bool Contains(object value) { return _parameterList.Contains((SqliteParameter)value); } /// /// Not implemented /// /// /// public override void CopyTo(Array array, int index) { throw new NotImplementedException(); } /// /// Returns a count of parameters in the collection /// public override int Count { get { return _parameterList.Count; } } /// /// Overloaded to specialize the return value of the default indexer /// /// Name of the parameter to get/set /// The specified named Sqlite parameter public new SqliteParameter this[string parameterName] { get { return (SqliteParameter)GetParameter(parameterName); } set { SetParameter(parameterName, value); } } /// /// Overloaded to specialize the return value of the default indexer /// /// The index of the parameter to get/set /// The specified Sqlite parameter public new SqliteParameter this[int index] { get { return (SqliteParameter)GetParameter(index); } set { SetParameter(index, value); } } /// /// Retrieve a parameter by name from the collection /// /// The name of the parameter to fetch /// A DbParameter object protected override DbParameter GetParameter(string parameterName) { return GetParameter(IndexOf(parameterName)); } /// /// Retrieves a parameter by its index in the collection /// /// The index of the parameter to retrieve /// A DbParameter object protected override DbParameter GetParameter(int index) { return _parameterList[index]; } /// /// Returns the index of a parameter given its name /// /// The name of the parameter to find /// -1 if not found, otherwise a zero-based index of the parameter public override int IndexOf(string parameterName) { int x = _parameterList.Count; for (int n = 0; n < x; n++) { if (String.Compare(parameterName, _parameterList[n].ParameterName, true, CultureInfo.InvariantCulture) == 0) return n; } return -1; } /// /// Returns the index of a parameter /// /// The parameter to find /// -1 if not found, otherwise a zero-based index of the parameter public override int IndexOf(object value) { return _parameterList.IndexOf((SqliteParameter)value); } /// /// Inserts a parameter into the array at the specified location /// /// The zero-based index to insert the parameter at /// The parameter to insert public override void Insert(int index, object value) { _unboundFlag = true; _parameterList.Insert(index, (SqliteParameter)value); } /// /// Removes a parameter from the collection /// /// The parameter to remove public override void Remove(object value) { _unboundFlag = true; _parameterList.Remove((SqliteParameter)value); } /// /// Removes a parameter from the collection given its name /// /// The name of the parameter to remove public override void RemoveAt(string parameterName) { RemoveAt(IndexOf(parameterName)); } /// /// Removes a parameter from the collection given its index /// /// The zero-based parameter index to remove public override void RemoveAt(int index) { _unboundFlag = true; _parameterList.RemoveAt(index); } /// /// Re-assign the named parameter to a new parameter object /// /// The name of the parameter to replace /// The new parameter protected override void SetParameter(string parameterName, DbParameter value) { SetParameter(IndexOf(parameterName), value); } /// /// Re-assign a parameter at the specified index /// /// The zero-based index of the parameter to replace /// The new parameter protected override void SetParameter(int index, DbParameter value) { _unboundFlag = true; _parameterList[index] = (SqliteParameter)value; } /// /// Un-binds all parameters from their statements /// internal void Unbind() { _unboundFlag = true; } /// /// This function attempts to map all parameters in the collection to all statements in a Command. /// Since named parameters may span multiple statements, this function makes sure all statements are bound /// to the same named parameter. Unnamed parameters are bound in sequence. /// internal void MapParameters(SqliteStatement activeStatement) { if (_unboundFlag == false || _parameterList.Count == 0 || _command._statementList == null) return; int nUnnamed = 0; string s; int n; int y = -1; SqliteStatement stmt; foreach(SqliteParameter p in _parameterList) { y ++; s = p.ParameterName; if (s == null) { s = String.Format(CultureInfo.InvariantCulture, ";{0}", nUnnamed); nUnnamed++; } int x; bool isMapped = false; if (activeStatement == null) x = _command._statementList.Count; else x = 1; stmt = activeStatement; for (n = 0; n < x; n++) { isMapped = false; if (stmt == null) stmt = _command._statementList[n]; if (stmt._paramNames != null) { if (stmt.MapParameter(s, p) == true) isMapped = true; } stmt = null; } // If the parameter has a name, but the SQL statement uses unnamed references, this can happen -- attempt to map // the parameter by its index in the collection if (isMapped == false) { s = String.Format(CultureInfo.InvariantCulture, ";{0}", y); stmt = activeStatement; for (n = 0; n < x; n++) { if (stmt == null) stmt = _command._statementList[n]; if (stmt._paramNames != null) { if (stmt.MapParameter(s, p) == true) isMapped = true; } stmt = null; } } } if (activeStatement == null) _unboundFlag = false; } } } #endif hyena-0.5/Mono.Data.Sqlite/Mono.Data.Sqlite/SQLiteFunction.cs0000644000175000001440000005340311377104476024054 0ustar00gabeusers00000000000000// // Mono.Data.Sqlite.SQLiteFunction.cs // // Author(s): // Robert Simpson (robert@blackcastlesoft.com) // // Adapted and modified for the Mono Project by // Marek Habersack (grendello@gmail.com) // // // Copyright (C) 2006 Novell, Inc (http://www.novell.com) // Copyright (C) 2007 Marek Habersack // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // /******************************************************** * ADO.NET 2.0 Data Provider for Sqlite Version 3.X * Written by Robert Simpson (robert@blackcastlesoft.com) * * Released to the public domain, use at your own risk! ********************************************************/ #if NET_2_0 namespace Mono.Data.Sqlite { using System; using System.Collections; using System.Collections.Generic; using System.Runtime.InteropServices; using System.Globalization; /// /// The type of user-defined function to declare /// public enum FunctionType { /// /// Scalar functions are designed to be called and return a result immediately. Examples include ABS(), Upper(), Lower(), etc. /// Scalar = 0, /// /// Aggregate functions are designed to accumulate data until the end of a call and then return a result gleaned from the accumulated data. /// Examples include SUM(), COUNT(), AVG(), etc. /// Aggregate = 1, /// /// Collation sequences are used to sort textual data in a custom manner, and appear in an ORDER BY clause. Typically text in an ORDER BY is /// sorted using a straight case-insensitive comparison function. Custom collating sequences can be used to alter the behavior of text sorting /// in a user-defined manner. /// Collation = 2, } /// /// An internal callback delegate declaration. /// /// Raw context pointer for the user function /// Count of arguments to the function /// A pointer to the array of argument pointers internal delegate void SqliteCallback(IntPtr context, int nArgs, IntPtr argsptr); /// /// An internal callback delegate declaration. /// /// Raw context pointer for the user function internal delegate void SqliteFinalCallback(IntPtr context); /// /// Internal callback delegate for implementing collation sequences /// /// Length of the string pv1 /// Pointer to the first string to compare /// Length of the string pv2 /// Pointer to the second string to compare /// Returns -1 if the first string is less than the second. 0 if they are equal, or 1 if the first string is greater /// than the second. internal delegate int SqliteCollation(int len1, IntPtr pv1, int len2, IntPtr pv2); /// /// This abstract class is designed to handle user-defined functions easily. An instance of the derived class is made for each /// connection to the database. /// /// /// Although there is one instance of a class derived from SqliteFunction per database connection, the derived class has no access /// to the underlying connection. This is necessary to deter implementers from thinking it would be a good idea to make database /// calls during processing. /// /// It is important to distinguish between a per-connection instance, and a per-SQL statement context. One instance of this class /// services all SQL statements being stepped through on that connection, and there can be many. One should never store per-statement /// information in member variables of user-defined function classes. /// /// For aggregate functions, always create and store your per-statement data in the contextData object on the 1st step. This data will /// be automatically freed for you (and Dispose() called if the item supports IDisposable) when the statement completes. /// public abstract class SqliteFunction : IDisposable { /// /// The base connection this function is attached to /// private SqliteBase _base; /// /// Internal array used to keep track of aggregate function context data /// private Dictionary _contextDataList; /// /// Holds a reference to the callback function for user functions /// private SqliteCallback _InvokeFunc; /// /// Holds a reference to the callbakc function for stepping in an aggregate function /// private SqliteCallback _StepFunc; /// /// Holds a reference to the callback function for finalizing an aggregate function /// private SqliteFinalCallback _FinalFunc; /// /// Holds a reference to the callback function for collation sequences /// private SqliteCollation _CompareFunc; /// /// This static list contains all the user-defined functions declared using the proper attributes. /// private static List _registeredFunctions = new List(); /// /// Internal constructor, initializes the function's internal variables. /// protected SqliteFunction() { _contextDataList = new Dictionary(); } /// /// Returns a reference to the underlying connection's SqliteConvert class, which can be used to convert /// strings and DateTime's into the current connection's encoding schema. /// public SqliteConvert SqliteConvert { get { return _base; } } /// /// Scalar functions override this method to do their magic. /// /// /// Parameters passed to functions have only an affinity for a certain data type, there is no underlying schema available /// to force them into a certain type. Therefore the only types you will ever see as parameters are /// DBNull.Value, Int64, Double, String or byte[] array. /// /// The arguments for the command to process /// You may return most simple types as a return value, null or DBNull.Value to return null, DateTime, or /// you may return an Exception-derived class if you wish to return an error to Sqlite. Do not actually throw the error, /// just return it! public virtual object Invoke(object[] args) { return null; } /// /// Aggregate functions override this method to do their magic. /// /// /// Typically you'll be updating whatever you've placed in the contextData field and returning as quickly as possible. /// /// The arguments for the command to process /// The 1-based step number. This is incrememted each time the step method is called. /// A placeholder for implementers to store contextual data pertaining to the current context. public virtual void Step(object[] args, int stepNumber, ref object contextData) { } /// /// Aggregate functions override this method to finish their aggregate processing. /// /// /// If you implemented your aggregate function properly, /// you've been recording and keeping track of your data in the contextData object provided, and now at this stage you should have /// all the information you need in there to figure out what to return. /// NOTE: It is possible to arrive here without receiving a previous call to Step(), in which case the contextData will /// be null. This can happen when no rows were returned. You can either return null, or 0 or some other custom return value /// if that is the case. /// /// Your own assigned contextData, provided for you so you can return your final results. /// You may return most simple types as a return value, null or DBNull.Value to return null, DateTime, or /// you may return an Exception-derived class if you wish to return an error to Sqlite. Do not actually throw the error, /// just return it! /// public virtual object Final(object contextData) { return null; } /// /// User-defined collation sequences override this method to provide a custom string sorting algorithm. /// /// The first string to compare /// The second strnig to compare /// 1 if param1 is greater than param2, 0 if they are equal, or -1 if param1 is less than param2 public virtual int Compare(string param1, string param2) { return 0; } /// /// Converts an IntPtr array of context arguments to an object array containing the resolved parameters the pointers point to. /// /// /// Parameters passed to functions have only an affinity for a certain data type, there is no underlying schema available /// to force them into a certain type. Therefore the only types you will ever see as parameters are /// DBNull.Value, Int64, Double, String or byte[] array. /// /// The number of arguments /// A pointer to the array of arguments /// An object array of the arguments once they've been converted to .NET values internal object[] ConvertParams(int nArgs, IntPtr argsptr) { object[] parms = new object[nArgs]; #if !PLATFORM_COMPACTFRAMEWORK IntPtr[] argint = new IntPtr[nArgs]; #else int[] argint = new int[nArgs]; #endif Marshal.Copy(argsptr, argint, 0, nArgs); for (int n = 0; n < nArgs; n++) { switch (_base.GetParamValueType((IntPtr)argint[n])) { case TypeAffinity.Null: parms[n] = DBNull.Value; break; case TypeAffinity.Int64: parms[n] = _base.GetParamValueInt64((IntPtr)argint[n]); break; case TypeAffinity.Double: parms[n] = _base.GetParamValueDouble((IntPtr)argint[n]); break; case TypeAffinity.Text: parms[n] = _base.GetParamValueText((IntPtr)argint[n]); break; case TypeAffinity.Blob: { int x; byte[] blob; x = (int)_base.GetParamValueBytes((IntPtr)argint[n], 0, null, 0, 0); blob = new byte[x]; _base.GetParamValueBytes((IntPtr)argint[n], 0, blob, 0, x); parms[n] = blob; } break; case TypeAffinity.DateTime: // Never happens here but what the heck, maybe it will one day. parms[n] = _base.ToDateTime(_base.GetParamValueText((IntPtr)argint[n])); break; } } return parms; } /// /// Takes the return value from Invoke() and Final() and figures out how to return it to Sqlite's context. /// /// The context the return value applies to /// The parameter to return to Sqlite void SetReturnValue(IntPtr context, object returnValue) { if (returnValue == null || returnValue == DBNull.Value) { _base.ReturnNull(context); return; } Type t = returnValue.GetType(); if (t == typeof(DateTime)) { _base.ReturnText(context, _base.ToString((DateTime)returnValue)); return; } else { Exception r = returnValue as Exception; if (r != null) { _base.ReturnError(context, r.Message); return; } } switch (SqliteConvert.TypeToAffinity(t)) { case TypeAffinity.Null: _base.ReturnNull(context); return; case TypeAffinity.Int64: _base.ReturnInt64(context, Convert.ToInt64(returnValue, CultureInfo.CurrentCulture)); return; case TypeAffinity.Double: _base.ReturnDouble(context, Convert.ToDouble(returnValue, CultureInfo.CurrentCulture)); return; case TypeAffinity.Text: _base.ReturnText(context, returnValue.ToString()); return; case TypeAffinity.Blob: _base.ReturnBlob(context, (byte[])returnValue); return; } } /// /// Internal scalar callback function, which wraps the raw context pointer and calls the virtual Invoke() method. /// /// A raw context pointer /// Number of arguments passed in /// A pointer to the array of arguments internal void ScalarCallback(IntPtr context, int nArgs, IntPtr argsptr) { SetReturnValue(context, Invoke(ConvertParams(nArgs, argsptr))); } /// /// Internal collation sequence function, which wraps up the raw string pointers and executes the Compare() virtual function. /// /// Length of the string pv1 /// Pointer to the first string to compare /// Length of the string pv2 /// Pointer to the second string to compare /// Returns -1 if the first string is less than the second. 0 if they are equal, or 1 if the first string is greater /// than the second. internal int CompareCallback(int len1, IntPtr ptr1, int len2, IntPtr ptr2) { return Compare(_base.ToString(ptr1), _base.ToString(ptr2)); } /// /// The internal aggregate Step function callback, which wraps the raw context pointer and calls the virtual Step() method. /// /// /// This function takes care of doing the lookups and getting the important information put together to call the Step() function. /// That includes pulling out the user's contextData and updating it after the call is made. We use a sorted list for this so /// binary searches can be done to find the data. /// /// A raw context pointer /// Number of arguments passed in /// A pointer to the array of arguments internal void StepCallback(IntPtr context, int nArgs, IntPtr argsptr) { int n = _base.AggregateCount(context); long nAux; object obj = null; nAux = (long)_base.AggregateContext(context); if (n > 1) obj = _contextDataList[nAux]; Step(ConvertParams(nArgs, argsptr), n, ref obj); _contextDataList[nAux] = obj; } /// /// An internal aggregate Final function callback, which wraps the context pointer and calls the virtual Final() method. /// /// A raw context pointer internal void FinalCallback(IntPtr context) { long n = (long)_base.AggregateContext(context); object obj = null; if (_contextDataList.ContainsKey(n)) { obj = _contextDataList[n]; _contextDataList.Remove(n); } SetReturnValue(context, Final(obj)); IDisposable disp = obj as IDisposable; if (disp != null) disp.Dispose(); } /// /// Placeholder for a user-defined disposal routine /// /// True if the object is being disposed explicitly protected virtual void Dispose(bool disposing) { } /// /// Disposes of any active contextData variables that were not automatically cleaned up. Sometimes this can happen if /// someone closes the connection while a DataReader is open. /// public void Dispose() { Dispose(true); IDisposable disp; foreach (KeyValuePair kv in _contextDataList) { disp = kv.Value as IDisposable; if (disp != null) disp.Dispose(); } _contextDataList.Clear(); _InvokeFunc = null; _StepFunc = null; _FinalFunc = null; _CompareFunc = null; _base = null; _contextDataList = null; GC.SuppressFinalize(this); } #if !PLATFORM_COMPACTFRAMEWORK /// /// Using reflection, enumerate all assemblies in the current appdomain looking for classes that /// have a SqliteFunctionAttribute attribute, and registering them accordingly. /// static SqliteFunction() { SqliteFunctionAttribute at; System.Reflection.Assembly[] arAssemblies = System.AppDomain.CurrentDomain.GetAssemblies(); int w = arAssemblies.Length; System.Reflection.AssemblyName sqlite = System.Reflection.Assembly.GetCallingAssembly().GetName(); for (int n = 0; n < w; n++) { Type[] arTypes; bool found = false; System.Reflection.AssemblyName[] references; try { // Inspect only assemblies that reference SQLite references = arAssemblies[n].GetReferencedAssemblies(); int t = references.Length; for (int z = 0; z < t; z++) { if (references[z].Name == sqlite.Name) { found = true; break; } } if (found == false) continue; arTypes = arAssemblies[n].GetTypes(); } catch (System.Reflection.ReflectionTypeLoadException e) { arTypes = e.Types; } int v = arTypes.Length; for (int x = 0; x < v; x++) { if (arTypes[x] == null) continue; object[] arAtt = arTypes[x].GetCustomAttributes(typeof(SqliteFunctionAttribute), false); int u = arAtt.Length; for (int y = 0; y < u; y++) { at = arAtt[y] as SqliteFunctionAttribute; if (at != null) { at._instanceType = arTypes[x]; _registeredFunctions.Add(at); } } } } } #else /// /// Manual method of registering a function. The type must still have the SqliteFunctionAttributes in order to work /// properly, but this is a workaround for the Compact Framework where enumerating assemblies is not currently supported. /// /// The type of the function to register public static void RegisterFunction(Type typ) { object[] arAtt = typ.GetCustomAttributes(typeof(SqliteFunctionAttribute), false); int u = arAtt.Length; SqliteFunctionAttribute at; for (int y = 0; y < u; y++) { at = arAtt[y] as SqliteFunctionAttribute; if (at != null) { at._instanceType = typ; _registeredFunctions.Add(at); } } } #endif /// /// Called by SqliteBase derived classes, this function binds all user-defined functions to a connection. /// It is done this way so that all user-defined functions will access the database using the same encoding scheme /// as the connection (UTF-8 or UTF-16). /// /// The base object on which the functions are to bind /// Returns an array of functions which the connection object should retain until the connection is closed. internal static SqliteFunction[] BindFunctions(SqliteBase sqlbase) { SqliteFunction f; List lFunctions = new List(); foreach (SqliteFunctionAttribute pr in _registeredFunctions) { f = (SqliteFunction)Activator.CreateInstance(pr._instanceType); f._base = sqlbase; f._InvokeFunc = (pr.FuncType == FunctionType.Scalar) ? new SqliteCallback(f.ScalarCallback) : null; f._StepFunc = (pr.FuncType == FunctionType.Aggregate) ? new SqliteCallback(f.StepCallback) : null; f._FinalFunc = (pr.FuncType == FunctionType.Aggregate) ? new SqliteFinalCallback(f.FinalCallback) : null; f._CompareFunc = (pr.FuncType == FunctionType.Collation) ? new SqliteCollation(f.CompareCallback) : null; if (pr.FuncType != FunctionType.Collation) sqlbase.CreateFunction(pr.Name, pr.Arguments, f._InvokeFunc, f._StepFunc, f._FinalFunc); else sqlbase.CreateCollation(pr.Name, f._CompareFunc); lFunctions.Add(f); } SqliteFunction[] arFunctions = new SqliteFunction[lFunctions.Count]; lFunctions.CopyTo(arFunctions, 0); return arFunctions; } } } #endif hyena-0.5/Mono.Data.Sqlite/Mono.Data.Sqlite/SQLiteMetaDataCollectionNames.cs0000644000175000001440000000605711377104476026752 0ustar00gabeusers00000000000000// // Mono.Data.Sqlite.SQLiteMetaDataCollectionNames.cs // // Author(s): // Robert Simpson (robert@blackcastlesoft.com) // // Adapted and modified for the Mono Project by // Marek Habersack (grendello@gmail.com) // // // Copyright (C) 2006 Novell, Inc (http://www.novell.com) // Copyright (C) 2007 Marek Habersack // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // /******************************************************** * ADO.NET 2.0 Data Provider for Sqlite Version 3.X * Written by Robert Simpson (robert@blackcastlesoft.com) * * Released to the public domain, use at your own risk! ********************************************************/ #if NET_2_0 namespace Mono.Data.Sqlite { using System; /// /// MetaDataCollections specific to Sqlite /// public static class SqliteMetaDataCollectionNames { /// /// Returns a list of databases attached to the connection /// public static readonly string Catalogs = "Catalogs"; /// /// Returns column information for the specified table /// public static readonly string Columns = "Columns"; /// /// Returns index information for the optionally-specified table /// public static readonly string Indexes = "Indexes"; /// /// Returns base columns for the given index /// public static readonly string IndexColumns = "IndexColumns"; /// /// Returns the tables in the given catalog /// public static readonly string Tables = "Tables"; /// /// Returns user-defined views in the given catalog /// public static readonly string Views = "Views"; /// /// Returns underlying column information on the given view /// public static readonly string ViewColumns = "ViewColumns"; /// /// Returns foreign key information for the given catalog /// public static readonly string ForeignKeys = "ForeignKeys"; } } #endif hyena-0.5/Mono.Data.Sqlite/Mono.Data.Sqlite/SQLiteEnlistment.cs0000644000175000001440000000670111377104476024410 0ustar00gabeusers00000000000000// // Mono.Data.Sqlite.SQLiteEnlistment.cs // // Author(s): // Robert Simpson (robert@blackcastlesoft.com) // // Adapted and modified for the Mono Project by // Marek Habersack (grendello@gmail.com) // // // Copyright (C) 2006 Novell, Inc (http://www.novell.com) // Copyright (C) 2007 Marek Habersack // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // /******************************************************* * ADO.NET 2.0 Data Provider for Sqlite Version 3.X * Written by Robert Simpson (robert@blackcastlesoft.com) * * Released to the public domain, use at your own risk! ********************************************************/ #if NET_2_0 #if !PLATFORM_COMPACTFRAMEWORK namespace Mono.Data.Sqlite { using System; using System.Data; using System.Data.Common; using System.Transactions; internal class SqliteEnlistment : IEnlistmentNotification { internal SqliteTransaction _transaction; internal Transaction _scope; internal bool _disposeConnection; internal SqliteEnlistment(SqliteConnection cnn, Transaction scope) { _transaction = cnn.BeginTransaction(); _scope = scope; _disposeConnection = false; _scope.EnlistVolatile(this, System.Transactions.EnlistmentOptions.None); } private void Cleanup(SqliteConnection cnn) { if (_disposeConnection) cnn.Dispose(); _transaction = null; _scope = null; } #region IEnlistmentNotification Members public void Commit(Enlistment enlistment) { SqliteConnection cnn = _transaction.Connection; cnn._enlistment = null; try { _transaction.IsValid(true); _transaction.Connection._transactionLevel = 1; _transaction.Commit(); enlistment.Done(); } finally { Cleanup(cnn); } } public void InDoubt(Enlistment enlistment) { enlistment.Done(); } public void Prepare(PreparingEnlistment preparingEnlistment) { if (_transaction.IsValid(false) == false) preparingEnlistment.ForceRollback(); else preparingEnlistment.Prepared(); } public void Rollback(Enlistment enlistment) { SqliteConnection cnn = _transaction.Connection; cnn._enlistment = null; try { _transaction.Rollback(); enlistment.Done(); } finally { Cleanup(cnn); } } #endregion } } #endif // !PLATFORM_COMPACT_FRAMEWORK #endif hyena-0.5/Mono.Data.Sqlite/Mono.Data.Sqlite/SQLite3_UTF16.cs0000644000175000001440000001323511377104476023315 0ustar00gabeusers00000000000000// // Mono.Data.Sqlite.SQLite3_UTF16.cs // // Author(s): // Robert Simpson (robert@blackcastlesoft.com) // // Adapted and modified for the Mono Project by // Marek Habersack (grendello@gmail.com) // // // Copyright (C) 2006 Novell, Inc (http://www.novell.com) // Copyright (C) 2007 Marek Habersack // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // /******************************************************** * ADO.NET 2.0 Data Provider for SQLite Version 3.X * Written by Robert Simpson (robert@blackcastlesoft.com) * * Released to the public domain, use at your own risk! ********************************************************/ #if NET_2_0 namespace Mono.Data.Sqlite { using System; using System.Runtime.InteropServices; /// /// Alternate Sqlite3 object, overriding many text behaviors to support UTF-16 (Unicode) /// internal class Sqlite3_UTF16 : Sqlite3 { internal Sqlite3_UTF16(SqliteDateFormats fmt) : base(fmt) { } /// /// Overrides SqliteConvert.ToString() to marshal UTF-16 strings instead of UTF-8 /// /// A pointer to a UTF-16 string /// The length (IN BYTES) of the string /// A .NET string public override string ToString(IntPtr b) { return Marshal.PtrToStringUni(b); } internal override string Version { get { return base.ToString(UnsafeNativeMethods.sqlite3_libversion()); } } internal override void Open(string strFilename) { if (_sql != IntPtr.Zero) return; int n = UnsafeNativeMethods.sqlite3_open16(strFilename, out _sql); if (n > 0) throw new SqliteException(n, SqliteLastError()); _functionsArray = SqliteFunction.BindFunctions(this); } internal override string SqliteLastError() { return ToString(UnsafeNativeMethods.sqlite3_errmsg16(_sql)); } internal override void Bind_DateTime(SqliteStatement stmt, int index, DateTime dt) { Bind_Text(stmt, index, ToString(dt)); } internal override string Bind_ParamName(SqliteStatement stmt, int index) { return base.ToString(UnsafeNativeMethods.sqlite3_bind_parameter_name(stmt._sqlite_stmt, index)); } internal override void Bind_Text(SqliteStatement stmt, int index, string value) { int n = UnsafeNativeMethods.sqlite3_bind_text16(stmt._sqlite_stmt, index, value, value.Length * 2, -1); if (n > 0) throw new SqliteException(n, SqliteLastError()); } internal override string ColumnName(SqliteStatement stmt, int index) { return ToString(UnsafeNativeMethods.sqlite3_column_name16(stmt._sqlite_stmt, index)); } internal override DateTime GetDateTime(SqliteStatement stmt, int index) { return ToDateTime(GetText(stmt, index)); } internal override string GetText(SqliteStatement stmt, int index) { return ToString (UnsafeNativeMethods.sqlite3_column_text16(stmt._sqlite_stmt, index)); } internal override string ColumnOriginalName(SqliteStatement stmt, int index) { return ToString(UnsafeNativeMethods.sqlite3_column_origin_name16(stmt._sqlite_stmt, index)); } internal override string ColumnDatabaseName(SqliteStatement stmt, int index) { return ToString(UnsafeNativeMethods.sqlite3_column_database_name16(stmt._sqlite_stmt, index)); } internal override string ColumnTableName(SqliteStatement stmt, int index) { return ToString(UnsafeNativeMethods.sqlite3_column_table_name16(stmt._sqlite_stmt, index)); } internal override void CreateFunction(string strFunction, int nArgs, SqliteCallback func, SqliteCallback funcstep, SqliteFinalCallback funcfinal) { int n = UnsafeNativeMethods.sqlite3_create_function16(_sql, strFunction, nArgs, 4, IntPtr.Zero, func, funcstep, funcfinal); if (n > 0) throw new SqliteException(n, SqliteLastError()); } internal override void CreateCollation(string strCollation, SqliteCollation func) { int n = UnsafeNativeMethods.sqlite3_create_collation16(_sql, strCollation, 4, IntPtr.Zero, func); if (n > 0) throw new SqliteException(n, SqliteLastError()); } internal override string GetParamValueText(IntPtr ptr) { return ToString(UnsafeNativeMethods.sqlite3_value_text16(ptr)); } internal override void ReturnError(IntPtr context, string value) { UnsafeNativeMethods.sqlite3_result_error16(context, value, value.Length); } internal override void ReturnText(IntPtr context, string value) { UnsafeNativeMethods.sqlite3_result_text16(context, value, value.Length, (IntPtr)(-1)); } } } #endif hyena-0.5/Mono.Data.Sqlite/Mono.Data.Sqlite/SQLiteFunctionAttribute.cs0000644000175000001440000000615711377104476025744 0ustar00gabeusers00000000000000// // Mono.Data.Sqlite.SQLiteFunctionAttribute.cs // // Author(s): // Robert Simpson (robert@blackcastlesoft.com) // // Adapted and modified for the Mono Project by // Marek Habersack (grendello@gmail.com) // // // Copyright (C) 2006 Novell, Inc (http://www.novell.com) // Copyright (C) 2007 Marek Habersack // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // /******************************************************** * ADO.NET 2.0 Data Provider for Sqlite Version 3.X * Written by Robert Simpson (robert@blackcastlesoft.com) * * Released to the public domain, use at your own risk! ********************************************************/ #if NET_2_0 namespace Mono.Data.Sqlite { using System; using System.Runtime.InteropServices; /// /// A simple custom attribute to enable us to easily find user-defined functions in /// the loaded assemblies and initialize them in Sqlite as connections are made. /// [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = true)] public class SqliteFunctionAttribute : Attribute { private string _name; private int _arguments; private FunctionType _functionType; internal Type _instanceType; /// /// Default constructor, initializes the internal variables for the function. /// public SqliteFunctionAttribute() { Name = ""; Arguments = -1; FuncType = FunctionType.Scalar; } /// /// The function's name as it will be used in Sqlite command text. /// public string Name { get { return _name; } set { _name = value; } } /// /// The number of arguments this function expects. -1 if the number of arguments is variable. /// public int Arguments { get { return _arguments; } set { _arguments = value; } } /// /// The type of function this implementation will be. /// public FunctionType FuncType { get { return _functionType; } set { _functionType = value; } } } } #endif hyena-0.5/Mono.Data.Sqlite/Mono.Data.Sqlite/SQLiteDataAdapter.cs0000644000175000001440000001740011377104476024436 0ustar00gabeusers00000000000000// // Mono.Data.Sqlite.SQLiteDataAdapter.cs // // Author(s): // Robert Simpson (robert@blackcastlesoft.com) // // Adapted and modified for the Mono Project by // Marek Habersack (grendello@gmail.com) // // // Copyright (C) 2006 Novell, Inc (http://www.novell.com) // Copyright (C) 2007 Marek Habersack // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // /******************************************************** * ADO.NET 2.0 Data Provider for Sqlite Version 3.X * Written by Robert Simpson (robert@blackcastlesoft.com) * * Released to the public domain, use at your own risk! ********************************************************/ #if NET_2_0 namespace Mono.Data.Sqlite { using System; using System.Data; using System.Data.Common; using System.ComponentModel; /// /// Sqlite implementation of DbDataAdapter. /// #if !PLATFORM_COMPACTFRAMEWORK [DefaultEvent("RowUpdated")] [ToolboxItem("Sqlite.Designer.SqliteDataAdapterToolboxItem, Sqlite.Designer, Version=1.0.31.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139")] [Designer("Microsoft.VSDesigner.Data.VS.SqlDataAdapterDesigner, Microsoft.VSDesigner, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")] #endif public sealed class SqliteDataAdapter : DbDataAdapter { private static object _updatingEventPH = new object(); private static object _updatedEventPH = new object(); /// /// This class is just a shell around the DbDataAdapter. Nothing from DbDataAdapter is overridden here, just a few constructors are defined. /// /// /// Default constructor. /// public SqliteDataAdapter() { } /// /// Constructs a data adapter using the specified select command. /// /// The select command to associate with the adapter. public SqliteDataAdapter(SqliteCommand cmd) { SelectCommand = cmd; } /// /// Constructs a data adapter with the supplied select command text and associated with the specified connection. /// /// The select command text to associate with the data adapter. /// The connection to associate with the select command. public SqliteDataAdapter(string commandText, SqliteConnection connection) { SelectCommand = new SqliteCommand(commandText, connection); } /// /// Constructs a data adapter with the specified select command text, and using the specified database connection string. /// /// The select command text to use to construct a select command. /// A connection string suitable for passing to a new SqliteConnection, which is associated with the select command. public SqliteDataAdapter(string commandText, string connectionString) { SqliteConnection cnn = new SqliteConnection(connectionString); SelectCommand = new SqliteCommand(commandText, cnn); } /// /// Row updating event handler /// public event EventHandler RowUpdating { add { base.Events.AddHandler(_updatingEventPH, value); } remove { base.Events.RemoveHandler(_updatingEventPH, value); } } /// /// Row updated event handler /// public event EventHandler RowUpdated { add { base.Events.AddHandler(_updatedEventPH, value); } remove { base.Events.RemoveHandler(_updatedEventPH, value); } } /// /// Raised by the underlying DbDataAdapter when a row is being updated /// /// The event's specifics protected override void OnRowUpdating(RowUpdatingEventArgs value) { EventHandler handler = base.Events[_updatingEventPH] as EventHandler; if (handler != null) handler(this, value); } /// /// Raised by DbDataAdapter after a row is updated /// /// The event's specifics protected override void OnRowUpdated(RowUpdatedEventArgs value) { EventHandler handler = base.Events[_updatedEventPH] as EventHandler; if (handler != null) handler(this, value); } /// /// Gets/sets the select command for this DataAdapter /// #if !PLATFORM_COMPACTFRAMEWORK [DefaultValue((string)null), Editor("Microsoft.VSDesigner.Data.Design.DBCommandEditor, Microsoft.VSDesigner, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Drawing.Design.UITypeEditor, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")] #endif public new SqliteCommand SelectCommand { get { return (SqliteCommand)base.SelectCommand; } set { base.SelectCommand = value; } } /// /// Gets/sets the insert command for this DataAdapter /// #if !PLATFORM_COMPACTFRAMEWORK [DefaultValue((string)null), Editor("Microsoft.VSDesigner.Data.Design.DBCommandEditor, Microsoft.VSDesigner, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Drawing.Design.UITypeEditor, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")] #endif public new SqliteCommand InsertCommand { get { return (SqliteCommand)base.InsertCommand; } set { base.InsertCommand = value; } } /// /// Gets/sets the update command for this DataAdapter /// #if !PLATFORM_COMPACTFRAMEWORK [DefaultValue((string)null), Editor("Microsoft.VSDesigner.Data.Design.DBCommandEditor, Microsoft.VSDesigner, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Drawing.Design.UITypeEditor, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")] #endif public new SqliteCommand UpdateCommand { get { return (SqliteCommand)base.UpdateCommand; } set { base.UpdateCommand = value; } } /// /// Gets/sets the delete command for this DataAdapter /// #if !PLATFORM_COMPACTFRAMEWORK [DefaultValue((string)null), Editor("Microsoft.VSDesigner.Data.Design.DBCommandEditor, Microsoft.VSDesigner, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Drawing.Design.UITypeEditor, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")] #endif public new SqliteCommand DeleteCommand { get { return (SqliteCommand)base.DeleteCommand; } set { base.DeleteCommand = value; } } } } #endif hyena-0.5/Mono.Data.Sqlite/Mono.Data.Sqlite/SQLiteFactory.cs0000644000175000001440000000704511377104476023677 0ustar00gabeusers00000000000000// // Mono.Data.Sqlite.SQLiteFactory.cs // // Author(s): // Robert Simpson (robert@blackcastlesoft.com) // // Adapted and modified for the Mono Project by // Marek Habersack (grendello@gmail.com) // // // Copyright (C) 2006 Novell, Inc (http://www.novell.com) // Copyright (C) 2007 Marek Habersack // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // /******************************************************** * ADO.NET 2.0 Data Provider for Sqlite Version 3.X * Written by Robert Simpson (robert@blackcastlesoft.com) * * Released to the public domain, use at your own risk! ********************************************************/ #if NET_2_0 namespace Mono.Data.Sqlite { using System; using System.Data.Common; #if !PLATFORM_COMPACTFRAMEWORK /// /// Sqlite implementation of DbProviderFactory. /// public sealed class SqliteFactory : DbProviderFactory { /// /// Static instance member which returns an instanced SqliteFactory class. /// public static readonly SqliteFactory Instance = new SqliteFactory(); /// /// Returns a new SqliteCommand object. /// /// A SqliteCommand object. public override DbCommand CreateCommand() { return new SqliteCommand(); } /// /// Returns a new SqliteCommandBuilder object. /// /// A SqliteCommandBuilder object. public override DbCommandBuilder CreateCommandBuilder() { return new SqliteCommandBuilder(); } /// /// Creates a new SqliteConnection. /// /// A SqliteConnection object. public override DbConnection CreateConnection() { return new SqliteConnection(); } /// /// Creates a new SqliteConnectionStringBuilder. /// /// A SqliteConnectionStringBuilder object. public override DbConnectionStringBuilder CreateConnectionStringBuilder() { return new SqliteConnectionStringBuilder(); } /// /// Creates a new SqliteDataAdapter. /// /// A SqliteDataAdapter object. public override DbDataAdapter CreateDataAdapter() { return new SqliteDataAdapter(); } /// /// Creates a new SqliteParameter. /// /// A SqliteParameter object. public override DbParameter CreateParameter() { return new SqliteParameter(); } } #endif } #endif hyena-0.5/Mono.Data.Sqlite/Mono.Data.Sqlite/SR.Designer.cs0000644000175000001440000001532311377104476023267 0ustar00gabeusers00000000000000// // Mono.Data.Sqlite.SR.Designer.cs // // Author(s): // Robert Simpson (robert@blackcastlesoft.com) // // Adapted and modified for the Mono Project by // Marek Habersack (grendello@gmail.com) // // // Copyright (C) 2006 Novell, Inc (http://www.novell.com) // Copyright (C) 2007 Marek Habersack // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // //------------------------------------------------------------------------------ // // This code was generated by a tool. // Runtime Version:2.0.50727.42 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // //------------------------------------------------------------------------------ #if NET_2_0 namespace Mono.Data.Sqlite { using System; /// /// A strongly-typed resource class, for looking up localized strings, etc. /// // This class was auto-generated by the StronglyTypedResourceBuilder // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "2.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] internal class SR { private static global::System.Resources.ResourceManager resourceMan; private static global::System.Globalization.CultureInfo resourceCulture; [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] internal SR() { } /// /// Returns the cached ResourceManager instance used by this class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] internal static global::System.Resources.ResourceManager ResourceManager { get { if (object.ReferenceEquals(resourceMan, null)) { global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("SR", typeof(SR).Assembly); resourceMan = temp; } return resourceMan; } } /// /// Overrides the current thread's CurrentUICulture property for all /// resource lookups using this strongly typed resource class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] internal static global::System.Globalization.CultureInfo Culture { get { return resourceCulture; } set { resourceCulture = value; } } /// /// Looks up a localized string similar to <?xml version="1.0" standalone="yes"?> ///<DocumentElement> /// <DataTypes> /// <TypeName>smallint</TypeName> /// <ProviderDbType>10</ProviderDbType> /// <ColumnSize>5</ColumnSize> /// <DataType>System.Int16</DataType> /// <CreateFormat>smallint</CreateFormat> /// <IsAutoIncrementable>false</IsAutoIncrementable> /// <IsCaseSensitive>false</IsCaseSensitive> /// <IsFixedLength>true</IsFixedLength> /// <IsFixedPrecisionScale>true</IsFixedPrecisionScale> /// <IsLong>false</IsLong> /// <IsNullable>true</ [rest of string was truncated]";. /// internal static string DataTypes { get { return ResourceManager.GetString("DataTypes", resourceCulture); } } /// /// Looks up a localized string similar to ALL,ALTER,AND,AS,AUTOINCREMENT,BETWEEN,BY,CASE,CHECK,COLLATE,COMMIT,CONSTRAINT,CREATE,CROSS,DEFAULT,DEFERRABLE,DELETE,DISTINCT,DROP,ELSE,ESCAPE,EXCEPT,FOREIGN,FROM,FULL,GROUP,HAVING,IN,INDEX,INNER,INSERT,INTERSECT,INTO,IS,ISNULL,JOIN,LEFT,LIMIT,NATURAL,NOT,NOTNULL,NULL,ON,OR,ORDER,OUTER,PRIMARY,REFERENCES,RIGHT,ROLLBACK,SELECT,SET,TABLE,THEN,TO,TRANSACTION,UNION,UNIQUE,UPDATE,USING,VALUES,WHEN,WHERE. /// internal static string Keywords { get { return ResourceManager.GetString("Keywords", resourceCulture); } } /// /// Looks up a localized string similar to <?xml version="1.0" encoding="utf-8" ?> ///<DocumentElement> /// <MetaDataCollections> /// <CollectionName>MetaDataCollections</CollectionName> /// <NumberOfRestrictions>0</NumberOfRestrictions> /// <NumberOfIdentifierParts>0</NumberOfIdentifierParts> /// </MetaDataCollections> /// <MetaDataCollections> /// <CollectionName>DataSourceInformation</CollectionName> /// <NumberOfRestrictions>0</NumberOfRestrictions> /// <NumberOfIdentifierParts>0</NumberOfIdentifierParts> /// </MetaDataCollections> /// <MetaDataC [rest of string was truncated]";. /// internal static string MetaDataCollections { get { return ResourceManager.GetString("MetaDataCollections", resourceCulture); } } } } #endif hyena-0.5/Mono.Data.Sqlite/Mono.Data.Sqlite/SQLiteConnectionStringBuilder.cs0000644000175000001440000002113711377104476027063 0ustar00gabeusers00000000000000// // Mono.Data.Sqlite.SQLiteConnectionStringBuilder.cs // // Author(s): // Robert Simpson (robert@blackcastlesoft.com) // // Adapted and modified for the Mono Project by // Marek Habersack (grendello@gmail.com) // // // Copyright (C) 2006 Novell, Inc (http://www.novell.com) // Copyright (C) 2007 Marek Habersack // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // /******************************************************** * ADO.NET 2.0 Data Provider for Sqlite Version 3.X * Written by Robert Simpson (robert@blackcastlesoft.com) * * Released to the public domain, use at your own risk! ********************************************************/ #if NET_2_0 namespace Mono.Data.Sqlite { using System; using System.Data.Common; using System.ComponentModel; using System.Collections; using System.Globalization; using System.Reflection; #if !PLATFORM_COMPACTFRAMEWORK using System.ComponentModel.Design; /// /// Sqlite implementation of DbConnectionStringBuilder. /// [DefaultProperty("DataSource")] [DefaultMember("Item")] public sealed class SqliteConnectionStringBuilder : DbConnectionStringBuilder { /// /// Properties of this class /// private Hashtable _properties; /// /// Constructs a new instance of the class /// /// /// Default constructor /// public SqliteConnectionStringBuilder() { Initialize(null); } /// /// Constructs a new instance of the class using the specified connection string. /// /// The connection string to parse public SqliteConnectionStringBuilder(string connectionString) { Initialize(connectionString); } /// /// Private initializer, which assigns the connection string and resets the builder /// /// The connection string to assign private void Initialize(string cnnString) { _properties = new Hashtable(); base.GetProperties(_properties); if (String.IsNullOrEmpty(cnnString) == false) ConnectionString = cnnString; } /// /// Gets/Sets the default version of the Sqlite engine to instantiate. Currently the only valid value is 3, indicating version 3 of the sqlite library. /// [Browsable(true)] [DefaultValue(3)] public int Version { get { if (ContainsKey("Version") == false) return 3; return Convert.ToInt32(this["Version"], CultureInfo.CurrentCulture); } set { if (value != 3) throw new NotSupportedException(); this["Version"] = value; } } /// /// Gets/Sets the synchronous mode of the connection string. Default is "Normal". /// [DisplayName("Synchronous")] [Browsable(true)] [DefaultValue(SynchronizationModes.Normal)] public SynchronizationModes SyncMode { get { return (SynchronizationModes)TypeDescriptor.GetConverter(typeof(SynchronizationModes)).ConvertFrom(this["Synchronous"]); } set { this["Synchronous"] = value; } } /// /// Gets/Sets the encoding for the connection string. The default is "False" which indicates UTF-8 encoding. /// [Browsable(true)] [DefaultValue(false)] public bool UseUTF16Encoding { get { return Convert.ToBoolean(this["UseUTF16Encoding"], CultureInfo.CurrentCulture); } set { this["UseUTF16Encoding"] = value; } } /// /// Gets/Sets the filename to open on the connection string. /// [DisplayName("Data Source")] [Browsable(true)] public string DataSource { get { if (ContainsKey("Data Source") == false) return ""; return this["Data Source"].ToString(); } set { this["Data Source"] = value; } } #region Mono-specific /// /// Gets/Sets the filename to open on the connection string (Mono-specific, uses DataSource). /// [DisplayName("Data Source")] [Browsable(true)] public string Uri { get { return DataSource; } set { DataSource = value; } } #endregion /// /// Determines whether or not the connection will automatically participate /// in the current distributed transaction (if one exists) /// [DisplayName("Automatic Enlistment")] [Browsable(true)] [DefaultValue(true)] public bool Enlist { get { if (ContainsKey("Enlist") == false) return true; return (this["Enlist"].ToString() == "Y"); } set { this["Enlist"] = (value == true) ? "Y" : "N"; } } /// /// Gets/sets the database encryption password /// [Browsable(true)] [PasswordPropertyText(true)] public string Password { get { if (ContainsKey("Password") == false) return ""; return this["Password"].ToString(); } set { this["Password"] = value; } } /// /// Gets/Sets the page size for the connection. /// [DisplayName("Page Size")] [Browsable(true)] [DefaultValue(1024)] public int PageSize { get { if (ContainsKey("Page Size") == false) return 1024; return Convert.ToInt32(this["Page Size"], CultureInfo.InvariantCulture); } set { this["Page Size"] = value; } } /// /// Gets/Sets the cache size for the connection. /// [DisplayName("Cache Size")] [Browsable(true)] [DefaultValue(2000)] public int CacheSize { get { if (ContainsKey("Cache Size") == false) return 2000; return Convert.ToInt32(this["Cache Size"], CultureInfo.InvariantCulture); } set { this["Cache Size"] = value; } } /// /// Gets/Sets the datetime format for the connection. /// [Browsable(true)] [DefaultValue(SqliteDateFormats.ISO8601)] public SqliteDateFormats DateTimeFormat { get { if (ContainsKey("DateTimeFormat") == false) return SqliteDateFormats.ISO8601; return (SqliteDateFormats)TypeDescriptor.GetConverter(typeof(SqliteDateFormats)).ConvertFrom(this["DateTimeFormat"]); } set { this["DateTimeFormat"] = value; } } /// /// Helper function for retrieving values from the connectionstring /// /// The keyword to retrieve settings for /// The resulting parameter value /// Returns true if the value was found and returned public override bool TryGetValue(string keyword, out object value) { bool b = base.TryGetValue(keyword, out value); if (!_properties.ContainsKey(keyword)) return b; PropertyDescriptor pd = _properties[keyword] as PropertyDescriptor; if (pd == null) return b; if (b) { value = TypeDescriptor.GetConverter(pd.PropertyType).ConvertFrom(value); } else { DefaultValueAttribute att = pd.Attributes[typeof(DefaultValueAttribute)] as DefaultValueAttribute; if (att != null) { value = att.Value; b = true; } } return b; } } #endif } #endif hyena-0.5/Mono.Data.Sqlite/Mono.Data.Sqlite/SQLiteStatement.cs0000644000175000001440000002113411377104476024227 0ustar00gabeusers00000000000000// // Mono.Data.Sqlite.SQLiteStatement.cs // // Author(s): // Robert Simpson (robert@blackcastlesoft.com) // // Adapted and modified for the Mono Project by // Marek Habersack (grendello@gmail.com) // // // Copyright (C) 2006 Novell, Inc (http://www.novell.com) // Copyright (C) 2007 Marek Habersack // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // /******************************************************** * ADO.NET 2.0 Data Provider for Sqlite Version 3.X * Written by Robert Simpson (robert@blackcastlesoft.com) * * Released to the public domain, use at your own risk! ********************************************************/ #if NET_2_0 namespace Mono.Data.Sqlite { using System; using System.Data; using System.Collections.Generic; using System.Globalization; /// /// Represents a single SQL statement in Sqlite. /// internal sealed class SqliteStatement : IDisposable { /// /// The underlying Sqlite object this statement is bound to /// internal SqliteBase _sql; /// /// The command text of this SQL statement /// internal string _sqlStatement; /// /// The actual statement pointer /// internal IntPtr _sqlite_stmt; /// /// An index from which unnamed parameters begin /// internal int _unnamedParameters; /// /// Names of the parameters as Sqlite understands them to be /// internal string[] _paramNames; /// /// Parameters for this statement /// internal SqliteParameter[] _paramValues; /// /// Command this statement belongs to (if any) /// internal SqliteCommand _command; private string[] _types; /// /// Initializes the statement and attempts to get all information about parameters in the statement /// /// The base Sqlite object /// The statement /// The command text for this statement /// The previous command in a multi-statement command internal SqliteStatement(SqliteBase sqlbase, IntPtr stmt, string strCommand, SqliteStatement previous) { _sql = sqlbase; _sqlite_stmt = stmt; _sqlStatement = strCommand; // Determine parameters for this statement (if any) and prepare space for them. int nCmdStart = 0; int n = _sql.Bind_ParamCount(this); int x; string s; if (n > 0) { if (previous != null) nCmdStart = previous._unnamedParameters; _paramNames = new string[n]; _paramValues = new SqliteParameter[n]; for (x = 0; x < n; x++) { s = _sql.Bind_ParamName(this, x + 1); if (String.IsNullOrEmpty(s)) { s = String.Format(CultureInfo.InvariantCulture, ";{0}", nCmdStart); nCmdStart++; _unnamedParameters++; } _paramNames[x] = s; _paramValues[x] = null; } } } /// /// Called by SqliteParameterCollection, this function determines if the specified parameter name belongs to /// this statement, and if so, keeps a reference to the parameter so it can be bound later. /// /// The parameter name to map /// The parameter to assign it internal bool MapParameter(string s, SqliteParameter p) { if (_paramNames == null) return false; int startAt = 0; if (s.Length > 0) { if (":$@;".IndexOf(s[0]) == -1) startAt = 1; } int x = _paramNames.Length; for (int n = 0; n < x; n++) { if (String.Compare(_paramNames[n], startAt, s, 0, Math.Max(_paramNames[n].Length - startAt, s.Length), true, CultureInfo.InvariantCulture) == 0) { _paramValues[n] = p; return true; } } return false; } #region IDisposable Members /// /// Disposes and finalizes the statement /// public void Dispose() { _sql.FinalizeStatement(this); _paramNames = null; _paramValues = null; _sql = null; _sqlStatement = null; GC.SuppressFinalize(this); } #endregion /// /// Bind all parameters, making sure the caller didn't miss any /// internal void BindParameters() { if (_paramNames == null) return; int x = _paramNames.Length; for (int n = 0; n < x; n++) { BindParameter(n + 1, _paramValues[n]); } } /// /// Perform the bind operation for an individual parameter /// /// The index of the parameter to bind /// The parameter we're binding private void BindParameter(int index, SqliteParameter param) { if (param == null) throw new SqliteException((int)SqliteErrorCode.Error, "Insufficient parameters supplied to the command"); object obj = param.Value; DbType objType = param.DbType; if (Convert.IsDBNull(obj) || obj == null) { _sql.Bind_Null(this, index); return; } if (objType == DbType.Object) objType = SqliteConvert.TypeToDbType(obj.GetType()); switch (objType) { case DbType.Date: case DbType.Time: case DbType.DateTime: _sql.Bind_DateTime(this, index, Convert.ToDateTime(obj, CultureInfo.CurrentCulture)); break; case DbType.Int64: case DbType.UInt64: _sql.Bind_Int64(this, index, Convert.ToInt64(obj, CultureInfo.CurrentCulture)); break; case DbType.Boolean: case DbType.Int16: case DbType.Int32: case DbType.UInt16: case DbType.UInt32: case DbType.SByte: case DbType.Byte: _sql.Bind_Int32(this, index, Convert.ToInt32(obj, CultureInfo.CurrentCulture)); break; case DbType.Single: case DbType.Double: case DbType.Currency: case DbType.Decimal: _sql.Bind_Double(this, index, Convert.ToDouble(obj, CultureInfo.CurrentCulture)); break; case DbType.Binary: _sql.Bind_Blob(this, index, (byte[])obj); break; case DbType.Guid: if (_command.Connection._binaryGuid == true) _sql.Bind_Blob(this, index, ((Guid)obj).ToByteArray()); else _sql.Bind_Text(this, index, obj.ToString()); break; default: _sql.Bind_Text(this, index, obj.ToString()); break; } } internal string[] TypeDefinitions { get { return _types; } } internal void SetTypes(string typedefs) { int pos = typedefs.IndexOf("TYPES", 0, StringComparison.OrdinalIgnoreCase); if (pos == -1) throw new ArgumentOutOfRangeException(); string[] types = typedefs.Substring(pos + 6).Replace(" ", "").Replace(";", "").Replace("\"", "").Replace("[", "").Replace("]", "").Split(',', '\r', '\n', '\t'); int cols = 0; int n; for (n = 0; n < types.Length; n++) { if (String.IsNullOrEmpty(types[n]) == false) cols++; } _types = new string[cols]; cols = 0; for (n = 0; n < types.Length; n++) { if (String.IsNullOrEmpty(types[n]) == false) _types[cols++] = types[n]; } } } } #endif hyena-0.5/Mono.Data.Sqlite/Mono.Data.Sqlite/SQLiteDataReader.cs0000644000175000001440000011223411377104476024261 0ustar00gabeusers00000000000000// // Mono.Data.Sqlite.SQLiteDataReader.cs // // Author(s): // Robert Simpson (robert@blackcastlesoft.com) // // Adapted and modified for the Mono Project by // Marek Habersack (grendello@gmail.com) // // // Copyright (C) 2006 Novell, Inc (http://www.novell.com) // Copyright (C) 2007 Marek Habersack // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // /******************************************************** * ADO.NET 2.0 Data Provider for Sqlite Version 3.X * Written by Robert Simpson (robert@blackcastlesoft.com) * * Released to the public domain, use at your own risk! ********************************************************/ #if NET_2_0 namespace Mono.Data.Sqlite { using System; using System.Data; using System.Data.Common; using System.Collections; using System.Collections.Generic; using System.Globalization; using System.Reflection; /// /// Sqlite implementation of DbDataReader. /// public class SqliteDataReader : DbDataReader { /// /// Underlying command this reader is attached to /// private SqliteCommand _command; /// /// Index of the current statement in the command being processed /// private int _activeStatementIndex; /// /// Current statement being Read() /// private SqliteStatement _activeStatement; /// /// State of the current statement being processed. /// -1 = First Step() executed, so the first Read() will be ignored /// 0 = Actively reading /// 1 = Finished reading /// 2 = Non-row-returning statement, no records /// private int _readingState; /// /// Number of records affected by the insert/update statements executed on the command /// private int _rowsAffected; /// /// Count of fields (columns) in the row-returning statement currently being processed /// private int _fieldCount; /// /// Datatypes of active fields (columns) in the current statement, used for type-restricting data /// private SqliteType[] _fieldTypeArray; /// /// The behavior of the datareader /// private CommandBehavior _commandBehavior; /// /// If set, then dispose of the command object when the reader is finished /// internal bool _disposeCommand; #if MONO_SUPPORT_KEYREADER /// /// An array of rowid's for the active statement if CommandBehavior.KeyInfo is specified /// private SqliteKeyReader _keyInfo; #endif /// /// Internal constructor, initializes the datareader and sets up to begin executing statements /// /// The SqliteCommand this data reader is for /// The expected behavior of the data reader internal SqliteDataReader(SqliteCommand cmd, CommandBehavior behave) { _command = cmd; _commandBehavior = behave; _activeStatementIndex = -1; _activeStatement = null; _rowsAffected = -1; _fieldCount = -1; if (_command != null) NextResult(); } /// /// Closes the datareader, potentially closing the connection as well if CommandBehavior.CloseConnection was specified. /// public override void Close() { if (_command != null) { while (NextResult()) { } _command.ClearDataReader(); // If the datareader's behavior includes closing the connection, then do so here. if ((_commandBehavior & CommandBehavior.CloseConnection) != 0 && _command.Connection != null) _command.Connection.Close(); if (_disposeCommand) ((IDisposable)_command).Dispose(); } _command = null; _activeStatement = null; _fieldTypeArray = null; #if MONO_SUPPORT_KEYREADER if (_keyInfo != null) { _keyInfo.Dispose(); _keyInfo = null; } #endif } /// /// Disposes the datareader. Calls Close() to ensure everything is cleaned up. /// protected override void Dispose(bool disposing) { base.Dispose(disposing); GC.SuppressFinalize(this); } /// /// Throw an error if the datareader is closed /// private void CheckClosed() { if (_command == null) throw new InvalidOperationException("DataReader has been closed"); } /// /// Throw an error if a row is not loaded /// private void CheckValidRow() { if (_readingState != 0) throw new InvalidOperationException("No current row"); } /// /// Enumerator support /// /// Returns a DbEnumerator object. public override System.Collections.IEnumerator GetEnumerator() { return new DbEnumerator(this); } /// /// Not implemented. Returns 0 /// public override int Depth { get { CheckClosed(); return 0; } } /// /// Returns the number of columns in the current resultset /// public override int FieldCount { get { CheckClosed(); #if MONO_SUPPORT_KEYREADER if (_keyInfo == null) return _fieldCount; return _fieldCount + _keyInfo.Count; #else return _fieldCount; #endif } } /// /// Returns the number of visible fielsd in the current resultset /// public override int VisibleFieldCount { get { CheckClosed(); return _fieldCount; } } /// /// Sqlite is inherently un-typed. All datatypes in Sqlite are natively strings. The definition of the columns of a table /// and the affinity of returned types are all we have to go on to type-restrict data in the reader. /// /// This function attempts to verify that the type of data being requested of a column matches the datatype of the column. In /// the case of columns that are not backed into a table definition, we attempt to match up the affinity of a column (int, double, string or blob) /// to a set of known types that closely match that affinity. It's not an exact science, but its the best we can do. /// /// /// This function throws an InvalidTypeCast() exception if the requested type doesn't match the column's definition or affinity. /// /// The index of the column to type-check /// The type we want to get out of the column private TypeAffinity VerifyType(int i, DbType typ) { CheckClosed(); CheckValidRow(); TypeAffinity affinity; affinity = _activeStatement._sql.ColumnAffinity(_activeStatement, i); switch (affinity) { case TypeAffinity.Int64: if (typ == DbType.Int16) return affinity; if (typ == DbType.Int32) return affinity; if (typ == DbType.Int64) return affinity; if (typ == DbType.Boolean) return affinity; if (typ == DbType.Byte) return affinity; if (typ == DbType.DateTime && _command.Connection._sql._datetimeFormat == SqliteDateFormats.Ticks) return affinity; if (typ == DbType.Single) return affinity; if (typ == DbType.Double) return affinity; if (typ == DbType.Decimal) return affinity; break; case TypeAffinity.Double: if (typ == DbType.Single) return affinity; if (typ == DbType.Double) return affinity; if (typ == DbType.Decimal) return affinity; break; case TypeAffinity.Text: if (typ == DbType.SByte) return affinity; if (typ == DbType.String) return affinity; if (typ == DbType.SByte) return affinity; if (typ == DbType.Guid) return affinity; if (typ == DbType.DateTime) return affinity; break; case TypeAffinity.Blob: if (typ == DbType.Guid) return affinity; if (typ == DbType.String) return affinity; if (typ == DbType.Binary) return affinity; break; } throw new InvalidCastException(); } /// /// Retrieves the column as a boolean value /// /// The index of the column to retrieve /// bool public override bool GetBoolean(int i) { #if MONO_SUPPORT_KEYREADER if (i >= VisibleFieldCount && _keyInfo != null) return _keyInfo.GetBoolean(i - VisibleFieldCount); #endif VerifyType(i, DbType.Boolean); return Convert.ToBoolean(GetValue(i), CultureInfo.CurrentCulture); } /// /// Retrieves the column as a single byte value /// /// The index of the column to retrieve /// byte public override byte GetByte(int i) { #if MONO_SUPPORT_KEYREADER if (i >= VisibleFieldCount && _keyInfo != null) return _keyInfo.GetByte(i - VisibleFieldCount); #endif VerifyType(i, DbType.Byte); return Convert.ToByte(_activeStatement._sql.GetInt32(_activeStatement, i)); } /// /// Retrieves a column as an array of bytes (blob) /// /// The index of the column to retrieve /// The zero-based index of where to begin reading the data /// The buffer to write the bytes into /// The zero-based index of where to begin writing into the array /// The number of bytes to retrieve /// The actual number of bytes written into the array /// /// To determine the number of bytes in the column, pass a null value for the buffer. The total length will be returned. /// public override long GetBytes(int i, long fieldOffset, byte[] buffer, int bufferoffset, int length) { #if MONO_SUPPORT_KEYREADER if (i >= VisibleFieldCount && _keyInfo != null) return _keyInfo.GetBytes(i - VisibleFieldCount, fieldOffset, buffer, bufferoffset, length); #endif VerifyType(i, DbType.Binary); return _activeStatement._sql.GetBytes(_activeStatement, i, (int)fieldOffset, buffer, bufferoffset, length); } /// /// Returns the column as a single character /// /// The index of the column to retrieve /// char public override char GetChar(int i) { #if MONO_SUPPORT_KEYREADER if (i >= VisibleFieldCount && _keyInfo != null) return _keyInfo.GetChar(i - VisibleFieldCount); #endif VerifyType(i, DbType.SByte); return Convert.ToChar(_activeStatement._sql.GetInt32(_activeStatement, i)); } /// /// Retrieves a column as an array of chars (blob) /// /// The index of the column to retrieve /// The zero-based index of where to begin reading the data /// The buffer to write the characters into /// The zero-based index of where to begin writing into the array /// The number of bytes to retrieve /// The actual number of characters written into the array /// /// To determine the number of characters in the column, pass a null value for the buffer. The total length will be returned. /// public override long GetChars(int i, long fieldoffset, char[] buffer, int bufferoffset, int length) { #if MONO_SUPPORT_KEYREADER if (i >= VisibleFieldCount && _keyInfo != null) return _keyInfo.GetChars(i - VisibleFieldCount, fieldoffset, buffer, bufferoffset, length); #endif VerifyType(i, DbType.String); return _activeStatement._sql.GetChars(_activeStatement, i, (int)fieldoffset, buffer, bufferoffset, length); } /// /// Retrieves the name of the back-end datatype of the column /// /// The index of the column to retrieve /// string public override string GetDataTypeName(int i) { CheckClosed(); #if MONO_SUPPORT_KEYREADER if (i >= VisibleFieldCount && _keyInfo != null) return _keyInfo.GetDataTypeName(i - VisibleFieldCount); #endif SqliteType typ = GetSqliteType(i); if (typ.Type == DbType.Object) return SqliteConvert.SqliteTypeToType(typ).Name; return _activeStatement._sql.ColumnType(_activeStatement, i, out typ.Affinity); } /// /// Retrieve the column as a date/time value /// /// The index of the column to retrieve /// DateTime public override DateTime GetDateTime(int i) { #if MONO_SUPPORT_KEYREADER if (i >= VisibleFieldCount && _keyInfo != null) return _keyInfo.GetDateTime(i - VisibleFieldCount); #endif VerifyType(i, DbType.DateTime); return _activeStatement._sql.GetDateTime(_activeStatement, i); } /// /// Retrieve the column as a decimal value /// /// The index of the column to retrieve /// decimal public override decimal GetDecimal(int i) { #if MONO_SUPPORT_KEYREADER if (i >= VisibleFieldCount && _keyInfo != null) return _keyInfo.GetDecimal(i - VisibleFieldCount); #endif VerifyType(i, DbType.Decimal); return Convert.ToDecimal(_activeStatement._sql.GetDouble(_activeStatement, i)); } /// /// Returns the column as a double /// /// The index of the column to retrieve /// double public override double GetDouble(int i) { #if MONO_SUPPORT_KEYREADER if (i >= VisibleFieldCount && _keyInfo != null) return _keyInfo.GetDouble(i - VisibleFieldCount); #endif VerifyType(i, DbType.Double); return _activeStatement._sql.GetDouble(_activeStatement, i); } /// /// Returns the .NET type of a given column /// /// The index of the column to retrieve /// Type public override Type GetFieldType(int i) { CheckClosed(); #if MONO_SUPPORT_KEYREADER if (i >= VisibleFieldCount && _keyInfo != null) return _keyInfo.GetFieldType(i - VisibleFieldCount); #endif return SqliteConvert.SqliteTypeToType(GetSqliteType(i)); } /// /// Returns a column as a float value /// /// The index of the column to retrieve /// float public override float GetFloat(int i) { #if MONO_SUPPORT_KEYREADER if (i >= VisibleFieldCount && _keyInfo != null) return _keyInfo.GetFloat(i - VisibleFieldCount); #endif VerifyType(i, DbType.Single); return Convert.ToSingle(_activeStatement._sql.GetDouble(_activeStatement, i)); } /// /// Returns the column as a Guid /// /// The index of the column to retrieve /// Guid public override Guid GetGuid(int i) { #if MONO_SUPPORT_KEYREADER if (i >= VisibleFieldCount && _keyInfo != null) return _keyInfo.GetGuid(i - VisibleFieldCount); #endif TypeAffinity affinity = VerifyType(i, DbType.Guid); if (affinity == TypeAffinity.Blob) { byte[] buffer = new byte[16]; _activeStatement._sql.GetBytes(_activeStatement, i, 0, buffer, 0, 16); return new Guid(buffer); } else return new Guid(_activeStatement._sql.GetText(_activeStatement, i)); } /// /// Returns the column as a short /// /// The index of the column to retrieve /// Int16 public override Int16 GetInt16(int i) { #if MONO_SUPPORT_KEYREADER if (i >= VisibleFieldCount && _keyInfo != null) return _keyInfo.GetInt16(i - VisibleFieldCount); #endif VerifyType(i, DbType.Int16); return Convert.ToInt16(_activeStatement._sql.GetInt32(_activeStatement, i)); } /// /// Retrieves the column as an int /// /// The index of the column to retrieve /// Int32 public override Int32 GetInt32(int i) { #if MONO_SUPPORT_KEYREADER if (i >= VisibleFieldCount && _keyInfo != null) return _keyInfo.GetInt32(i - VisibleFieldCount); #endif VerifyType(i, DbType.Int32); return _activeStatement._sql.GetInt32(_activeStatement, i); } /// /// Retrieves the column as a long /// /// The index of the column to retrieve /// Int64 public override Int64 GetInt64(int i) { #if MONO_SUPPORT_KEYREADER if (i >= VisibleFieldCount && _keyInfo != null) return _keyInfo.GetInt64(i - VisibleFieldCount); #endif VerifyType(i, DbType.Int64); return _activeStatement._sql.GetInt64(_activeStatement, i); } /// /// Retrieves the name of the column /// /// The index of the column to retrieve /// string public override string GetName(int i) { CheckClosed(); #if MONO_SUPPORT_KEYREADER if (i >= VisibleFieldCount && _keyInfo != null) return _keyInfo.GetName(i - VisibleFieldCount); #endif return _activeStatement._sql.ColumnName(_activeStatement, i); } /// /// Retrieves the i of a column, given its name /// /// The name of the column to retrieve /// The int i of the column public override int GetOrdinal(string name) { CheckClosed(); int r = _activeStatement._sql.ColumnIndex(_activeStatement, name); #if MONO_SUPPORT_KEYREADER if (r == -1 && _keyInfo != null) { r = _keyInfo.GetOrdinal(name); if (r > -1) r += VisibleFieldCount; } #endif return r; } /// /// Schema information in Sqlite is difficult to map into .NET conventions, so a lot of work must be done /// to gather the necessary information so it can be represented in an ADO.NET manner. /// /// Returns a DataTable containing the schema information for the active SELECT statement being processed. public override DataTable GetSchemaTable() { return GetSchemaTable(true, false); } internal DataTable GetSchemaTable(bool wantUniqueInfo, bool wantDefaultValue) { CheckClosed(); DataTable tbl = new DataTable("SchemaTable"); DataTable tblIndexes = null; DataTable tblIndexColumns; DataRow row; string temp; string strCatalog = ""; string strTable = ""; string strColumn = ""; tbl.Locale = CultureInfo.InvariantCulture; tbl.Columns.Add(SchemaTableColumn.ColumnName, typeof(String)); tbl.Columns.Add(SchemaTableColumn.ColumnOrdinal, typeof(int)); tbl.Columns.Add(SchemaTableColumn.ColumnSize, typeof(int)); tbl.Columns.Add(SchemaTableColumn.NumericPrecision, typeof(short)); tbl.Columns.Add(SchemaTableColumn.NumericScale, typeof(short)); tbl.Columns.Add(SchemaTableColumn.IsUnique, typeof(Boolean)); tbl.Columns.Add(SchemaTableColumn.IsKey, typeof(Boolean)); tbl.Columns.Add(SchemaTableOptionalColumn.BaseServerName, typeof(string)); tbl.Columns.Add(SchemaTableOptionalColumn.BaseCatalogName, typeof(String)); tbl.Columns.Add(SchemaTableColumn.BaseColumnName, typeof(String)); tbl.Columns.Add(SchemaTableColumn.BaseSchemaName, typeof(String)); tbl.Columns.Add(SchemaTableColumn.BaseTableName, typeof(String)); tbl.Columns.Add(SchemaTableColumn.DataType, typeof(Type)); tbl.Columns.Add(SchemaTableColumn.AllowDBNull, typeof(Boolean)); tbl.Columns.Add(SchemaTableColumn.ProviderType, typeof(int)); tbl.Columns.Add(SchemaTableColumn.IsAliased, typeof(Boolean)); tbl.Columns.Add(SchemaTableColumn.IsExpression, typeof(Boolean)); tbl.Columns.Add(SchemaTableOptionalColumn.IsAutoIncrement, typeof(Boolean)); tbl.Columns.Add(SchemaTableOptionalColumn.IsRowVersion, typeof(Boolean)); tbl.Columns.Add(SchemaTableOptionalColumn.IsHidden, typeof(Boolean)); tbl.Columns.Add(SchemaTableColumn.IsLong, typeof(Boolean)); tbl.Columns.Add(SchemaTableOptionalColumn.IsReadOnly, typeof(Boolean)); tbl.Columns.Add(SchemaTableOptionalColumn.ProviderSpecificDataType, typeof(Type)); tbl.Columns.Add(SchemaTableOptionalColumn.DefaultValue, typeof(object)); tbl.Columns.Add("DataTypeName", typeof(string)); tbl.BeginLoadData(); for (int n = 0; n < _fieldCount; n++) { row = tbl.NewRow(); // Default settings for the column row[SchemaTableColumn.ColumnName] = GetName(n); row[SchemaTableColumn.ColumnOrdinal] = n; row[SchemaTableColumn.ColumnSize] = SqliteConvert.DbTypeToColumnSize(GetSqliteType(n).Type); row[SchemaTableColumn.NumericPrecision] = 255; row[SchemaTableColumn.NumericScale] = 255; row[SchemaTableColumn.ProviderType] = GetSqliteType(n).Type; row[SchemaTableColumn.IsLong] = (GetSqliteType(n).Type == DbType.Binary); row[SchemaTableColumn.AllowDBNull] = true; row[SchemaTableOptionalColumn.IsReadOnly] = false; row[SchemaTableOptionalColumn.IsRowVersion] = false; row[SchemaTableColumn.IsUnique] = false; row[SchemaTableColumn.IsKey] = false; row[SchemaTableOptionalColumn.IsAutoIncrement] = false; row[SchemaTableOptionalColumn.IsReadOnly] = false; row[SchemaTableColumn.DataType] = GetFieldType(n); row[SchemaTableOptionalColumn.IsHidden] = false; strColumn = _command.Connection._sql.ColumnOriginalName(_activeStatement, n); if (String.IsNullOrEmpty(strColumn) == false) row[SchemaTableColumn.BaseColumnName] = strColumn; row[SchemaTableColumn.IsExpression] = String.IsNullOrEmpty(strColumn); row[SchemaTableColumn.IsAliased] = (String.Compare(GetName(n), strColumn, true, CultureInfo.InvariantCulture) != 0); temp = _command.Connection._sql.ColumnTableName(_activeStatement, n); if (String.IsNullOrEmpty(temp) == false) row[SchemaTableColumn.BaseTableName] = temp; temp = _command.Connection._sql.ColumnDatabaseName(_activeStatement, n); if (String.IsNullOrEmpty(temp) == false) row[SchemaTableOptionalColumn.BaseCatalogName] = temp; string dataType = null; // If we have a table-bound column, extract the extra information from it if (String.IsNullOrEmpty(strColumn) == false) { string collSeq; bool bNotNull; bool bPrimaryKey; bool bAutoIncrement; string[] arSize; // Get the column meta data _command.Connection._sql.ColumnMetaData( (string)row[SchemaTableOptionalColumn.BaseCatalogName], (string)row[SchemaTableColumn.BaseTableName], strColumn, out dataType, out collSeq, out bNotNull, out bPrimaryKey, out bAutoIncrement); if (bNotNull || bPrimaryKey) row[SchemaTableColumn.AllowDBNull] = false; row[SchemaTableColumn.IsKey] = bPrimaryKey; row[SchemaTableOptionalColumn.IsAutoIncrement] = bAutoIncrement; // For types like varchar(50) and such, extract the size arSize = dataType.Split('('); if (arSize.Length > 1) { dataType = arSize[0]; arSize = arSize[1].Split(')'); if (arSize.Length > 1) { arSize = arSize[0].Split(',', '.'); if (GetSqliteType(n).Type == DbType.String || GetSqliteType(n).Type == DbType.Binary) { row[SchemaTableColumn.ColumnSize] = Convert.ToInt32(arSize[0], CultureInfo.InvariantCulture); } else { row[SchemaTableColumn.NumericPrecision] = Convert.ToInt32(arSize[0], CultureInfo.InvariantCulture); if (arSize.Length > 1) row[SchemaTableColumn.NumericScale] = Convert.ToInt32(arSize[1], CultureInfo.InvariantCulture); } } } if (wantDefaultValue) { // Determine the default value for the column, which sucks because we have to query the schema for each column using (SqliteCommand cmdTable = new SqliteCommand(String.Format(CultureInfo.InvariantCulture, "PRAGMA [{0}].TABLE_INFO([{1}])", row[SchemaTableOptionalColumn.BaseCatalogName], row[SchemaTableColumn.BaseTableName] ), _command.Connection)) using (DbDataReader rdTable = cmdTable.ExecuteReader()) { // Find the matching column while (rdTable.Read()) { if (String.Compare((string)row[SchemaTableColumn.BaseColumnName], rdTable.GetString(1), true, CultureInfo.InvariantCulture) == 0) { if (rdTable.IsDBNull(4) == false) row[SchemaTableOptionalColumn.DefaultValue] = rdTable[4]; break; } } } } // Determine IsUnique properly, which is a pain in the butt! if (wantUniqueInfo) { if ((string)row[SchemaTableOptionalColumn.BaseCatalogName] != strCatalog || (string)row[SchemaTableColumn.BaseTableName] != strTable) { strCatalog = (string)row[SchemaTableOptionalColumn.BaseCatalogName]; strTable = (string)row[SchemaTableColumn.BaseTableName]; tblIndexes = _command.Connection.GetSchema("Indexes", new string[] { (string)row[SchemaTableOptionalColumn.BaseCatalogName], null, (string)row[SchemaTableColumn.BaseTableName], null }); } foreach (DataRow rowIndexes in tblIndexes.Rows) { tblIndexColumns = _command.Connection.GetSchema("IndexColumns", new string[] { (string)row[SchemaTableOptionalColumn.BaseCatalogName], null, (string)row[SchemaTableColumn.BaseTableName], (string)rowIndexes["INDEX_NAME"], null }); foreach (DataRow rowColumnIndex in tblIndexColumns.Rows) { if (String.Compare((string)rowColumnIndex["COLUMN_NAME"], strColumn, true, CultureInfo.InvariantCulture) == 0) { if (tblIndexColumns.Rows.Count == 1 && (bool)row[SchemaTableColumn.AllowDBNull] == false) row[SchemaTableColumn.IsUnique] = rowIndexes["UNIQUE"]; break; } } } } } if (String.IsNullOrEmpty(dataType)) { TypeAffinity affin; dataType = _activeStatement._sql.ColumnType(_activeStatement, n, out affin); } if (String.IsNullOrEmpty(dataType) == false) row["DataTypeName"] = dataType; tbl.Rows.Add(row); } #if MONO_SUPPORT_KEYREADER if (_keyInfo != null) _keyInfo.AppendSchemaTable(tbl); #endif tbl.AcceptChanges(); tbl.EndLoadData(); return tbl; } /// /// Retrieves the column as a string /// /// The index of the column to retrieve /// string public override string GetString(int i) { #if MONO_SUPPORT_KEYREADER if (i >= VisibleFieldCount && _keyInfo != null) return _keyInfo.GetString(i - VisibleFieldCount); #endif VerifyType(i, DbType.String); return _activeStatement._sql.GetText(_activeStatement, i); } /// /// Retrieves the column as an object corresponding to the underlying datatype of the column /// /// The index of the column to retrieve /// object public override object GetValue(int i) { CheckClosed(); #if MONO_SUPPORT_KEYREADER if (i >= VisibleFieldCount && _keyInfo != null) return _keyInfo.GetValue(i - VisibleFieldCount); #endif SqliteType typ = GetSqliteType(i); typ.Affinity = _activeStatement._sql.ColumnAffinity(_activeStatement, i); return _activeStatement._sql.GetValue(_activeStatement, i, typ); } /// /// Retreives the values of multiple columns, up to the size of the supplied array /// /// The array to fill with values from the columns in the current resultset /// The number of columns retrieved public override int GetValues(object[] values) { int nMax = FieldCount; if (values.Length < nMax) nMax = values.Length; for (int n = 0; n < nMax; n++) { values[n] = GetValue(n); } return nMax; } /// /// Returns True if the resultset has rows that can be fetched /// public override bool HasRows { get { CheckClosed(); return (_readingState != 1); } } /// /// Returns True if the data reader is closed /// public override bool IsClosed { get { return (_command == null); } } /// /// Returns True if the specified column is null /// /// The index of the column to retrieve /// True or False public override bool IsDBNull(int i) { CheckClosed(); #if MONO_SUPPORT_KEYREADER if (i >= VisibleFieldCount && _keyInfo != null) return _keyInfo.IsDBNull(i - VisibleFieldCount); #endif return _activeStatement._sql.IsNull(_activeStatement, i); } /// /// Moves to the next resultset in multiple row-returning SQL command. /// /// True if the command was successful and a new resultset is available, False otherwise. public override bool NextResult() { CheckClosed(); SqliteStatement stmt = null; int fieldCount; while (true) { if (_activeStatement != null && stmt == null) { // Reset the previously-executed statement _activeStatement._sql.Reset(_activeStatement); // If we're only supposed to return a single rowset, step through all remaining statements once until // they are all done and return false to indicate no more resultsets exist. if ((_commandBehavior & CommandBehavior.SingleResult) != 0) { for (; ; ) { stmt = _command.GetStatement(_activeStatementIndex + 1); if (stmt == null) break; _activeStatementIndex++; stmt._sql.Step(stmt); if (stmt._sql.ColumnCount(stmt) == 0) { if (_rowsAffected == -1) _rowsAffected = 0; _rowsAffected += stmt._sql.Changes; } stmt._sql.Reset(stmt); // Gotta reset after every step to release any locks and such! } return false; } } // Get the next statement to execute stmt = _command.GetStatement(_activeStatementIndex + 1); // If we've reached the end of the statements, return false, no more resultsets if (stmt == null) return false; // If we were on a current resultset, set the state to "done reading" for it if (_readingState < 1) _readingState = 1; _activeStatementIndex++; fieldCount = stmt._sql.ColumnCount(stmt); // If the statement is not a select statement or we're not retrieving schema only, then perform the initial step if ((_commandBehavior & CommandBehavior.SchemaOnly) == 0 || fieldCount == 0) { if (stmt._sql.Step(stmt)) { _readingState = -1; } else if (fieldCount == 0) // No rows returned, if fieldCount is zero, skip to the next statement { if (_rowsAffected == -1) _rowsAffected = 0; _rowsAffected += stmt._sql.Changes; stmt._sql.Reset(stmt); continue; // Skip this command and move to the next, it was not a row-returning resultset } else // No rows, fieldCount is non-zero so stop here { _readingState = 1; // This command returned columns but no rows, so return true, but HasRows = false and Read() returns false } } // Ahh, we found a row-returning resultset eligible to be returned! _activeStatement = stmt; _fieldCount = fieldCount; _fieldTypeArray = null; if ((_commandBehavior & CommandBehavior.KeyInfo) != 0) LoadKeyInfo(); return true; } } /// /// Retrieves the SqliteType for a given column, and caches it to avoid repetetive interop calls. /// /// The index of the column to retrieve /// A SqliteType structure private SqliteType GetSqliteType(int i) { SqliteType typ; // Initialize the field types array if not already initialized if (_fieldTypeArray == null) _fieldTypeArray = new SqliteType[VisibleFieldCount]; // Initialize this column's field type instance if (_fieldTypeArray[i] == null) _fieldTypeArray[i] = new SqliteType(); typ = _fieldTypeArray[i]; // If not initialized, then fetch the declared column datatype and attempt to convert it // to a known DbType. if (typ.Affinity == TypeAffinity.Uninitialized) typ.Type = SqliteConvert.TypeNameToDbType(_activeStatement._sql.ColumnType(_activeStatement, i, out typ.Affinity)); else typ.Affinity = _activeStatement._sql.ColumnAffinity(_activeStatement, i); return typ; } /// /// Reads the next row from the resultset /// /// True if a new row was successfully loaded and is ready for processing public override bool Read() { CheckClosed(); if (_readingState == -1) // First step was already done at the NextResult() level, so don't step again, just return true. { _readingState = 0; return true; } else if (_readingState == 0) // Actively reading rows { if (_activeStatement._sql.Step(_activeStatement) == true) { #if MONO_SUPPORT_KEYREADER if (_keyInfo != null) _keyInfo.Reset(); #endif return true; } _readingState = 1; // Finished reading rows } return false; } /// /// Retrieve the count of records affected by an update/insert command. Only valid once the data reader is closed! /// public override int RecordsAffected { get { return _rowsAffected; } } /// /// Indexer to retrieve data from a column given its name /// /// The name of the column to retrieve data for /// The value contained in the column public override object this[string name] { get { return GetValue(GetOrdinal(name)); } } /// /// Indexer to retrieve data from a column given its i /// /// The index of the column to retrieve /// The value contained in the column public override object this[int i] { get { return GetValue(i); } } private void LoadKeyInfo() { #if MONO_SUPPORT_KEYREADER if (_keyInfo != null) _keyInfo.Dispose(); _keyInfo = new SqliteKeyReader(_command.Connection, this, _activeStatement); #endif } } } #endif hyena-0.5/Mono.Data.Sqlite/Mono.Data.Sqlite/SQLiteConnection.cs0000644000175000001440000023260311377104476024367 0ustar00gabeusers00000000000000// // Mono.Data.Sqlite.SQLiteConnection.cs // // Author(s): // Robert Simpson (robert@blackcastlesoft.com) // // Adapted and modified for the Mono Project by // Marek Habersack (grendello@gmail.com) // // // Copyright (C) 2006 Novell, Inc (http://www.novell.com) // Copyright (C) 2007 Marek Habersack // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // /******************************************************** * ADO.NET 2.0 Data Provider for Sqlite Version 3.X * Written by Robert Simpson (robert@blackcastlesoft.com) * * Released to the public domain, use at your own risk! ********************************************************/ #if NET_2_0 namespace Mono.Data.Sqlite { using System; using System.Data; using System.Data.Common; using System.Collections.Generic; using System.Globalization; using System.ComponentModel; /// /// Sqlite implentation of DbConnection. /// /// /// The ConnectionString property of the SqliteConnection class can contain the following parameter(s), delimited with a semi-colon: /// /// /// Parameter /// Values /// Required /// Default /// /// /// Data Source /// {filename} /// Y /// /// /// /// Version /// 3 /// N /// 3 /// /// /// UseUTF16Encoding /// True
False
/// N /// False ///
/// /// DateTimeFormat /// Ticks - Use DateTime.Ticks
ISO8601 - Use ISO8601 DateTime format
/// N /// ISO8601 ///
/// /// BinaryGUID /// True - Store GUID columns in binary form
False - Store GUID columns as text
/// N /// True ///
/// /// Cache Size /// {size in bytes} /// N /// 2000 /// /// /// Synchronous /// Normal - Normal file flushing behavior
Full - Full flushing after all writes
Off - Underlying OS flushes I/O's
/// N /// Normal ///
/// /// Page Size /// {size in bytes} /// N /// 1024 /// /// /// Password /// {password} /// N /// /// /// /// Enlist /// Y - Automatically enlist in distributed transactions
N - No automatic enlistment
/// N /// Y ///
///
///
public sealed class SqliteConnection : DbConnection, ICloneable { private const string _dataDirectory = "|DataDirectory|"; /// /// State of the current connection /// private ConnectionState _connectionState; /// /// The connection string /// private string _connectionString; /// /// Nesting level of the transactions open on the connection /// internal int _transactionLevel; /// /// Busy command timeout value. Defaults to 30 /// internal int _busyTimeout; #if !PLATFORM_COMPACTFRAMEWORK /// /// Whether or not the connection is enlisted in a distrubuted transaction /// internal SqliteEnlistment _enlistment; #endif /// /// The base Sqlite object to interop with /// internal SqliteBase _sql; /// /// Commands associated with this connection /// internal List _commandList; /// /// The database filename minus path and extension /// private string _dataSource; #if MONO_SUPPORT_PASSWORDS /// /// Temporary password storage, emptied after the database has been opened /// private byte[] _password; #endif internal bool _binaryGuid; internal long _version; private event SqliteUpdateEventHandler _updateHandler; private event SqliteCommitHandler _commitHandler; private event EventHandler _rollbackHandler; private SqliteUpdateCallback _updateCallback; private SqliteCommitCallback _commitCallback; private SqliteRollbackCallback _rollbackCallback; /// /// This event is raised whenever the database is opened or closed. /// //public override event StateChangeEventHandler StateChange; /// /// This event is raised whenever Sqlite makes an update/delete/insert into the database on /// this connection. It only applies to the given connection. /// public event SqliteUpdateEventHandler Update { add { if (_updateHandler == null) { _updateCallback = new SqliteUpdateCallback(UpdateCallback); _sql.SetUpdateHook(_updateCallback); } _updateHandler += value; } remove { _updateHandler -= value; if (_updateHandler == null) { _sql.SetUpdateHook(null); _updateCallback = null; } } } private void UpdateCallback(int type, IntPtr database, int databaseLen, IntPtr table, int tableLen, Int64 rowid) { _updateHandler(this, new UpdateEventArgs( _sql.UTF8ToString(database), _sql.UTF8ToString(table), (UpdateEventType)type, rowid)); } /// /// This event is raised whenever Sqlite is committing a transaction. /// Return non-zero to trigger a rollback /// public event SqliteCommitHandler Commit { add { if (_commitHandler == null) { _commitCallback = new SqliteCommitCallback(CommitCallback); _sql.SetCommitHook(_commitCallback); } _commitHandler += value; } remove { _commitHandler -= value; if (_commitHandler == null) { _sql.SetCommitHook(null); _commitCallback = null; } } } /// /// This event is raised whenever Sqlite is committing a transaction. /// Return non-zero to trigger a rollback /// public event EventHandler RollBack { add { if (_rollbackHandler == null) { _rollbackCallback = new SqliteRollbackCallback(RollbackCallback); _sql.SetRollbackHook(_rollbackCallback); } _rollbackHandler += value; } remove { _rollbackHandler -= value; if (_rollbackHandler == null) { _sql.SetRollbackHook(null); _rollbackCallback = null; } } } private int CommitCallback() { CommitEventArgs e = new CommitEventArgs(); _commitHandler(this, e); return (e.AbortTransaction == true) ? 1 : 0; } private void RollbackCallback() { _rollbackHandler(this, EventArgs.Empty); } /// /// Constructs a new SqliteConnection object /// /// /// Default constructor /// public SqliteConnection() : this("") { } /// /// Initializes the connection with the specified connection string /// /// The connection string to use on the connection public SqliteConnection(string connectionString) { _sql = null; _connectionState = ConnectionState.Closed; _connectionString = ""; _transactionLevel = 0; _busyTimeout = 30; _version = 0; _commandList = new List(); if (connectionString != null) ConnectionString = connectionString; } /// /// Clones the settings and connection string from an existing connection. If the existing connection is already open, this /// function will open its own connection, enumerate any attached databases of the original connection, and automatically /// attach to them. /// /// public SqliteConnection(SqliteConnection connection) : this(connection.ConnectionString) { string str; if (connection.State == ConnectionState.Open) { Open(); // Reattach all attached databases from the existing connection using (DataTable tbl = connection.GetSchema("Catalogs")) { foreach (DataRow row in tbl.Rows) { str = row[0].ToString(); if (String.Compare(str, "main", true, CultureInfo.InvariantCulture) != 0 && String.Compare(str, "temp", true, CultureInfo.InvariantCulture) != 0) { using (SqliteCommand cmd = CreateCommand()) { cmd.CommandText = String.Format(CultureInfo.InvariantCulture, "ATTACH DATABASE '{0}' AS [{1}]", row[1], row[0]); cmd.ExecuteNonQuery(); } } } } } } /// /// Creates a clone of the connection. All attached databases and user-defined functions are cloned. If the existing connection is open, the cloned connection /// will also be opened. /// /// public object Clone() { return new SqliteConnection(this); } /// /// Disposes of the SqliteConnection, closing it if it is active. /// /// True if the connection is being explicitly closed. protected override void Dispose(bool disposing) { base.Dispose(disposing); Close(); } /// /// Creates a database file. This just creates a zero-byte file which Sqlite /// will turn into a database when the file is opened properly. /// /// The file to create static public void CreateFile(string databaseFileName) { System.IO.FileStream fs = System.IO.File.Create(databaseFileName); fs.Close(); } /// /// On NTFS volumes, this function turns on the compression attribute for the given file. /// It must not be open or referenced at the time of the function call. /// /// The file to compress static public void CompressFile(string databaseFileName) { UnsafeNativeMethods.sqlite3_compressfile(databaseFileName); } /// /// On NTFS volumes, this function removes the compression attribute for the given file. /// It must not be open or referenced at the time of the function call. /// /// The file to decompress static public void DecompressFile(string databaseFileName) { UnsafeNativeMethods.sqlite3_decompressfile(databaseFileName); } /// /// Raises the state change event when the state of the connection changes /// /// The new state. If it is different from the previous state, an event is raised. internal void OnStateChange(ConnectionState newState) { // FIXME: breaks when the commented out code is used ConnectionState oldState = _connectionState; _connectionState = newState; // if (StateChange != null && oldState != newState) if (oldState != newState) { StateChangeEventArgs e = new StateChangeEventArgs(oldState, newState); //StateChange(this, e); base.OnStateChange (e); } } /// /// Creates a new SqliteTransaction if one isn't already active on the connection. /// /// Sqlite doesn't support varying isolation levels, so this parameter is ignored. /// When TRUE, Sqlite defers obtaining a write lock until a write operation is requested. /// When FALSE, a writelock is obtained immediately. The default is TRUE, but in a multi-threaded multi-writer /// environment, one may instead choose to lock the database immediately to avoid any possible writer deadlock. /// Returns a SqliteTransaction object. public SqliteTransaction BeginTransaction(System.Data.IsolationLevel isolationLevel, bool deferredLock) { return BeginTransaction(deferredLock); } /// /// Creates a new SqliteTransaction if one isn't already active on the connection. /// /// When TRUE, Sqlite defers obtaining a write lock until a write operation is requested. /// When FALSE, a writelock is obtained immediately. The default is TRUE, but in a multi-threaded multi-writer /// environment, one may instead choose to lock the database immediately to avoid any possible writer deadlock. /// Returns a SqliteTransaction object. public SqliteTransaction BeginTransaction(bool deferredLock) { if (_connectionState != ConnectionState.Open) throw new InvalidOperationException(); return new SqliteTransaction(this, deferredLock); } /// /// Creates a new SqliteTransaction if one isn't already active on the connection. /// /// Sqlite supports only serializable transactions. /// Returns a SqliteTransaction object. public new SqliteTransaction BeginTransaction(System.Data.IsolationLevel isolationLevel) { return BeginTransaction(false); } /// /// Creates a new SqliteTransaction if one isn't already active on the connection. /// /// Returns a SqliteTransaction object. public new SqliteTransaction BeginTransaction() { return BeginTransaction(false); } /// /// Forwards to the local BeginTransaction() function /// /// /// protected override DbTransaction BeginDbTransaction(System.Data.IsolationLevel isolationLevel) { return BeginTransaction(false); } /// /// Not implemented /// /// public override void ChangeDatabase(string databaseName) { throw new NotImplementedException(); } /// /// When the database connection is closed, all commands linked to this connection are automatically reset. /// public override void Close() { if (_sql != null) { // Force any commands associated with this connection to release their unmanaged // resources. The commands are still valid and will automatically re-acquire the // unmanaged resources the next time they are run -- provided this connection is // re-opened before then. lock (_commandList) { foreach (SqliteCommand cmd in _commandList) cmd.ClearCommands(); } #if !PLATFORM_COMPACTFRAMEWORK if (_enlistment != null) { // If the connection is enlisted in a transaction scope and the scope is still active, // we cannot truly shut down this connection until the scope has completed. Therefore make a // hidden connection temporarily to hold open the connection until the scope has completed. SqliteConnection cnn = new SqliteConnection(); cnn._sql = _sql; cnn._transactionLevel = _transactionLevel; cnn._enlistment = _enlistment; cnn._connectionState = _connectionState; cnn._version = _version; cnn._enlistment._transaction._cnn = cnn; cnn._enlistment._disposeConnection = true; } else { _sql.Close(); } _enlistment = null; #else _sql.Close(); #endif _sql = null; _transactionLevel = 0; } OnStateChange(ConnectionState.Closed); } /// /// The connection string containing the parameters for the connection /// /// /// /// /// Parameter /// Values /// Required /// Default /// /// /// Data Source /// {filename} /// Y /// /// /// /// Version /// 3 /// N /// 3 /// /// /// UseUTF16Encoding /// True
False
/// N /// False ///
/// /// DateTimeFormat /// Ticks - Use DateTime.Ticks
ISO8601 - Use ISO8601 DateTime format
/// N /// ISO8601 ///
/// /// BinaryGUID /// Yes/On/1 - Store GUID columns in binary form
No/Off/0 - Store GUID columns as text
/// N /// On ///
/// /// Cache Size /// {size in bytes} /// N /// 2000 /// /// /// Synchronous /// Normal - Normal file flushing behavior
Full - Full flushing after all writes
Off - Underlying OS flushes I/O's
/// N /// Normal ///
/// /// Page Size /// {size in bytes} /// N /// 1024 /// /// /// Password /// {password} /// N /// /// /// /// Enlist /// Y - Automatically enlist in distributed transactions
N - No automatic enlistment
/// N /// Y ///
///
///
#if !PLATFORM_COMPACTFRAMEWORK [RefreshProperties(RefreshProperties.All), DefaultValue("")] [Editor("Sqlite.Designer.SqliteConnectionStringEditor, Sqlite.Designer, Version=1.0.31.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139", "System.Drawing.Design.UITypeEditor, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")] #endif public override string ConnectionString { get { return _connectionString; } set { if (value == null) throw new ArgumentNullException(); else if (_connectionState != ConnectionState.Closed) throw new InvalidOperationException(); _connectionString = value; } } /// /// Create a new SqliteCommand and associate it with this connection. /// /// Returns an instantiated SqliteCommand object already assigned to this connection. public new SqliteCommand CreateCommand() { return new SqliteCommand(this); } /// /// Forwards to the local CreateCommand() function /// /// protected override DbCommand CreateDbCommand() { return CreateCommand(); } /// /// Returns the filename without extension or path /// #if !PLATFORM_COMPACTFRAMEWORK [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] #endif public override string DataSource { get { return _dataSource; } } /// /// Returns "main' /// #if !PLATFORM_COMPACTFRAMEWORK [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] #endif public override string Database { get { return "main"; } } /// /// Maps mono-specific connection string keywords to the standard ones /// /// The mapped keyword name internal void MapMonoKeyword (string[] arPiece, List> ls) { string keyword, value; switch (arPiece[0].ToLower (CultureInfo.InvariantCulture)) { case "uri": keyword = "Data Source"; value = MapMonoUriPath (arPiece[1]); break; default: keyword = arPiece[0]; value = arPiece[1]; break; } ls.Add(new KeyValuePair(keyword, value)); } internal string MapMonoUriPath (string path) { if (path.StartsWith ("file://")) { return path.Substring (7); } else if (path.StartsWith ("file:")) { return path.Substring (5); } else if (path.StartsWith ("/")) { return path; } else { throw new InvalidOperationException ("Invalid connection string: invalid URI"); } } /// /// Parses the connection string into component parts /// /// An array of key-value pairs representing each parameter of the connection string internal KeyValuePair[] ParseConnectionString() { string s = _connectionString.Replace (',', ';'); // Mono compatibility int n; List> ls = new List>(); // First split into semi-colon delimited values. The Split() function of SqliteBase accounts for and properly // skips semi-colons in quoted strings string[] arParts = SqliteConvert.Split(s, ';'); string[] arPiece; int x = arParts.Length; // For each semi-colon piece, split into key and value pairs by the presence of the = sign for (n = 0; n < x; n++) { arPiece = SqliteConvert.Split(arParts[n], '='); if (arPiece.Length == 2) MapMonoKeyword (arPiece, ls); else throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, "Invalid ConnectionString format for parameter \"{0}\"", (arPiece.Length > 0) ? arPiece[0] : "null")); } KeyValuePair[] ar = new KeyValuePair[ls.Count]; ls.CopyTo(ar, 0); // Return the array of key-value pairs return ar; } #if !PLATFORM_COMPACTFRAMEWORK /// /// Manual distributed transaction enlistment support /// /// The distributed transaction to enlist in public override void EnlistTransaction(System.Transactions.Transaction transaction) { if (_transactionLevel > 0 && transaction != null) throw new ArgumentException("Unable to enlist in transaction, a local transaction already exists"); if (_enlistment != null && transaction != _enlistment._scope) throw new ArgumentException("Already enlisted in a transaction"); _enlistment = new SqliteEnlistment(this, transaction); } #endif /// /// Looks for a key in the array of key/values of the parameter string. If not found, return the specified default value /// /// The Key/Value pair array to look in /// The key to find /// The default value to return if the key is not found /// The value corresponding to the specified key, or the default value if not found. static internal string FindKey(KeyValuePair[] opts, string key, string defValue) { int x = opts.Length; for (int n = 0; n < x; n++) { if (String.Compare(opts[n].Key, key, true, CultureInfo.InvariantCulture) == 0) { return opts[n].Value; } } return defValue; } /// /// Opens the connection using the parameters found in the ConnectionString /// public override void Open() { if (_connectionState != ConnectionState.Closed) throw new InvalidOperationException(); Close(); KeyValuePair[] opts = ParseConnectionString(); string fileName; if (Convert.ToInt32(FindKey(opts, "Version", "3"), CultureInfo.InvariantCulture) != 3) throw new NotSupportedException("Only Sqlite Version 3 is supported at this time"); fileName = FindKey(opts, "Data Source", ""); if (String.IsNullOrEmpty(fileName)) throw new ArgumentException("Data Source cannot be empty. Use :memory: to open an in-memory database"); if (String.Compare(fileName, ":MEMORY:", true, CultureInfo.InvariantCulture) == 0) fileName = ":memory:"; #if PLATFORM_COMPACTFRAMEWORK else if (fileName.StartsWith(".\\")) fileName = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetCallingAssembly().GetName().CodeBase) + fileName.Substring(1); #endif string bt = FindKey (opts, "busy_timeout", "30"); try { _busyTimeout = Int32.Parse (bt); } catch (Exception) { // ignore } try { bool bUTF16 = (Convert.ToBoolean(FindKey(opts, "UseUTF16Encoding", "False"), CultureInfo.InvariantCulture) == true); SqliteDateFormats dateFormat = String.Compare(FindKey(opts, "DateTimeFormat", "ISO8601"), "ticks", true, CultureInfo.InvariantCulture) == 0 ? SqliteDateFormats.Ticks : SqliteDateFormats.ISO8601; if (bUTF16) // Sqlite automatically sets the encoding of the database to UTF16 if called from sqlite3_open16() _sql = new Sqlite3_UTF16(dateFormat); else _sql = new Sqlite3(dateFormat); fileName = ExpandFileName(fileName); try { if (System.IO.File.Exists(fileName) == false) throw new System.IO.FileNotFoundException(String.Format(CultureInfo.CurrentCulture, "Unable to locate file \"{0}\", creating new database.", fileName)); } catch { } _sql.Open(fileName); _binaryGuid = (Convert.ToBoolean(FindKey(opts, "BinaryGUID", "True"), CultureInfo.InvariantCulture) == true); #if MONO_SUPPORT_PASSWORDS // Not used under mono now string password = FindKey(opts, "Password", null); if (String.IsNullOrEmpty(password) == false) _sql.SetPassword(System.Text.UTF8Encoding.UTF8.GetBytes(password)); else if (_password != null) _sql.SetPassword(_password); _password = null; #endif _dataSource = System.IO.Path.GetFileNameWithoutExtension(fileName); OnStateChange(ConnectionState.Open); _version++; using (SqliteCommand cmd = CreateCommand()) { string defValue; defValue = FindKey(opts, "Synchronous", "Normal"); if (String.Compare(defValue, "Normal", true, CultureInfo.InvariantCulture) != 0) { cmd.CommandText = String.Format(CultureInfo.InvariantCulture, "PRAGMA Synchronous={0}", defValue); cmd.ExecuteNonQuery(); } defValue = FindKey(opts, "Cache Size", "2000"); if (Convert.ToInt32(defValue) != 2000) { cmd.CommandText = String.Format(CultureInfo.InvariantCulture, "PRAGMA Cache_Size={0}", defValue); cmd.ExecuteNonQuery(); } if (fileName != ":memory:") { defValue = FindKey(opts, "Page Size", "1024"); if (Convert.ToInt32(defValue) != 1024) { cmd.CommandText = String.Format(CultureInfo.InvariantCulture, "PRAGMA Page_Size={0}", defValue); cmd.ExecuteNonQuery(); } } } #if !PLATFORM_COMPACTFRAMEWORK if (FindKey(opts, "Enlist", "Y").ToUpper()[0] == 'Y' && System.Transactions.Transaction.Current != null) EnlistTransaction(System.Transactions.Transaction.Current); #endif } catch (SqliteException) { OnStateChange(ConnectionState.Broken); throw; } } /// /// Returns the version of the underlying Sqlite database engine /// #if !PLATFORM_COMPACTFRAMEWORK [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] #endif public override string ServerVersion { get { if (_connectionState != ConnectionState.Open) throw new InvalidOperationException(); return _sql.Version; } } /// /// Returns the state of the connection. /// #if !PLATFORM_COMPACTFRAMEWORK [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] #endif public override ConnectionState State { get { return _connectionState; } } #if MONO_SUPPORT_PASSWORDS // Not used on mono now /// /// Change the password (or assign a password) to an open database. /// /// /// No readers or writers may be active for this process. The database must already be open /// and if it already was password protected, the existing password must already have been supplied. /// /// The new password to assign to the database public void ChangePassword(string newPassword) { ChangePassword(String.IsNullOrEmpty(newPassword) ? null : System.Text.UTF8Encoding.UTF8.GetBytes(newPassword)); } /// /// Change the password (or assign a password) to an open database. /// /// /// No readers or writers may be active for this process. The database must already be open /// and if it already was password protected, the existing password must already have been supplied. /// /// The new password to assign to the database public void ChangePassword(byte[] newPassword) { if (_connectionState != ConnectionState.Open) throw new InvalidOperationException("Database must be opened before changing the password."); _sql.ChangePassword(newPassword); } /// /// Sets the password for a password-protected database. A password-protected database is /// unusable for any operation until the password has been set. /// /// The password for the database public void SetPassword(string databasePassword) { SetPassword(String.IsNullOrEmpty(databasePassword) ? null : System.Text.UTF8Encoding.UTF8.GetBytes(databasePassword)); } /// /// Sets the password for a password-protected database. A password-protected database is /// unusable for any operation until the password has been set. /// /// The password for the database public void SetPassword(byte[] databasePassword) { if (_connectionState != ConnectionState.Closed) throw new InvalidOperationException("Password can only be set before the database is opened."); if (databasePassword != null) if (databasePassword.Length == 0) databasePassword = null; _password = databasePassword; } #endif /// /// Expand the filename of the data source, resolving the |DataDirectory| macro as appropriate. /// /// The database filename to expand /// The expanded path and filename of the filename private string ExpandFileName(string sourceFile) { if (String.IsNullOrEmpty(sourceFile)) return sourceFile; if (sourceFile.StartsWith(_dataDirectory, StringComparison.OrdinalIgnoreCase)) { string dataDirectory; #if PLATFORM_COMPACTFRAMEWORK dataDirectory = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetCallingAssembly().GetName().CodeBase); #else dataDirectory = AppDomain.CurrentDomain.GetData("DataDirectory") as string; if (String.IsNullOrEmpty(dataDirectory)) dataDirectory = AppDomain.CurrentDomain.BaseDirectory; #endif if (sourceFile.Length > _dataDirectory.Length) { if (sourceFile[_dataDirectory.Length] == System.IO.Path.DirectorySeparatorChar || sourceFile[_dataDirectory.Length] == System.IO.Path.AltDirectorySeparatorChar) sourceFile = sourceFile.Remove(_dataDirectory.Length, 1); } sourceFile = System.IO.Path.Combine(dataDirectory, sourceFile.Substring(_dataDirectory.Length)); } return sourceFile; } /// /// The following commands are used to extract schema information out of the database. Valid schema types are: /// /// /// MetaDataCollections /// /// /// DataSourceInformation /// /// /// Catalogs /// /// /// Columns /// /// /// ForeignKeys /// /// /// Indexes /// /// /// IndexColumns /// /// /// Tables /// /// /// Views /// /// /// ViewColumns /// /// /// /// /// Returns the MetaDataCollections schema /// /// A DataTable of the MetaDataCollections schema public override DataTable GetSchema() { return GetSchema("MetaDataCollections", null); } /// /// Returns schema information of the specified collection /// /// The schema collection to retrieve /// A DataTable of the specified collection public override DataTable GetSchema(string collectionName) { return GetSchema(collectionName, new string[0]); } /// /// Retrieves schema information using the specified constraint(s) for the specified collection /// /// The collection to retrieve /// The restrictions to impose /// A DataTable of the specified collection public override DataTable GetSchema(string collectionName, string[] restrictionValues) { if (_connectionState != ConnectionState.Open) throw new InvalidOperationException(); string[] parms = new string[5]; if (restrictionValues == null) restrictionValues = new string[0]; restrictionValues.CopyTo(parms, 0); switch (collectionName.ToUpper(CultureInfo.InvariantCulture)) { case "METADATACOLLECTIONS": return Schema_MetaDataCollections(); case "DATASOURCEINFORMATION": return Schema_DataSourceInformation(); case "DATATYPES": return Schema_DataTypes(); case "COLUMNS": return Schema_Columns(parms[0], parms[2], parms[3]); case "INDEXES": return Schema_Indexes(parms[0], parms[2], parms[4]); case "INDEXCOLUMNS": return Schema_IndexColumns(parms[0], parms[2], parms[3], parms[4]); case "TABLES": return Schema_Tables(parms[0], parms[2], parms[3]); case "VIEWS": return Schema_Views(parms[0], parms[2]); case "VIEWCOLUMNS": return Schema_ViewColumns(parms[0], parms[2], parms[3]); case "FOREIGNKEYS": return Schema_ForeignKeys(parms[0], parms[2], parms[3]); case "CATALOGS": return Schema_Catalogs(parms[0]); case "RESERVEDWORDS": return Schema_ReservedWords(); } throw new NotSupportedException(); } private static DataTable Schema_ReservedWords() { DataTable tbl = new DataTable("MetaDataCollections"); tbl.Locale = CultureInfo.InvariantCulture; tbl.Columns.Add("ReservedWord", typeof(string)); tbl.Columns.Add("MaximumVersion", typeof(string)); tbl.Columns.Add("MinimumVersion", typeof(string)); tbl.BeginLoadData(); DataRow row; foreach (string word in SR.Keywords.Split(new char[] { ',' })) { row = tbl.NewRow(); row[0] = word; tbl.Rows.Add(row); } tbl.AcceptChanges(); tbl.EndLoadData(); return tbl; } /// /// Builds a MetaDataCollections schema datatable /// /// DataTable private static DataTable Schema_MetaDataCollections() { DataTable tbl = new DataTable("MetaDataCollections"); tbl.Locale = CultureInfo.InvariantCulture; tbl.Columns.Add("CollectionName", typeof(string)); tbl.Columns.Add("NumberOfRestrictions", typeof(int)); tbl.Columns.Add("NumberOfIdentifierParts", typeof(int)); tbl.BeginLoadData(); System.IO.StringReader reader = new System.IO.StringReader(SR.MetaDataCollections); tbl.ReadXml(reader); reader.Close(); tbl.AcceptChanges(); tbl.EndLoadData(); return tbl; } /// /// Builds a DataSourceInformation datatable /// /// DataTable private DataTable Schema_DataSourceInformation() { DataTable tbl = new DataTable("DataSourceInformation"); DataRow row; tbl.Locale = CultureInfo.InvariantCulture; tbl.Columns.Add(DbMetaDataColumnNames.CompositeIdentifierSeparatorPattern, typeof(string)); tbl.Columns.Add(DbMetaDataColumnNames.DataSourceProductName, typeof(string)); tbl.Columns.Add(DbMetaDataColumnNames.DataSourceProductVersion, typeof(string)); tbl.Columns.Add(DbMetaDataColumnNames.DataSourceProductVersionNormalized, typeof(string)); tbl.Columns.Add(DbMetaDataColumnNames.GroupByBehavior, typeof(int)); tbl.Columns.Add(DbMetaDataColumnNames.IdentifierPattern, typeof(string)); tbl.Columns.Add(DbMetaDataColumnNames.IdentifierCase, typeof(int)); tbl.Columns.Add(DbMetaDataColumnNames.OrderByColumnsInSelect, typeof(bool)); tbl.Columns.Add(DbMetaDataColumnNames.ParameterMarkerFormat, typeof(string)); tbl.Columns.Add(DbMetaDataColumnNames.ParameterMarkerPattern, typeof(string)); tbl.Columns.Add(DbMetaDataColumnNames.ParameterNameMaxLength, typeof(int)); tbl.Columns.Add(DbMetaDataColumnNames.ParameterNamePattern, typeof(string)); tbl.Columns.Add(DbMetaDataColumnNames.QuotedIdentifierPattern, typeof(string)); tbl.Columns.Add(DbMetaDataColumnNames.QuotedIdentifierCase, typeof(int)); tbl.Columns.Add(DbMetaDataColumnNames.StatementSeparatorPattern, typeof(string)); tbl.Columns.Add(DbMetaDataColumnNames.StringLiteralPattern, typeof(string)); tbl.Columns.Add(DbMetaDataColumnNames.SupportedJoinOperators, typeof(int)); tbl.BeginLoadData(); row = tbl.NewRow(); row.ItemArray = new object[] { null, "Sqlite", _sql.Version, _sql.Version, 3, @"(^\[\p{Lo}\p{Lu}\p{Ll}_@#][\p{Lo}\p{Lu}\p{Ll}\p{Nd}@$#_]*$)|(^\[[^\]\0]|\]\]+\]$)|(^\""[^\""\0]|\""\""+\""$)", 1, false, "{0}", @"@[\p{Lo}\p{Lu}\p{Ll}\p{Lm}_@#][\p{Lo}\p{Lu}\p{Ll}\p{Lm}\p{Nd}\uff3f_@#\$]*(?=\s+|$)", 255, @"^[\p{Lo}\p{Lu}\p{Ll}\p{Lm}_@#][\p{Lo}\p{Lu}\p{Ll}\p{Lm}\p{Nd}\uff3f_@#\$]*(?=\s+|$)", @"(([^\[]|\]\])*)", 1, ";", @"'(([^']|'')*)'", // ' a bug in c-sharp mode for emacs 15 }; tbl.Rows.Add(row); tbl.AcceptChanges(); tbl.EndLoadData(); return tbl; } /// /// Build a Columns schema /// /// The catalog (attached database) to query, can be null /// The table to retrieve schema information for, must not be null /// The column to retrieve schema information for, can be null /// DataTable private DataTable Schema_Columns(string strCatalog, string strTable, string strColumn) { DataTable tbl = new DataTable("Columns"); DataRow row; tbl.Locale = CultureInfo.InvariantCulture; tbl.Columns.Add("TABLE_CATALOG", typeof(string)); tbl.Columns.Add("TABLE_SCHEMA", typeof(string)); tbl.Columns.Add("TABLE_NAME", typeof(string)); tbl.Columns.Add("COLUMN_NAME", typeof(string)); tbl.Columns.Add("COLUMN_GUID", typeof(Guid)); tbl.Columns.Add("COLUMN_PROPID", typeof(long)); tbl.Columns.Add("ORDINAL_POSITION", typeof(int)); tbl.Columns.Add("COLUMN_HASDEFAULT", typeof(bool)); tbl.Columns.Add("COLUMN_DEFAULT", typeof(string)); tbl.Columns.Add("COLUMN_FLAGS", typeof(long)); tbl.Columns.Add("IS_NULLABLE", typeof(bool)); tbl.Columns.Add("DATA_TYPE", typeof(string)); tbl.Columns.Add("TYPE_GUID", typeof(Guid)); tbl.Columns.Add("CHARACTER_MAXIMUM_LENGTH", typeof(int)); tbl.Columns.Add("CHARACTER_OCTET_LENGTH", typeof(int)); tbl.Columns.Add("NUMERIC_PRECISION", typeof(int)); tbl.Columns.Add("NUMERIC_SCALE", typeof(int)); tbl.Columns.Add("DATETIME_PRECISION", typeof(long)); tbl.Columns.Add("CHARACTER_SET_CATALOG", typeof(string)); tbl.Columns.Add("CHARACTER_SET_SCHEMA", typeof(string)); tbl.Columns.Add("CHARACTER_SET_NAME", typeof(string)); tbl.Columns.Add("COLLATION_CATALOG", typeof(string)); tbl.Columns.Add("COLLATION_SCHEMA", typeof(string)); tbl.Columns.Add("COLLATION_NAME", typeof(string)); tbl.Columns.Add("DOMAIN_CATALOG", typeof(string)); tbl.Columns.Add("DOMAIN_NAME", typeof(string)); tbl.Columns.Add("DESCRIPTION", typeof(string)); tbl.Columns.Add("PRIMARY_KEY", typeof(bool)); tbl.BeginLoadData(); if (String.IsNullOrEmpty(strCatalog)) strCatalog = "main"; using (SqliteCommand cmdTables = new SqliteCommand(String.Format(CultureInfo.InvariantCulture, "SELECT * FROM [{0}].[sqlite_master] WHERE [type] LIKE 'table' OR [type] LIKE 'view'", strCatalog), this)) using (SqliteDataReader rdTables = cmdTables.ExecuteReader()) { while (rdTables.Read()) { if (String.IsNullOrEmpty(strTable) || String.Compare(strTable, rdTables.GetString(2), true, CultureInfo.InvariantCulture) == 0) { using (SqliteCommand cmd = new SqliteCommand(String.Format(CultureInfo.InvariantCulture, "SELECT * FROM [{0}].[{1}]", strCatalog, rdTables.GetString(2)), this)) using (SqliteDataReader rd = (SqliteDataReader)cmd.ExecuteReader(CommandBehavior.SchemaOnly)) using (DataTable tblSchema = rd.GetSchemaTable(false, true)) { foreach (DataRow schemaRow in tblSchema.Rows) { if (String.Compare(schemaRow[SchemaTableColumn.ColumnName].ToString(), strColumn, true, CultureInfo.InvariantCulture) == 0 || strColumn == null) { row = tbl.NewRow(); row["TABLE_NAME"] = rdTables.GetString(2); row["COLUMN_NAME"] = schemaRow[SchemaTableColumn.ColumnName]; row["TABLE_CATALOG"] = strCatalog; row["ORDINAL_POSITION"] = schemaRow[SchemaTableColumn.ColumnOrdinal]; row["COLUMN_HASDEFAULT"] = (schemaRow[SchemaTableOptionalColumn.DefaultValue] != DBNull.Value); row["COLUMN_DEFAULT"] = schemaRow[SchemaTableOptionalColumn.DefaultValue]; row["IS_NULLABLE"] = schemaRow[SchemaTableColumn.AllowDBNull]; row["DATA_TYPE"] = schemaRow["DataTypeName"]; // SqliteConvert.DbTypeToType((DbType)schemaRow[SchemaTableColumn.ProviderType]).ToString(); row["CHARACTER_MAXIMUM_LENGTH"] = schemaRow[SchemaTableColumn.ColumnSize]; row["TABLE_SCHEMA"] = schemaRow[SchemaTableColumn.BaseSchemaName]; row["PRIMARY_KEY"] = schemaRow[SchemaTableColumn.IsKey]; tbl.Rows.Add(row); } } } } } } tbl.AcceptChanges(); tbl.EndLoadData(); return tbl; } /// /// Returns index information for the given database and catalog /// /// The catalog (attached database) to query, can be null /// The name of the index to retrieve information for, can be null /// The table to retrieve index information for, can be null /// DataTable private DataTable Schema_Indexes(string strCatalog, string strTable, string strIndex) { DataTable tbl = new DataTable("Indexes"); DataRow row; System.Collections.Generic.List primaryKeys = new List(); bool maybeRowId; tbl.Locale = CultureInfo.InvariantCulture; tbl.Columns.Add("TABLE_CATALOG", typeof(string)); tbl.Columns.Add("TABLE_SCHEMA", typeof(string)); tbl.Columns.Add("TABLE_NAME", typeof(string)); tbl.Columns.Add("INDEX_CATALOG", typeof(string)); tbl.Columns.Add("INDEX_SCHEMA", typeof(string)); tbl.Columns.Add("INDEX_NAME", typeof(string)); tbl.Columns.Add("PRIMARY_KEY", typeof(bool)); tbl.Columns.Add("UNIQUE", typeof(bool)); tbl.Columns.Add("CLUSTERED", typeof(bool)); tbl.Columns.Add("TYPE", typeof(int)); tbl.Columns.Add("FILL_FACTOR", typeof(int)); tbl.Columns.Add("INITIAL_SIZE", typeof(int)); tbl.Columns.Add("NULLS", typeof(int)); tbl.Columns.Add("SORT_BOOKMARKS", typeof(bool)); tbl.Columns.Add("AUTO_UPDATE", typeof(bool)); tbl.Columns.Add("NULL_COLLATION", typeof(int)); tbl.Columns.Add("ORDINAL_POSITION", typeof(int)); tbl.Columns.Add("COLUMN_NAME", typeof(string)); tbl.Columns.Add("COLUMN_GUID", typeof(Guid)); tbl.Columns.Add("COLUMN_PROPID", typeof(long)); tbl.Columns.Add("COLLATION", typeof(short)); tbl.Columns.Add("CARDINALITY", typeof(Decimal)); tbl.Columns.Add("PAGES", typeof(int)); tbl.Columns.Add("FILTER_CONDITION", typeof(string)); tbl.Columns.Add("INTEGRATED", typeof(bool)); tbl.BeginLoadData(); if (String.IsNullOrEmpty(strCatalog)) strCatalog = "main"; using (SqliteCommand cmdTables = new SqliteCommand(String.Format(CultureInfo.InvariantCulture, "SELECT * FROM [{0}].[sqlite_master] WHERE [type] LIKE 'table'", strCatalog), this)) using (SqliteDataReader rdTables = cmdTables.ExecuteReader()) { while (rdTables.Read()) { maybeRowId = false; primaryKeys.Clear(); if (String.IsNullOrEmpty(strTable) || String.Compare(rdTables.GetString(2), strTable, true, CultureInfo.InvariantCulture) == 0) { // First, look for any rowid indexes -- which sqlite defines are INTEGER PRIMARY KEY columns. // Such indexes are not listed in the indexes list but count as indexes just the same. using (SqliteCommand cmdTable = new SqliteCommand(String.Format(CultureInfo.InvariantCulture, "PRAGMA [{0}].table_info([{1}])", strCatalog, rdTables.GetString(2)), this)) using (SqliteDataReader rdTable = cmdTable.ExecuteReader()) { while (rdTable.Read()) { if (rdTable.GetInt32(5) == 1) { primaryKeys.Add(rdTable.GetInt32(0)); // If the primary key is of type INTEGER, then its a rowid and we need to make a fake index entry for it. if (String.Compare(rdTable.GetString(2), "INTEGER", true, CultureInfo.InvariantCulture) == 0) maybeRowId = true; } } } if (primaryKeys.Count == 1 && maybeRowId == true) { row = tbl.NewRow(); row["TABLE_CATALOG"] = strCatalog; row["TABLE_NAME"] = rdTables.GetString(2); row["INDEX_CATALOG"] = strCatalog; row["PRIMARY_KEY"] = true; row["INDEX_NAME"] = String.Format(CultureInfo.InvariantCulture, "sqlite_master_PK_{0}", rdTables.GetString(2)); row["UNIQUE"] = true; if (String.Compare((string)row["INDEX_NAME"], strIndex, true, CultureInfo.InvariantCulture) == 0 || strIndex == null) { tbl.Rows.Add(row); } primaryKeys.Clear(); } // Now fetch all the rest of the indexes. using (SqliteCommand cmd = new SqliteCommand(String.Format(CultureInfo.InvariantCulture, "PRAGMA [{0}].index_list([{1}])", strCatalog, rdTables.GetString(2)), this)) using (SqliteDataReader rd = (SqliteDataReader)cmd.ExecuteReader()) { while (rd.Read()) { if (String.Compare(rd.GetString(1), strIndex, true, CultureInfo.InvariantCulture) == 0 || strIndex == null) { row = tbl.NewRow(); row["TABLE_CATALOG"] = strCatalog; row["TABLE_NAME"] = rdTables.GetString(2); row["INDEX_CATALOG"] = strCatalog; row["INDEX_NAME"] = rd.GetString(1); row["UNIQUE"] = rd.GetBoolean(2); row["PRIMARY_KEY"] = false; // Now for the really hard work. Figure out which index is the primary key index. // The only way to figure it out is to check if the index was an autoindex and if we have a non-rowid // primary key, and all the columns in the given index match the primary key columns if (primaryKeys.Count > 0 && rd.GetString(1).StartsWith("sqlite_autoindex_" + rdTables.GetString(2), StringComparison.InvariantCultureIgnoreCase) == true) { using (SqliteCommand cmdDetails = new SqliteCommand(String.Format(CultureInfo.InvariantCulture, "PRAGMA [{0}].index_info([{1}])", strCatalog, rd.GetString(1)), this)) using (SqliteDataReader rdDetails = cmdDetails.ExecuteReader()) { int nMatches = 0; while (rdDetails.Read()) { if (primaryKeys.Contains(rdDetails.GetInt32(1)) == false) { nMatches = 0; break; } nMatches++; } if (nMatches == primaryKeys.Count) { row["PRIMARY_KEY"] = true; primaryKeys.Clear(); } } } tbl.Rows.Add(row); } } } } } } tbl.AcceptChanges(); tbl.EndLoadData(); return tbl; } /// /// Retrieves table schema information for the database and catalog /// /// The catalog (attached database) to retrieve tables on /// The table to retrieve, can be null /// The table type, can be null /// DataTable private DataTable Schema_Tables(string strCatalog, string strTable, string strType) { DataTable tbl = new DataTable("Tables"); DataRow row; string strItem; tbl.Locale = CultureInfo.InvariantCulture; tbl.Columns.Add("TABLE_CATALOG", typeof(string)); tbl.Columns.Add("TABLE_SCHEMA", typeof(string)); tbl.Columns.Add("TABLE_NAME", typeof(string)); tbl.Columns.Add("TABLE_TYPE", typeof(string)); tbl.Columns.Add("TABLE_ID", typeof(long)); tbl.Columns.Add("TABLE_ROOTPAGE", typeof(int)); tbl.BeginLoadData(); if (String.IsNullOrEmpty(strCatalog)) strCatalog = "main"; using (SqliteCommand cmd = new SqliteCommand(String.Format(CultureInfo.InvariantCulture, "SELECT [type], [name], [tbl_name], [rootpage], [sql], [rowid] FROM [{0}].[sqlite_master] WHERE [type] LIKE 'table'", strCatalog), this)) using (SqliteDataReader rd = (SqliteDataReader)cmd.ExecuteReader()) { while (rd.Read()) { strItem = rd.GetString(0); if (String.Compare(rd.GetString(2), 0, "SQLITE_", 0, 7, true, CultureInfo.InvariantCulture) == 0) strItem = "SYSTEM_TABLE"; if (String.Compare(strType, strItem, true, CultureInfo.InvariantCulture) == 0 || strType == null) { if (String.Compare(rd.GetString(2), strTable, true, CultureInfo.InvariantCulture) == 0 || strTable == null) { row = tbl.NewRow(); row["TABLE_CATALOG"] = strCatalog; row["TABLE_NAME"] = rd.GetString(2); row["TABLE_TYPE"] = strItem; row["TABLE_ID"] = rd.GetInt64(5); row["TABLE_ROOTPAGE"] = rd.GetInt32(3); tbl.Rows.Add(row); } } } } tbl.AcceptChanges(); tbl.EndLoadData(); return tbl; } /// /// Retrieves view schema information for the database /// /// The catalog (attached database) to retrieve views on /// The view name, can be null /// DataTable private DataTable Schema_Views(string strCatalog, string strView) { DataTable tbl = new DataTable("Views"); DataRow row; string strItem; int nPos; tbl.Locale = CultureInfo.InvariantCulture; tbl.Columns.Add("TABLE_CATALOG", typeof(string)); tbl.Columns.Add("TABLE_SCHEMA", typeof(string)); tbl.Columns.Add("TABLE_NAME", typeof(string)); tbl.Columns.Add("VIEW_DEFINITION", typeof(string)); tbl.Columns.Add("CHECK_OPTION", typeof(bool)); tbl.Columns.Add("IS_UPDATABLE", typeof(bool)); tbl.Columns.Add("DESCRIPTION", typeof(string)); tbl.Columns.Add("DATE_CREATED", typeof(DateTime)); tbl.Columns.Add("DATE_MODIFIED", typeof(DateTime)); tbl.BeginLoadData(); if (String.IsNullOrEmpty(strCatalog)) strCatalog = "main"; using (SqliteCommand cmd = new SqliteCommand(String.Format(CultureInfo.InvariantCulture, "SELECT * FROM [{0}].[sqlite_master] WHERE [type] LIKE 'view'", strCatalog), this)) using (SqliteDataReader rd = (SqliteDataReader)cmd.ExecuteReader()) { while (rd.Read()) { if (String.Compare(rd.GetString(1), strView, true, CultureInfo.InvariantCulture) == 0 || String.IsNullOrEmpty(strView)) { strItem = rd.GetString(4).Replace('\r', ' ').Replace('\n', ' ').Replace('\t', ' '); nPos = System.Globalization.CultureInfo.InvariantCulture.CompareInfo.IndexOf(strItem, " AS ", CompareOptions.IgnoreCase); if (nPos > -1) { strItem = strItem.Substring(nPos + 4).Trim(); row = tbl.NewRow(); row["TABLE_CATALOG"] = strCatalog; row["TABLE_NAME"] = rd.GetString(2); row["IS_UPDATABLE"] = false; row["VIEW_DEFINITION"] = strItem; tbl.Rows.Add(row); } } } } tbl.AcceptChanges(); tbl.EndLoadData(); return tbl; } /// /// Retrieves catalog (attached databases) schema information for the database /// /// The catalog to retrieve, can be null /// DataTable private DataTable Schema_Catalogs(string strCatalog) { DataTable tbl = new DataTable("Catalogs"); DataRow row; tbl.Locale = CultureInfo.InvariantCulture; tbl.Columns.Add("CATALOG_NAME", typeof(string)); tbl.Columns.Add("DESCRIPTION", typeof(string)); tbl.Columns.Add("ID", typeof(long)); tbl.BeginLoadData(); using (SqliteCommand cmd = new SqliteCommand("PRAGMA database_list", this)) using (SqliteDataReader rd = (SqliteDataReader)cmd.ExecuteReader()) { while (rd.Read()) { if (String.Compare(rd.GetString(1), strCatalog, true, CultureInfo.InvariantCulture) == 0 || strCatalog == null) { row = tbl.NewRow(); row["CATALOG_NAME"] = rd.GetString(1); row["DESCRIPTION"] = rd.GetString(2); row["ID"] = rd.GetInt64(0); tbl.Rows.Add(row); } } } tbl.AcceptChanges(); tbl.EndLoadData(); return tbl; } private DataTable Schema_DataTypes() { DataTable tbl = new DataTable("DataTypes"); tbl.Locale = CultureInfo.InvariantCulture; tbl.Columns.Add("TypeName", typeof(String)); tbl.Columns.Add("ProviderDbType", typeof(int)); tbl.Columns.Add("ColumnSize", typeof(long)); tbl.Columns.Add("CreateFormat", typeof(String)); tbl.Columns.Add("CreateParameters", typeof(String)); tbl.Columns.Add("DataType", typeof(String)); tbl.Columns.Add("IsAutoIncrementable", typeof(bool)); tbl.Columns.Add("IsBestMatch", typeof(bool)); tbl.Columns.Add("IsCaseSensitive", typeof(bool)); tbl.Columns.Add("IsFixedLength", typeof(bool)); tbl.Columns.Add("IsFixedPrecisionScale", typeof(bool)); tbl.Columns.Add("IsLong", typeof(bool)); tbl.Columns.Add("IsNullable", typeof(bool)); tbl.Columns.Add("IsSearchable", typeof(bool)); tbl.Columns.Add("IsSearchableWithLike", typeof(bool)); tbl.Columns.Add("IsLiteralSupported", typeof(bool)); tbl.Columns.Add("LiteralPrefix", typeof(String)); tbl.Columns.Add("LiteralSuffix", typeof(String)); tbl.Columns.Add("IsUnsigned", typeof(bool)); tbl.Columns.Add("MaximumScale", typeof(short)); tbl.Columns.Add("MinimumScale", typeof(short)); tbl.Columns.Add("IsConcurrencyType", typeof(bool)); tbl.BeginLoadData(); System.IO.StringReader reader = new System.IO.StringReader(SR.DataTypes); tbl.ReadXml(reader); reader.Close(); tbl.AcceptChanges(); tbl.EndLoadData(); return tbl; } /// /// Returns the base column information for indexes in a database /// /// The catalog to retrieve indexes for (can be null) /// The table to restrict index information by (can be null) /// The index to restrict index information by (can be null) /// The source column to restrict index information by (can be null) /// A DataTable containing the results private DataTable Schema_IndexColumns(string strCatalog, string strTable, string strIndex, string strColumn) { DataTable tbl = new DataTable("IndexColumns"); DataRow row; List> primaryKeys = new List>(); bool maybeRowId; tbl.Locale = CultureInfo.InvariantCulture; tbl.Columns.Add("CONSTRAINT_CATALOG", typeof(string)); tbl.Columns.Add("CONSTRAINT_SCHEMA", typeof(string)); tbl.Columns.Add("CONSTRAINT_NAME", typeof(string)); tbl.Columns.Add("TABLE_CATALOG", typeof(string)); tbl.Columns.Add("TABLE_SCHEMA", typeof(string)); tbl.Columns.Add("TABLE_NAME", typeof(string)); tbl.Columns.Add("COLUMN_NAME", typeof(string)); tbl.Columns.Add("ORDINAL_POSITION", typeof(int)); tbl.Columns.Add("INDEX_NAME", typeof(string)); if (String.IsNullOrEmpty(strCatalog)) strCatalog = "main"; tbl.BeginLoadData(); using (SqliteCommand cmdTables = new SqliteCommand(String.Format(CultureInfo.InvariantCulture, "SELECT * FROM [{0}].[sqlite_master] WHERE [type] LIKE 'table'", strCatalog), this)) using (SqliteDataReader rdTables = cmdTables.ExecuteReader()) { while (rdTables.Read()) { maybeRowId = false; primaryKeys.Clear(); if (String.IsNullOrEmpty(strTable) || String.Compare(rdTables.GetString(2), strTable, true, CultureInfo.InvariantCulture) == 0) { using (SqliteCommand cmdTable = new SqliteCommand(String.Format(CultureInfo.InvariantCulture, "PRAGMA [{0}].table_info([{1}])", strCatalog, rdTables.GetString(2)), this)) using (SqliteDataReader rdTable = cmdTable.ExecuteReader()) { while (rdTable.Read()) { if (rdTable.GetInt32(5) == 1) // is a primary key { primaryKeys.Add(new KeyValuePair(rdTable.GetInt32(0), rdTable.GetString(1))); // Is an integer -- could be a rowid if no other primary keys exist in the table if (String.Compare(rdTable.GetString(2), "INTEGER", true, CultureInfo.InvariantCulture) == 0) maybeRowId = true; } } } if (primaryKeys.Count == 1 && maybeRowId == true) { row = tbl.NewRow(); row["CONSTRAINT_CATALOG"] = strCatalog; row["CONSTRAINT_NAME"] = String.Format(CultureInfo.InvariantCulture, "sqlite_master_PK_{0}", rdTables.GetString(2)); row["TABLE_CATALOG"] = strCatalog; row["TABLE_NAME"] = rdTables.GetString(2); row["COLUMN_NAME"] = primaryKeys[0].Value; row["INDEX_NAME"] = row["CONSTRAINT_NAME"]; row["ORDINAL_POSITION"] = primaryKeys[0].Key; if (String.IsNullOrEmpty(strIndex) || String.Compare(strIndex, (string)row["INDEX_NAME"], true, CultureInfo.InvariantCulture) == 0) tbl.Rows.Add(row); } using (SqliteCommand cmdIndexes = new SqliteCommand(String.Format(CultureInfo.InvariantCulture, "SELECT * FROM [{0}].[sqlite_master] WHERE [type] LIKE 'index' AND [tbl_name] LIKE '{1}'", strCatalog, rdTables.GetString(2).Replace("'", "''")), this)) using (SqliteDataReader rdIndexes = cmdIndexes.ExecuteReader()) { while (rdIndexes.Read()) { if (String.IsNullOrEmpty(strIndex) || String.Compare(strIndex, rdIndexes.GetString(1), true, CultureInfo.InvariantCulture) == 0) { using (SqliteCommand cmdIndex = new SqliteCommand(String.Format(CultureInfo.InvariantCulture, "PRAGMA [{0}].index_info([{1}])", strCatalog, rdIndexes.GetString(1)), this)) using (SqliteDataReader rdIndex = cmdIndex.ExecuteReader()) { while (rdIndex.Read()) { row = tbl.NewRow(); row["CONSTRAINT_CATALOG"] = strCatalog; row["CONSTRAINT_NAME"] = rdIndexes.GetString(1); row["TABLE_CATALOG"] = strCatalog; row["TABLE_NAME"] = rdIndexes.GetString(2); row["COLUMN_NAME"] = rdIndex.GetString(2); row["INDEX_NAME"] = rdIndexes.GetString(1); row["ORDINAL_POSITION"] = rdIndex.GetInt32(1); if (String.IsNullOrEmpty(strColumn) || String.Compare(strColumn, row["COLUMN_NAME"].ToString(), true, CultureInfo.InvariantCulture) == 0) tbl.Rows.Add(row); } } } } } } } } tbl.EndLoadData(); tbl.AcceptChanges(); return tbl; } /// /// Returns detailed column information for a specified view /// /// The catalog to retrieve columns for (can be null) /// The view to restrict column information by (can be null) /// The source column to restrict column information by (can be null) /// A DataTable containing the results private DataTable Schema_ViewColumns(string strCatalog, string strView, string strColumn) { DataTable tbl = new DataTable("ViewColumns"); DataRow row; string strSql; int n; DataRow schemaRow; DataRow viewRow; tbl.Locale = CultureInfo.InvariantCulture; tbl.Columns.Add("VIEW_CATALOG", typeof(string)); tbl.Columns.Add("VIEW_SCHEMA", typeof(string)); tbl.Columns.Add("VIEW_NAME", typeof(string)); tbl.Columns.Add("VIEW_COLUMN_NAME", typeof(String)); tbl.Columns.Add("TABLE_CATALOG", typeof(string)); tbl.Columns.Add("TABLE_SCHEMA", typeof(string)); tbl.Columns.Add("TABLE_NAME", typeof(string)); tbl.Columns.Add("COLUMN_NAME", typeof(string)); if (String.IsNullOrEmpty(strCatalog)) strCatalog = "main"; tbl.BeginLoadData(); using (SqliteCommand cmdViews = new SqliteCommand(String.Format(CultureInfo.InvariantCulture, "SELECT * FROM [{0}].[sqlite_master] WHERE [type] LIKE 'view'", strCatalog), this)) using (SqliteDataReader rdViews = cmdViews.ExecuteReader()) { while (rdViews.Read()) { if (String.IsNullOrEmpty(strView) || String.Compare(strView, rdViews.GetString(2), true, CultureInfo.InvariantCulture) == 0) { using (SqliteCommand cmdViewSelect = new SqliteCommand(String.Format(CultureInfo.InvariantCulture, "SELECT * FROM [{0}].[{1}]", strCatalog, rdViews.GetString(2)), this)) { strSql = rdViews.GetString(4).Replace('\r', ' ').Replace('\n', ' ').Replace('\t', ' '); n = CultureInfo.InvariantCulture.CompareInfo.IndexOf(strSql, " AS ", CompareOptions.IgnoreCase); if (n < 0) continue; strSql = strSql.Substring(n + 4); using (SqliteCommand cmd = new SqliteCommand(strSql, this)) using (SqliteDataReader rdViewSelect = cmdViewSelect.ExecuteReader(CommandBehavior.SchemaOnly)) using (SqliteDataReader rd = (SqliteDataReader)cmd.ExecuteReader(CommandBehavior.SchemaOnly)) using (DataTable tblSchemaView = rdViewSelect.GetSchemaTable(false, false)) using (DataTable tblSchema = rd.GetSchemaTable(false, false)) { for (n = 0; n < tblSchema.Rows.Count; n++) { viewRow = tblSchemaView.Rows[n]; schemaRow = tblSchema.Rows[n]; if (String.Compare(viewRow[SchemaTableColumn.ColumnName].ToString(), strColumn, true, CultureInfo.InvariantCulture) == 0 || strColumn == null) { row = tbl.NewRow(); row["VIEW_CATALOG"] = strCatalog; row["VIEW_NAME"] = rdViews.GetString(2); row["TABLE_CATALOG"] = strCatalog; row["TABLE_SCHEMA"] = schemaRow[SchemaTableColumn.BaseSchemaName]; row["TABLE_NAME"] = schemaRow[SchemaTableColumn.BaseTableName]; row["COLUMN_NAME"] = schemaRow[SchemaTableColumn.ColumnName]; row["VIEW_COLUMN_NAME"] = viewRow[SchemaTableColumn.ColumnName]; tbl.Rows.Add(row); } } } } } } } tbl.EndLoadData(); tbl.AcceptChanges(); return tbl; } /// /// Retrieves foreign key information from the specified set of filters /// /// An optional catalog to restrict results on /// An optional table to restrict results on /// An optional foreign key name to restrict results on /// A DataTable with the results of the query private DataTable Schema_ForeignKeys(string strCatalog, string strTable, string strKeyName) { DataTable tbl = new DataTable("ForeignKeys"); DataRow row; tbl.Locale = CultureInfo.InvariantCulture; tbl.Columns.Add("CONSTRAINT_CATALOG", typeof(string)); tbl.Columns.Add("CONSTRAINT_SCHEMA", typeof(string)); tbl.Columns.Add("CONSTRAINT_NAME", typeof(string)); tbl.Columns.Add("TABLE_CATALOG", typeof(string)); tbl.Columns.Add("TABLE_SCHEMA", typeof(string)); tbl.Columns.Add("TABLE_NAME", typeof(string)); tbl.Columns.Add("CONSTRAINT_TYPE", typeof(string)); tbl.Columns.Add("IS_DEFERRABLE", typeof(bool)); tbl.Columns.Add("INITIALLY_DEFERRED", typeof(bool)); tbl.Columns.Add("FKEY_FROM_COLUMN", typeof(string)); tbl.Columns.Add("FKEY_FROM_ORDINAL_POSITION", typeof(int)); tbl.Columns.Add("FKEY_TO_CATALOG", typeof(string)); tbl.Columns.Add("FKEY_TO_SCHEMA", typeof(string)); tbl.Columns.Add("FKEY_TO_TABLE", typeof(string)); tbl.Columns.Add("FKEY_TO_COLUMN", typeof(string)); if (String.IsNullOrEmpty(strCatalog)) strCatalog = "main"; tbl.BeginLoadData(); using (SqliteCommand cmdTables = new SqliteCommand(String.Format(CultureInfo.InvariantCulture, "SELECT * FROM [{0}].[sqlite_master] WHERE [type] LIKE 'table'", strCatalog), this)) using (SqliteDataReader rdTables = cmdTables.ExecuteReader()) { while (rdTables.Read()) { if (String.IsNullOrEmpty(strTable) || String.Compare(strTable, rdTables.GetString(2), true, CultureInfo.InvariantCulture) == 0) { using (SqliteCommand cmdTable = new SqliteCommand(String.Format(CultureInfo.InvariantCulture, "SELECT * FROM [{0}].[{1}]", strCatalog, rdTables.GetString(2)), this)) using (SqliteDataReader rdTable = cmdTable.ExecuteReader(CommandBehavior.SchemaOnly)) using (SqliteCommand cmdKey = new SqliteCommand(String.Format(CultureInfo.InvariantCulture, "PRAGMA [{0}].foreign_key_list([{1}])", strCatalog, rdTables.GetString(2)), this)) using (SqliteDataReader rdKey = cmdKey.ExecuteReader()) { while (rdKey.Read()) { row = tbl.NewRow(); row["CONSTRAINT_CATALOG"] = strCatalog; row["CONSTRAINT_NAME"] = String.Format(CultureInfo.InvariantCulture, "FK_{0}_{1}_{2}", rdTables.GetString(2), rdKey.GetString(3), rdKey.GetString(4)); row["TABLE_CATALOG"] = strCatalog; row["TABLE_NAME"] = rdTables.GetString(2); row["CONSTRAINT_TYPE"] = "FOREIGN KEY"; row["IS_DEFERRABLE"] = false; row["INITIALLY_DEFERRED"] = false; row["FKEY_FROM_COLUMN"] = rdKey.GetString(3); row["FKEY_FROM_ORDINAL_POSITION"] = rdTable.GetOrdinal(row["FKEY_FROM_COLUMN"].ToString()); row["FKEY_TO_CATALOG"] = strCatalog; row["FKEY_TO_TABLE"] = rdKey.GetString(2); row["FKEY_TO_COLUMN"] = rdKey.GetString(4); if (String.IsNullOrEmpty(strKeyName) || String.Compare(strKeyName, row["CONSTRAINT_NAME"].ToString(), true, CultureInfo.InvariantCulture) == 0) tbl.Rows.Add(row); } } } } } tbl.EndLoadData(); tbl.AcceptChanges(); return tbl; } internal void AddCommand(SqliteCommand cmd) { lock (_commandList) { _commandList.Add(cmd); } } internal void RemoveCommand(SqliteCommand cmd) { lock (_commandList) { _commandList.Remove(cmd); } } #if MONO_BACKWARD_COMPAT /// /// Obsolete /// public override int ConnectionTimeout { get { return 30; } } public int Version { get { return 3; } } public long LastInsertRowId { get { return _sql.GetLastInsertRowId (); } } public int BusyTimeout { get { return _busyTimeout; } } #endif } /// /// The I/O file cache flushing behavior for the connection /// public enum SynchronizationModes { /// /// Normal file flushing at critical sections of the code /// Normal = 0, /// /// Full file flushing after every write operation /// Full = 1, /// /// Use the default operating system's file flushing, Sqlite does not explicitly flush the file buffers after writing /// Off = 2, } internal delegate void SqliteUpdateCallback(int type, IntPtr database, int databaseLen, IntPtr table, int tableLen, Int64 rowid); internal delegate int SqliteCommitCallback(); internal delegate void SqliteRollbackCallback(); /// /// Raised when a transaction is about to be committed. To roll back a transaction, set the /// rollbackTrans boolean value to true. /// /// The connection committing the transaction /// Event arguments on the transaction public delegate void SqliteCommitHandler(object sender, CommitEventArgs e); /// /// Raised when data is inserted, updated and deleted on a given connection /// /// The connection committing the transaction /// The event parameters which triggered the event public delegate void SqliteUpdateEventHandler(object sender, UpdateEventArgs e); /// /// Whenever an update event is triggered on a connection, this enum will indicate /// exactly what type of operation is being performed. /// public enum UpdateEventType { /// /// A row is being deleted from the given database and table /// Delete = 9, /// /// A row is being inserted into the table. /// Insert = 18, /// /// A row is being updated in the table. /// Update = 23, } /// /// Passed during an Update callback, these event arguments detail the type of update operation being performed /// on the given connection. /// public class UpdateEventArgs : EventArgs { /// /// The name of the database being updated (usually "main" but can be any attached or temporary database) /// public readonly string Database; /// /// The name of the table being updated /// public readonly string Table; /// /// The type of update being performed (insert/update/delete) /// public readonly UpdateEventType Event; /// /// The RowId affected by this update. /// public readonly Int64 RowId; internal UpdateEventArgs(string database, string table, UpdateEventType eventType, Int64 rowid) { Database = database; Table = table; Event = eventType; RowId = rowid; } } /// /// Event arguments raised when a transaction is being committed /// public class CommitEventArgs : EventArgs { internal CommitEventArgs() { } /// /// Set to true to abort the transaction and trigger a rollback /// public bool AbortTransaction; } } #endif hyena-0.5/Mono.Data.Sqlite/Mono.Data.Sqlite/SQLite3.cs0000644000175000001440000005172211377104476022433 0ustar00gabeusers00000000000000// // Mono.Data.Sqlite.SQLite3.cs // // Author(s): // Robert Simpson (robert@blackcastlesoft.com) // // Adapted and modified for the Mono Project by // Marek Habersack (grendello@gmail.com) // // // Copyright (C) 2006 Novell, Inc (http://www.novell.com) // Copyright (C) 2007 Marek Habersack // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // /******************************************************** * ADO.NET 2.0 Data Provider for Sqlite Version 3.X * Written by Robert Simpson (robert@blackcastlesoft.com) * * Released to the public domain, use at your own risk! ********************************************************/ #if NET_2_0 namespace Mono.Data.Sqlite { using System; using System.Data; using System.Runtime.InteropServices; using System.Collections.Generic; using System.Globalization; /// /// This class implements SqliteBase completely, and is the guts of the code that interop's Sqlite with .NET /// internal class Sqlite3 : SqliteBase { /// /// The opaque pointer returned to us by the sqlite provider /// protected IntPtr _sql; /// /// The user-defined functions registered on this connection /// protected SqliteFunction[] _functionsArray; internal Sqlite3(SqliteDateFormats fmt) : base(fmt) { } protected override void Dispose(bool bDisposing) { Close(); } internal override void Close() { if (_sql != IntPtr.Zero) { int n = UnsafeNativeMethods.sqlite3_close(_sql); if (n > 0) throw new SqliteException(n, SqliteLastError()); } _sql = IntPtr.Zero; } internal override void Cancel() { UnsafeNativeMethods.sqlite3_interrupt(_sql); } internal override string Version { get { return ToString (UnsafeNativeMethods.sqlite3_libversion()); } } internal override int Changes { get { return UnsafeNativeMethods.sqlite3_changes(_sql); } } internal override void Open(string strFilename) { if (_sql != IntPtr.Zero) return; int n = UnsafeNativeMethods.sqlite3_open(ToUTF8(strFilename), out _sql); if (n > 0) throw new SqliteException(n, SqliteLastError()); _functionsArray = SqliteFunction.BindFunctions(this); } internal override void SetTimeout(int nTimeoutMS) { int n = UnsafeNativeMethods.sqlite3_busy_timeout(_sql, nTimeoutMS); if (n > 0) throw new SqliteException(n, SqliteLastError()); } internal override bool Step(SqliteStatement stmt) { int n; long timeout = 0; Random rnd = null; while (true) { n = UnsafeNativeMethods.sqlite3_step(stmt._sqlite_stmt); if (n == 100) return true; if (n == 101) return false; if (n > 0) { int r; // An error occurred, attempt to reset the statement. If the reset worked because the // schema has changed, re-try the step again. If it errored our because the database // is locked, then keep retrying until the command timeout occurs. r = Reset(stmt); if (r == 0) throw new SqliteException(n, SqliteLastError()); else if (r == 6 && stmt._command != null) // SQLITE_LOCKED { // Keep trying if (timeout == 0) // First time we've encountered the lock { timeout = Environment.TickCount + (stmt._command._commandTimeout * 1000); rnd = new Random(); } // If we've exceeded the command's timeout, give up and throw an error if (Environment.TickCount - timeout > 0) { throw new SqliteException(r, SqliteLastError()); } else { // Otherwise sleep for a random amount of time up to 250ms UnsafeNativeMethods.sqlite3_sleep((uint)rnd.Next(1, 250)); } } } } } internal override void FinalizeStatement(SqliteStatement stmt) { if (stmt._sqlite_stmt != IntPtr.Zero) { int n = UnsafeNativeMethods.sqlite3_finalize(stmt._sqlite_stmt); if (n > 0) throw new SqliteException(n, SqliteLastError()); } stmt._sqlite_stmt = IntPtr.Zero; } internal override int Reset(SqliteStatement stmt) { int n; n = UnsafeNativeMethods.sqlite3_reset(stmt._sqlite_stmt); // If the schema changed, try and re-prepare it if (n == 17) // SQLITE_SCHEMA { // Recreate a dummy statement string str; using (SqliteStatement tmp = Prepare(stmt._sqlStatement, null, out str)) { // Finalize the existing statement FinalizeStatement(stmt); // Reassign a new statement pointer to the old statement and clear the temporary one stmt._sqlite_stmt = tmp._sqlite_stmt; tmp._sqlite_stmt = IntPtr.Zero; // Reapply parameters stmt.BindParameters(); } return -1; // Reset was OK, with schema change } else if (n == 6) // SQLITE_LOCKED return n; if (n > 0) throw new SqliteException(n, SqliteLastError()); return 0; // We reset OK, no schema changes } internal override string SqliteLastError() { return ToString(UnsafeNativeMethods.sqlite3_errmsg(_sql)); } internal override SqliteStatement Prepare(string strSql, SqliteStatement previous, out string strRemain) { IntPtr stmt = IntPtr.Zero; IntPtr ptr = IntPtr.Zero; int n = 17; int retries = 0; byte[] b = ToUTF8(strSql); string typedefs = null; SqliteStatement cmd = null; GCHandle handle = GCHandle.Alloc(b, GCHandleType.Pinned); IntPtr psql = handle.AddrOfPinnedObject(); try { while (n == 17 && retries < 3) { try { n = UnsafeNativeMethods.sqlite3_prepare_v2(_sql, psql, b.Length - 1, out stmt, out ptr); } catch (EntryPointNotFoundException) { n = UnsafeNativeMethods.sqlite3_prepare (_sql, psql, b.Length - 1, out stmt, out ptr); } retries++; if (n == 1) { if (String.Compare(SqliteLastError(), "near \"TYPES\": syntax error", StringComparison.OrdinalIgnoreCase) == 0) { int pos = strSql.IndexOf(';'); if (pos == -1) pos = strSql.Length - 1; typedefs = strSql.Substring(0, pos + 1); strSql = strSql.Substring(pos + 1); strRemain = ""; while (cmd == null && strSql.Length > 0) { cmd = Prepare(strSql, previous, out strRemain); strSql = strRemain; } if (cmd != null) cmd.SetTypes(typedefs); return cmd; } } } if (n > 0) throw new SqliteException(n, SqliteLastError()); strRemain = UTF8ToString(ptr); if (stmt != IntPtr.Zero) cmd = new SqliteStatement(this, stmt, strSql.Substring(0, strSql.Length - strRemain.Length), previous); return cmd; } finally { handle.Free(); } } internal override void Bind_Double(SqliteStatement stmt, int index, double value) { int n = UnsafeNativeMethods.sqlite3_bind_double(stmt._sqlite_stmt, index, value); if (n > 0) throw new SqliteException(n, SqliteLastError()); } internal override void Bind_Int32(SqliteStatement stmt, int index, int value) { int n = UnsafeNativeMethods.sqlite3_bind_int(stmt._sqlite_stmt, index, value); if (n > 0) throw new SqliteException(n, SqliteLastError()); } internal override void Bind_Int64(SqliteStatement stmt, int index, long value) { int n = UnsafeNativeMethods.sqlite3_bind_int64(stmt._sqlite_stmt, index, value); if (n > 0) throw new SqliteException(n, SqliteLastError()); } internal override void Bind_Text(SqliteStatement stmt, int index, string value) { byte[] b = ToUTF8(value); int n = UnsafeNativeMethods.sqlite3_bind_text(stmt._sqlite_stmt, index, b, b.Length - 1, (IntPtr)(-1)); if (n > 0) throw new SqliteException(n, SqliteLastError()); } internal override void Bind_DateTime(SqliteStatement stmt, int index, DateTime dt) { byte[] b = ToUTF8(dt); int n = UnsafeNativeMethods.sqlite3_bind_text(stmt._sqlite_stmt, index, b, b.Length - 1, (IntPtr)(-1)); if (n > 0) throw new SqliteException(n, SqliteLastError()); } internal override void Bind_Blob(SqliteStatement stmt, int index, byte[] blobData) { int n = UnsafeNativeMethods.sqlite3_bind_blob(stmt._sqlite_stmt, index, blobData, blobData.Length, (IntPtr)(-1)); if (n > 0) throw new SqliteException(n, SqliteLastError()); } internal override void Bind_Null(SqliteStatement stmt, int index) { int n = UnsafeNativeMethods.sqlite3_bind_null(stmt._sqlite_stmt, index); if (n > 0) throw new SqliteException(n, SqliteLastError()); } internal override int Bind_ParamCount(SqliteStatement stmt) { return UnsafeNativeMethods.sqlite3_bind_parameter_count(stmt._sqlite_stmt); } internal override string Bind_ParamName(SqliteStatement stmt, int index) { return ToString(UnsafeNativeMethods.sqlite3_bind_parameter_name(stmt._sqlite_stmt, index)); } internal override int Bind_ParamIndex(SqliteStatement stmt, string paramName) { return UnsafeNativeMethods.sqlite3_bind_parameter_index(stmt._sqlite_stmt, ToUTF8(paramName)); } internal override int ColumnCount(SqliteStatement stmt) { return UnsafeNativeMethods.sqlite3_column_count(stmt._sqlite_stmt); } internal override string ColumnName(SqliteStatement stmt, int index) { return ToString(UnsafeNativeMethods.sqlite3_column_name(stmt._sqlite_stmt, index)); } internal override TypeAffinity ColumnAffinity(SqliteStatement stmt, int index) { return UnsafeNativeMethods.sqlite3_column_type(stmt._sqlite_stmt, index); } internal override string ColumnType(SqliteStatement stmt, int index, out TypeAffinity nAffinity) { IntPtr p = UnsafeNativeMethods.sqlite3_column_decltype(stmt._sqlite_stmt, index); nAffinity = ColumnAffinity(stmt, index); if (p != IntPtr.Zero) return base.ToString(p); else { string[] ar = stmt.TypeDefinitions; if (ar != null) { if (index < ar.Length) return ar[index]; } switch (nAffinity) { case TypeAffinity.Int64: return "BIGINT"; case TypeAffinity.Double: return "DOUBLE"; case TypeAffinity.Blob: return "BLOB"; default: return "TEXT"; } } } internal override int ColumnIndex(SqliteStatement stmt, string columnName) { int x = ColumnCount(stmt); for (int n = 0; n < x; n++) { if (String.Compare(columnName, ColumnName(stmt, n), true, CultureInfo.InvariantCulture) == 0) return n; } return -1; } internal override string ColumnOriginalName(SqliteStatement stmt, int index) { return ToString(UnsafeNativeMethods.sqlite3_column_origin_name(stmt._sqlite_stmt, index)); } internal override string ColumnDatabaseName(SqliteStatement stmt, int index) { return ToString(UnsafeNativeMethods.sqlite3_column_database_name(stmt._sqlite_stmt, index)); } internal override string ColumnTableName(SqliteStatement stmt, int index) { return ToString(UnsafeNativeMethods.sqlite3_column_table_name(stmt._sqlite_stmt, index)); } internal override void ColumnMetaData(string dataBase, string table, string column, out string dataType, out string collateSequence, out bool notNull, out bool primaryKey, out bool autoIncrement) { IntPtr dataTypePtr; IntPtr collSeqPtr; int nnotNull; int nprimaryKey; int nautoInc; int n; n = UnsafeNativeMethods.sqlite3_table_column_metadata(_sql, ToUTF8(dataBase), ToUTF8(table), ToUTF8(column), out dataTypePtr, out collSeqPtr, out nnotNull, out nprimaryKey, out nautoInc); if (n > 0) throw new SqliteException(n, SqliteLastError()); dataType = base.ToString(dataTypePtr); collateSequence = base.ToString(collSeqPtr); notNull = (nnotNull == 1); primaryKey = (nprimaryKey == 1); autoIncrement = (nautoInc == 1); } internal override double GetDouble(SqliteStatement stmt, int index) { return UnsafeNativeMethods.sqlite3_column_double(stmt._sqlite_stmt, index); } internal override int GetInt32(SqliteStatement stmt, int index) { return UnsafeNativeMethods.sqlite3_column_int(stmt._sqlite_stmt, index); } internal override long GetInt64(SqliteStatement stmt, int index) { return UnsafeNativeMethods.sqlite3_column_int64(stmt._sqlite_stmt, index); } internal override string GetText(SqliteStatement stmt, int index) { return ToString (UnsafeNativeMethods.sqlite3_column_text(stmt._sqlite_stmt, index)); } internal override DateTime GetDateTime(SqliteStatement stmt, int index) { return ToDateTime(GetText (stmt, index)); } internal override long GetBytes(SqliteStatement stmt, int index, int nDataOffset, byte[] bDest, int nStart, int nLength) { IntPtr ptr; int nlen; int nCopied = nLength; nlen = UnsafeNativeMethods.sqlite3_column_bytes(stmt._sqlite_stmt, index); ptr = UnsafeNativeMethods.sqlite3_column_blob(stmt._sqlite_stmt, index); if (bDest == null) return nlen; if (nCopied + nStart > bDest.Length) nCopied = bDest.Length - nStart; if (nCopied + nDataOffset > nlen) nCopied = nlen - nDataOffset; unsafe { if (nCopied > 0) Marshal.Copy((IntPtr)((byte*)ptr + nDataOffset), bDest, nStart, nCopied); else nCopied = 0; } return nCopied; } internal override long GetChars(SqliteStatement stmt, int index, int nDataOffset, char[] bDest, int nStart, int nLength) { int nlen; int nCopied = nLength; string str = GetText(stmt, index); nlen = str.Length; if (bDest == null) return nlen; if (nCopied + nStart > bDest.Length) nCopied = bDest.Length - nStart; if (nCopied + nDataOffset > nlen) nCopied = nlen - nDataOffset; if (nCopied > 0) str.CopyTo(nDataOffset, bDest, nStart, nCopied); else nCopied = 0; return nCopied; } internal override bool IsNull(SqliteStatement stmt, int index) { return (ColumnAffinity(stmt, index) == TypeAffinity.Null); } internal override int AggregateCount(IntPtr context) { return UnsafeNativeMethods.sqlite3_aggregate_count(context); } internal override void CreateFunction(string strFunction, int nArgs, SqliteCallback func, SqliteCallback funcstep, SqliteFinalCallback funcfinal) { int n = UnsafeNativeMethods.sqlite3_create_function(_sql, ToUTF8(strFunction), nArgs, 1, IntPtr.Zero, func, funcstep, funcfinal); if (n > 0) throw new SqliteException(n, SqliteLastError()); } internal override void CreateCollation(string strCollation, SqliteCollation func) { int n = UnsafeNativeMethods.sqlite3_create_collation(_sql, ToUTF8(strCollation), 1, IntPtr.Zero, func); if (n > 0) throw new SqliteException(n, SqliteLastError()); } internal override long GetParamValueBytes(IntPtr p, int nDataOffset, byte[] bDest, int nStart, int nLength) { IntPtr ptr; int nlen; int nCopied = nLength; nlen = UnsafeNativeMethods.sqlite3_value_bytes(p); ptr = UnsafeNativeMethods.sqlite3_value_blob(p); if (bDest == null) return nlen; if (nCopied + nStart > bDest.Length) nCopied = bDest.Length - nStart; if (nCopied + nDataOffset > nlen) nCopied = nlen - nDataOffset; unsafe { if (nCopied > 0) Marshal.Copy((IntPtr)((byte*)ptr + nDataOffset), bDest, nStart, nCopied); else nCopied = 0; } return nCopied; } internal override double GetParamValueDouble(IntPtr ptr) { return UnsafeNativeMethods.sqlite3_value_double(ptr); } internal override int GetParamValueInt32(IntPtr ptr) { return UnsafeNativeMethods.sqlite3_value_int(ptr); } internal override long GetParamValueInt64(IntPtr ptr) { return UnsafeNativeMethods.sqlite3_value_int64(ptr); } internal override string GetParamValueText(IntPtr ptr) { return ToString(UnsafeNativeMethods.sqlite3_value_text(ptr)); } internal override TypeAffinity GetParamValueType(IntPtr ptr) { return UnsafeNativeMethods.sqlite3_value_type(ptr); } internal override void ReturnBlob(IntPtr context, byte[] value) { UnsafeNativeMethods.sqlite3_result_blob(context, value, value.Length, (IntPtr)(-1)); } internal override void ReturnDouble(IntPtr context, double value) { UnsafeNativeMethods.sqlite3_result_double(context, value); } internal override void ReturnError(IntPtr context, string value) { UnsafeNativeMethods.sqlite3_result_error(context, ToUTF8(value), value.Length); } internal override void ReturnInt32(IntPtr context, int value) { UnsafeNativeMethods.sqlite3_result_int(context, value); } internal override void ReturnInt64(IntPtr context, long value) { UnsafeNativeMethods.sqlite3_result_int64(context, value); } internal override void ReturnNull(IntPtr context) { UnsafeNativeMethods.sqlite3_result_null(context); } internal override void ReturnText(IntPtr context, string value) { byte[] b = ToUTF8(value); UnsafeNativeMethods.sqlite3_result_text(context, ToUTF8(value), b.Length - 1, (IntPtr)(-1)); } internal override IntPtr AggregateContext(IntPtr context) { return UnsafeNativeMethods.sqlite3_aggregate_context(context, 1); } internal override void SetUpdateHook(SqliteUpdateCallback func) { UnsafeNativeMethods.sqlite3_update_hook(_sql, func); } internal override void SetCommitHook(SqliteCommitCallback func) { UnsafeNativeMethods.sqlite3_commit_hook(_sql, func); } internal override void SetRollbackHook(SqliteRollbackCallback func) { UnsafeNativeMethods.sqlite3_rollback_hook(_sql, func); } /// /// Helper function to retrieve a column of data from an active statement. /// /// The statement being step()'d through /// The column index to retrieve /// The type of data contained in the column. If Uninitialized, this function will retrieve the datatype information. /// Returns the data in the column internal override object GetValue(SqliteStatement stmt, int index, SqliteType typ) { if (typ.Affinity == 0) typ = SqliteConvert.ColumnToType(stmt, index); if (IsNull(stmt, index)) return DBNull.Value; Type t = SqliteConvert.SqliteTypeToType(typ); switch (TypeToAffinity(t)) { case TypeAffinity.Blob: if (typ.Type == DbType.Guid && typ.Affinity == TypeAffinity.Text) return new Guid(GetText(stmt, index)); int n = (int)GetBytes(stmt, index, 0, null, 0, 0); byte[] b = new byte[n]; GetBytes(stmt, index, 0, b, 0, n); if (typ.Type == DbType.Guid && n == 16) return new Guid(b); return b; case TypeAffinity.DateTime: return GetDateTime(stmt, index); case TypeAffinity.Double: return Convert.ChangeType(GetDouble(stmt, index), t, null); case TypeAffinity.Int64: return Convert.ChangeType(GetInt64(stmt, index), t, null); default: return GetText(stmt, index); } } internal override long GetLastInsertRowId () { return UnsafeNativeMethods.sqlite3_last_insert_rowid (_sql); } } } #endif hyena-0.5/Mono.Data.Sqlite/Mono.Data.Sqlite/SQLiteException.cs0000644000175000001440000002017211377104476024222 0ustar00gabeusers00000000000000// // Mono.Data.Sqlite.SQLiteException.cs // // Author(s): // Robert Simpson (robert@blackcastlesoft.com) // // Adapted and modified for the Mono Project by // Marek Habersack (grendello@gmail.com) // // // Copyright (C) 2006 Novell, Inc (http://www.novell.com) // Copyright (C) 2007 Marek Habersack // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // /******************************************************** * ADO.NET 2.0 Data Provider for Sqlite Version 3.X * Written by Robert Simpson (robert@blackcastlesoft.com) * * Released to the public domain, use at your own risk! ********************************************************/ #if NET_2_0 namespace Mono.Data.Sqlite { using System; using System.Collections.Generic; using System.Text; using System.Data.Common; #if !PLATFORM_COMPACTFRAMEWORK using System.Runtime.Serialization; #endif /// /// Sqlite exception class. /// #if !PLATFORM_COMPACTFRAMEWORK [Serializable] public class SqliteException : DbException #else public class SqliteException : Exception #endif { private SqliteErrorCode _errorCode; #if !PLATFORM_COMPACTFRAMEWORK private SqliteException(SerializationInfo info, StreamingContext context) : base(info, context) { } #endif /// /// Public constructor for generating a Sqlite error given the base error code /// /// The Sqlite error code to report /// Extra text to go along with the error message text public SqliteException(int errorCode, string extendedInformation) : base(GetStockErrorMessage(errorCode, extendedInformation)) { _errorCode = (SqliteErrorCode)errorCode; } /// /// Various public constructors that just pass along to the base Exception /// /// Passed verbatim to Exception public SqliteException(string message) : base(message) { } /// /// Various public constructors that just pass along to the base Exception /// public SqliteException() { } /// /// Various public constructors that just pass along to the base Exception /// Passed to Exception /// Passed to Exception /// public SqliteException(string message, Exception innerException) : base(message, innerException) { } /// /// Retrieves the underlying Sqlite error code for this exception /// #if !PLATFORM_COMPACTFRAMEWORK public new SqliteErrorCode ErrorCode #else public SqliteErrorCode ErrorCode #endif { get { return _errorCode; } } /// /// Initializes the exception class with the Sqlite error code. /// /// The Sqlite error code /// A detailed error message /// An error message string private static string GetStockErrorMessage(int errorCode, string errorMessage) { if (errorMessage == null) errorMessage = ""; if (errorMessage.Length > 0) errorMessage = "\r\n" + errorMessage; if (errorCode < 0 || errorCode >= _errorMessages.Length) errorCode = 1; return _errorMessages[errorCode] + errorMessage; } private static string[] _errorMessages = { "Sqlite OK", "Sqlite error", "An internal logic error in Sqlite", "Access permission denied", "Callback routine requested an abort", "The database file is locked", "A table in the database is locked", "malloc() failed", "Attempt to write a read-only database", "Operation terminated by sqlite3_interrupt()", "Some kind of disk I/O error occurred", "The database disk image is malformed", "Table or record not found", "Insertion failed because the database is full", "Unable to open the database file", "Database lock protocol error", "Database is empty", "The database schema changed", "Too much data for one row of a table", "Abort due to constraint violation", "Data type mismatch", "Library used incorrectly", "Uses OS features not supported on host", "Authorization denied", "Auxiliary database format error", "2nd parameter to sqlite3_bind() out of range", "File opened that is not a database file", }; } /// /// Sqlite error codes /// public enum SqliteErrorCode { /// /// Success /// Ok = 0, /// /// SQL error or missing database /// Error, /// /// Internal logic error in Sqlite /// Internal, /// /// Access permission denied /// Perm, /// /// Callback routine requested an abort /// Abort, /// /// The database file is locked /// Busy, /// /// A table in the database is locked /// Locked, /// /// malloc() failed /// NoMem, /// /// Attempt to write a read-only database /// ReadOnly, /// /// Operation terminated by sqlite3_interrupt() /// Interrupt, /// /// Some kind of disk I/O error occurred /// IOErr, /// /// The database disk image is malformed /// Corrupt, /// /// Table or record not found /// NotFound, /// /// Insertion failed because database is full /// Full, /// /// Unable to open the database file /// CantOpen, /// /// Database lock protocol error /// Protocol, /// /// Database is empty /// Empty, /// /// The database schema changed /// Schema, /// /// Too much data for one row of a table /// TooBig, /// /// Abort due to constraint violation /// Constraint, /// /// Data type mismatch /// Mismatch, /// /// Library used incorrectly /// Misuse, /// /// Uses OS features not supported on host /// NOLFS, /// /// Authorization denied /// Auth, /// /// Auxiliary database format error /// Format, /// /// 2nd parameter to sqlite3_bind out of range /// Range, /// /// File opened that is not a database file /// NotADatabase, /// /// sqlite3_step() has another row ready /// Row = 100, /// /// sqlite3_step() has finished executing /// Done = 101, } } #endif hyena-0.5/Mono.Data.Sqlite/Mono.Data.Sqlite/SQLiteParameter.cs0000644000175000001440000003771611377104476024220 0ustar00gabeusers00000000000000// // Mono.Data.Sqlite.SQLiteParameter.cs // // Author(s): // Robert Simpson (robert@blackcastlesoft.com) // // Adapted and modified for the Mono Project by // Marek Habersack (grendello@gmail.com) // // // Copyright (C) 2006 Novell, Inc (http://www.novell.com) // Copyright (C) 2007 Marek Habersack // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // /******************************************************** * ADO.NET 2.0 Data Provider for Sqlite Version 3.X * Written by Robert Simpson (robert@blackcastlesoft.com) * * Released to the public domain, use at your own risk! ********************************************************/ #if NET_2_0 namespace Mono.Data.Sqlite { using System; using System.Data; using System.Data.Common; using System.ComponentModel; /// /// Sqlite implementation of DbParameter. /// public sealed class SqliteParameter : DbParameter, ICloneable { /// /// The data type of the parameter /// internal int _dbType; /// /// The version information for mapping the parameter /// private DataRowVersion _rowVersion; /// /// The value of the data in the parameter /// private Object _objValue; /// /// The source column for the parameter /// private string _sourceColumn; /// /// The column name /// private string _parameterName; /// /// The data size, unused by Sqlite /// private int _dataSize; private bool _nullable; private bool _nullMapping; /// /// Default constructor /// public SqliteParameter() : this(null, (DbType)(-1), 0, null, DataRowVersion.Current) { } /// /// Constructs a named parameter given the specified parameter name /// /// The parameter name public SqliteParameter(string parameterName) : this(parameterName, (DbType)(-1), 0, null, DataRowVersion.Current) { } /// /// Constructs a named parameter given the specified parameter name and initial value /// /// The parameter name /// The initial value of the parameter public SqliteParameter(string parameterName, object value) : this(parameterName, (DbType)(-1), 0, null, DataRowVersion.Current) { Value = value; } /// /// Constructs a named parameter of the specified type /// /// The parameter name /// The datatype of the parameter public SqliteParameter(string parameterName, DbType dbType) : this(parameterName, dbType, 0, null, DataRowVersion.Current) { } /// /// Constructs a named parameter of the specified type and source column reference /// /// The parameter name /// The data type /// The source column public SqliteParameter(string parameterName, DbType dbType, string sourceColumn) : this(parameterName, dbType, 0, sourceColumn, DataRowVersion.Current) { } /// /// Constructs a named parameter of the specified type, source column and row version /// /// The parameter name /// The data type /// The source column /// The row version information public SqliteParameter(string parameterName, DbType dbType, string sourceColumn, DataRowVersion rowVersion) : this(parameterName, dbType, 0, sourceColumn, rowVersion) { } /// /// Constructs an unnamed parameter of the specified data type /// /// The datatype of the parameter public SqliteParameter(DbType dbType) : this(null, dbType, 0, null, DataRowVersion.Current) { } /// /// Constructs an unnamed parameter of the specified data type and sets the initial value /// /// The datatype of the parameter /// The initial value of the parameter public SqliteParameter(DbType dbType, object value) : this(null, dbType, 0, null, DataRowVersion.Current) { Value = value; } /// /// Constructs an unnamed parameter of the specified data type and source column /// /// The datatype of the parameter /// The source column public SqliteParameter(DbType dbType, string sourceColumn) : this(null, dbType, 0, sourceColumn, DataRowVersion.Current) { } /// /// Constructs an unnamed parameter of the specified data type, source column and row version /// /// The data type /// The source column /// The row version information public SqliteParameter(DbType dbType, string sourceColumn, DataRowVersion rowVersion) : this(null, dbType, 0, sourceColumn, rowVersion) { } /// /// Constructs a named parameter of the specified type and size /// /// The parameter name /// The data type /// The size of the parameter public SqliteParameter(string parameterName, DbType parameterType, int parameterSize) : this(parameterName, parameterType, parameterSize, null, DataRowVersion.Current) { } /// /// Constructs a named parameter of the specified type, size and source column /// /// The name of the parameter /// The data type /// The size of the parameter /// The source column public SqliteParameter(string parameterName, DbType parameterType, int parameterSize, string sourceColumn) : this(parameterName, parameterType, parameterSize, sourceColumn, DataRowVersion.Current) { } /// /// Constructs a named parameter of the specified type, size, source column and row version /// /// The name of the parameter /// The data type /// The size of the parameter /// The source column /// The row version information public SqliteParameter(string parameterName, DbType parameterType, int parameterSize, string sourceColumn, DataRowVersion rowVersion) { _parameterName = parameterName; _dbType = (int)parameterType; _sourceColumn = sourceColumn; _rowVersion = rowVersion; _objValue = null; _dataSize = parameterSize; _nullMapping = false; _nullable = true; } private SqliteParameter(SqliteParameter source) : this(source.ParameterName, (DbType)source._dbType, 0, source.Direction, source.IsNullable, 0, 0, source.SourceColumn, source.SourceVersion, source.Value) { _nullMapping = source._nullMapping; } /// /// Constructs a named parameter of the specified type, size, source column and row version /// /// The name of the parameter /// The data type /// The size of the parameter /// Only input parameters are supported in Sqlite /// Ignored /// Ignored /// Ignored /// The source column /// The row version information /// The initial value to assign the parameter #if !PLATFORM_COMPACTFRAMEWORK [EditorBrowsable(EditorBrowsableState.Advanced)] #endif public SqliteParameter(string parameterName, DbType parameterType, int parameterSize, ParameterDirection direction, bool isNullable, byte precision, byte scale, string sourceColumn, DataRowVersion rowVersion, object value) : this(parameterName, parameterType, parameterSize, sourceColumn, rowVersion) { Direction = direction; IsNullable = isNullable; Value = value; } /// /// Constructs a named parameter, yet another flavor /// /// The name of the parameter /// The data type /// The size of the parameter /// Only input parameters are supported in Sqlite /// Ignored /// Ignored /// The source column /// The row version information /// Whether or not this parameter is for comparing NULL's /// The intial value to assign the parameter #if !PLATFORM_COMPACTFRAMEWORK [EditorBrowsable(EditorBrowsableState.Advanced)] #endif public SqliteParameter(string parameterName, DbType parameterType, int parameterSize, ParameterDirection direction, byte precision, byte scale, string sourceColumn, DataRowVersion rowVersion, bool sourceColumnNullMapping, object value) : this(parameterName, parameterType, parameterSize, sourceColumn, rowVersion) { Direction = direction; SourceColumnNullMapping = sourceColumnNullMapping; Value = value; } /// /// Constructs an unnamed parameter of the specified type and size /// /// The data type /// The size of the parameter public SqliteParameter(DbType parameterType, int parameterSize) : this(null, parameterType, parameterSize, null, DataRowVersion.Current) { } /// /// Constructs an unnamed parameter of the specified type, size, and source column /// /// The data type /// The size of the parameter /// The source column public SqliteParameter(DbType parameterType, int parameterSize, string sourceColumn) : this(null, parameterType, parameterSize, sourceColumn, DataRowVersion.Current) { } /// /// Constructs an unnamed parameter of the specified type, size, source column and row version /// /// The data type /// The size of the parameter /// The source column /// The row version information public SqliteParameter(DbType parameterType, int parameterSize, string sourceColumn, DataRowVersion rowVersion) : this(null, parameterType, parameterSize, sourceColumn, rowVersion) { } /// /// Whether or not the parameter can contain a null value /// public override bool IsNullable { get { return _nullable; } set { _nullable = value; } } /// /// Returns the datatype of the parameter /// #if !PLATFORM_COMPACTFRAMEWORK [DbProviderSpecificTypeProperty(true)] [RefreshProperties(RefreshProperties.All)] #endif public override DbType DbType { get { if (_dbType == -1) return DbType.String; // Unassigned default value is String return (DbType)_dbType; } set { _dbType = (int)value; } } /// /// Supports only input parameters /// public override ParameterDirection Direction { get { return ParameterDirection.Input; } set { if (value != ParameterDirection.Input) throw new NotSupportedException(); } } /// /// Returns the parameter name /// public override string ParameterName { get { return _parameterName; } set { _parameterName = value; } } /// /// Not implemented /// public override void ResetDbType() { } /// /// Returns the size of the parameter /// #if !PLATFORM_COMPACTFRAMEWORK [DefaultValue((int)0)] #endif public override int Size { get { return _dataSize; } set { _dataSize = value; } } /// /// Gets/sets the source column /// public override string SourceColumn { get { return _sourceColumn; } set { _sourceColumn = value; } } /// /// Used by DbCommandBuilder to determine the mapping for nullable fields /// public override bool SourceColumnNullMapping { get { return _nullMapping; } set { _nullMapping = value; } } /// /// Gets and sets the row version /// public override DataRowVersion SourceVersion { get { return _rowVersion; } set { _rowVersion = value; } } /// /// Gets and sets the parameter value. If no datatype was specified, the datatype will assume the type from the value given. /// #if !PLATFORM_COMPACTFRAMEWORK [TypeConverter(typeof(StringConverter)), RefreshProperties(RefreshProperties.All)] #endif public override object Value { get { return _objValue; } set { _objValue = value; if (_dbType == -1 && _objValue != null && _objValue != DBNull.Value) // If the DbType has never been assigned, try to glean one from the value's datatype _dbType = (int)SqliteConvert.TypeToDbType(_objValue.GetType()); } } /// /// Clones a parameter /// /// A new, unassociated SqliteParameter public object Clone() { SqliteParameter newparam = new SqliteParameter(this); return newparam; } } } #endif hyena-0.5/Mono.Data.Sqlite/Mono.Data.Sqlite/SQLiteBase.cs0000644000175000001440000002334111377104476023137 0ustar00gabeusers00000000000000// // Mono.Data.Sqlite.SQLiteBase.cs // // Author(s): // Robert Simpson (robert@blackcastlesoft.com) // // Adapted and modified for the Mono Project by // Marek Habersack (grendello@gmail.com) // // // Copyright (C) 2006 Novell, Inc (http://www.novell.com) // Copyright (C) 2007 Marek Habersack // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // /******************************************************** * ADO.NET 2.0 Data Provider for SQLite Version 3.X * Written by Robert Simpson (robert@blackcastlesoft.com) * * Released to the public domain, use at your own risk! ********************************************************/ #if NET_2_0 namespace Mono.Data.Sqlite { using System; using System.Data; using System.Runtime.InteropServices; using System.Collections.Generic; /// /// This internal class provides the foundation of Sqlite support. It defines all the abstract members needed to implement /// a Sqlite data provider, and inherits from SqliteConvert which allows for simple translations of string to and from Sqlite. /// internal abstract class SqliteBase : SqliteConvert, IDisposable { internal SqliteBase(SqliteDateFormats fmt) : base(fmt) {} /// /// Returns a string representing the active version of Sqlite /// internal abstract string Version { get; } /// /// Returns the number of changes the last executing insert/update caused. /// internal abstract int Changes { get; } /// /// Opens a database. /// /// /// Implementers should call SqliteFunction.BindFunctions() and save the array after opening a connection /// to bind all attributed user-defined functions and collating sequences to the new connection. /// /// The filename of the database to open. Sqlite automatically creates it if it doesn't exist. internal abstract void Open(string strFilename); /// /// Closes the currently-open database. /// /// /// After the database has been closed implemeters should call SqliteFunction.UnbindFunctions() to deallocate all interop allocated /// memory associated with the user-defined functions and collating sequences tied to the closed connection. /// internal abstract void Close(); /// /// Sets the busy timeout on the connection. SqliteCommand will call this before executing any command. /// /// The number of milliseconds to wait before returning SQLITE_BUSY internal abstract void SetTimeout(int nTimeoutMS); /// /// Returns the text of the last error issued by Sqlite /// /// internal abstract string SqliteLastError(); /// /// Prepares a SQL statement for execution. /// /// The SQL command text to prepare /// The previous statement in a multi-statement command, or null if no previous statement exists /// The remainder of the statement that was not processed. Each call to prepare parses the /// SQL up to to either the end of the text or to the first semi-colon delimiter. The remaining text is returned /// here for a subsequent call to Prepare() until all the text has been processed. /// Returns an initialized SqliteStatement. internal abstract SqliteStatement Prepare(string strSql, SqliteStatement previous, out string strRemain); /// /// Steps through a prepared statement. /// /// The SqliteStatement to step through /// True if a row was returned, False if not. internal abstract bool Step(SqliteStatement stmt); /// /// Finalizes a prepared statement. /// /// The statement to finalize internal abstract void FinalizeStatement(SqliteStatement stmt); /// /// Resets a prepared statement so it can be executed again. If the error returned is SQLITE_SCHEMA, /// transparently attempt to rebuild the SQL statement and throw an error if that was not possible. /// /// The statement to reset /// Returns -1 if the schema changed while resetting, 0 if the reset was sucessful or 6 (SQLITE_LOCKED) if the reset failed due to a lock internal abstract int Reset(SqliteStatement stmt); internal abstract void Cancel(); internal abstract void Bind_Double(SqliteStatement stmt, int index, double value); internal abstract void Bind_Int32(SqliteStatement stmt, int index, Int32 value); internal abstract void Bind_Int64(SqliteStatement stmt, int index, Int64 value); internal abstract void Bind_Text(SqliteStatement stmt, int index, string value); internal abstract void Bind_Blob(SqliteStatement stmt, int index, byte[] blobData); internal abstract void Bind_DateTime(SqliteStatement stmt, int index, DateTime dt); internal abstract void Bind_Null(SqliteStatement stmt, int index); internal abstract int Bind_ParamCount(SqliteStatement stmt); internal abstract string Bind_ParamName(SqliteStatement stmt, int index); internal abstract int Bind_ParamIndex(SqliteStatement stmt, string paramName); internal abstract int ColumnCount(SqliteStatement stmt); internal abstract string ColumnName(SqliteStatement stmt, int index); internal abstract TypeAffinity ColumnAffinity(SqliteStatement stmt, int index); internal abstract string ColumnType(SqliteStatement stmt, int index, out TypeAffinity nAffinity); internal abstract int ColumnIndex(SqliteStatement stmt, string columnName); internal abstract string ColumnOriginalName(SqliteStatement stmt, int index); internal abstract string ColumnDatabaseName(SqliteStatement stmt, int index); internal abstract string ColumnTableName(SqliteStatement stmt, int index); internal abstract void ColumnMetaData(string dataBase, string table, string column, out string dataType, out string collateSequence, out bool notNull, out bool primaryKey, out bool autoIncrement); internal abstract double GetDouble(SqliteStatement stmt, int index); internal abstract Int32 GetInt32(SqliteStatement stmt, int index); internal abstract Int64 GetInt64(SqliteStatement stmt, int index); internal abstract string GetText(SqliteStatement stmt, int index); internal abstract long GetBytes(SqliteStatement stmt, int index, int nDataoffset, byte[] bDest, int nStart, int nLength); internal abstract long GetChars(SqliteStatement stmt, int index, int nDataoffset, char[] bDest, int nStart, int nLength); internal abstract DateTime GetDateTime(SqliteStatement stmt, int index); internal abstract bool IsNull(SqliteStatement stmt, int index); internal abstract void CreateCollation(string strCollation, SqliteCollation func); internal abstract void CreateFunction(string strFunction, int nArgs, SqliteCallback func, SqliteCallback funcstep, SqliteFinalCallback funcfinal); internal abstract int AggregateCount(IntPtr context); internal abstract IntPtr AggregateContext(IntPtr context); internal abstract long GetParamValueBytes(IntPtr ptr, int nDataOffset, byte[] bDest, int nStart, int nLength); internal abstract double GetParamValueDouble(IntPtr ptr); internal abstract int GetParamValueInt32(IntPtr ptr); internal abstract Int64 GetParamValueInt64(IntPtr ptr); internal abstract string GetParamValueText(IntPtr ptr); internal abstract TypeAffinity GetParamValueType(IntPtr ptr); internal abstract void ReturnBlob(IntPtr context, byte[] value); internal abstract void ReturnDouble(IntPtr context, double value); internal abstract void ReturnError(IntPtr context, string value); internal abstract void ReturnInt32(IntPtr context, Int32 value); internal abstract void ReturnInt64(IntPtr context, Int64 value); internal abstract void ReturnNull(IntPtr context); internal abstract void ReturnText(IntPtr context, string value); internal abstract void SetUpdateHook(SqliteUpdateCallback func); internal abstract void SetCommitHook(SqliteCommitCallback func); internal abstract void SetRollbackHook(SqliteRollbackCallback func); internal abstract long GetLastInsertRowId (); internal abstract object GetValue(SqliteStatement stmt, int index, SqliteType typ); protected virtual void Dispose(bool bDisposing) { } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } } } #endif hyena-0.5/Mono.Data.Sqlite/Mono.Data.Sqlite/SQLiteCommandBuilder.cs0000644000175000001440000002731311377104476025155 0ustar00gabeusers00000000000000// // Mono.Data.Sqlite.SQLiteCommandBuilder.cs // // Author(s): // Robert Simpson (robert@blackcastlesoft.com) // // Adapted and modified for the Mono Project by // Marek Habersack (grendello@gmail.com) // // // Copyright (C) 2006 Novell, Inc (http://www.novell.com) // Copyright (C) 2007 Marek Habersack // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // /******************************************************** * ADO.NET 2.0 Data Provider for Sqlite Version 3.X * Written by Robert Simpson (robert@blackcastlesoft.com) * * Released to the public domain, use at your own risk! ********************************************************/ #if NET_2_0 namespace Mono.Data.Sqlite { using System; using System.Data; using System.Data.Common; using System.Globalization; using System.ComponentModel; /// /// Sqlite implementation of DbCommandBuilder. /// public sealed class SqliteCommandBuilder : DbCommandBuilder { private EventHandler _handler; /// /// Default constructor /// public SqliteCommandBuilder() : this(null) { } /// /// Initializes the command builder and associates it with the specified data adapter. /// /// public SqliteCommandBuilder(SqliteDataAdapter adp) { QuotePrefix = "["; QuoteSuffix = "]"; DataAdapter = adp; } /// /// Minimal amount of parameter processing. Primarily sets the DbType for the parameter equal to the provider type in the schema /// /// The parameter to use in applying custom behaviors to a row /// The row to apply the parameter to /// The type of statement /// Whether the application of the parameter is part of a WHERE clause protected override void ApplyParameterInfo(DbParameter parameter, DataRow row, StatementType statementType, bool whereClause) { SqliteParameter param = (SqliteParameter)parameter; param.DbType = (DbType)row[SchemaTableColumn.ProviderType]; } /// /// Returns a valid named parameter /// /// The name of the parameter /// Error protected override string GetParameterName(string parameterName) { return String.Format(CultureInfo.InvariantCulture, "@{0}", parameterName); } /// /// Returns a named parameter for the given ordinal /// /// The i of the parameter /// Error protected override string GetParameterName(int parameterOrdinal) { return String.Format(CultureInfo.InvariantCulture, "@param{0}", parameterOrdinal); } /// /// Returns a placeholder character for the specified parameter i. /// /// The index of the parameter to provide a placeholder for /// Returns a named parameter protected override string GetParameterPlaceholder(int parameterOrdinal) { return GetParameterName(parameterOrdinal); } /// /// Sets the handler for receiving row updating events. Used by the DbCommandBuilder to autogenerate SQL /// statements that may not have previously been generated. /// /// A data adapter to receive events on. protected override void SetRowUpdatingHandler(DbDataAdapter adapter) { SqliteDataAdapter adp = (SqliteDataAdapter)adapter; _handler = new EventHandler(RowUpdatingEventHandler); adp.RowUpdating += _handler; } private void RowUpdatingEventHandler(object sender, RowUpdatingEventArgs e) { base.RowUpdatingHandler(e); } /// /// Gets/sets the DataAdapter for this CommandBuilder /// public new SqliteDataAdapter DataAdapter { get { return (SqliteDataAdapter)base.DataAdapter; } set { base.DataAdapter = value; } } /// /// Returns the automatically-generated Sqlite command to delete rows from the database /// /// public new SqliteCommand GetDeleteCommand() { return (SqliteCommand)base.GetDeleteCommand(); } /// /// Returns the automatically-generated Sqlite command to delete rows from the database /// /// /// public new SqliteCommand GetDeleteCommand(bool useColumnsForParameterNames) { return (SqliteCommand)base.GetDeleteCommand(useColumnsForParameterNames); } /// /// Returns the automatically-generated Sqlite command to update rows in the database /// /// public new SqliteCommand GetUpdateCommand() { return (SqliteCommand)base.GetUpdateCommand(); } /// /// Returns the automatically-generated Sqlite command to update rows in the database /// /// /// public new SqliteCommand GetUpdateCommand(bool useColumnsForParameterNames) { return (SqliteCommand)base.GetUpdateCommand(useColumnsForParameterNames); } /// /// Returns the automatically-generated Sqlite command to insert rows into the database /// /// public new SqliteCommand GetInsertCommand() { return (SqliteCommand)base.GetInsertCommand(); } /// /// Returns the automatically-generated Sqlite command to insert rows into the database /// /// /// public new SqliteCommand GetInsertCommand(bool useColumnsForParameterNames) { return (SqliteCommand)base.GetInsertCommand(useColumnsForParameterNames); } /// /// Overridden to hide its property from the designer /// #if !PLATFORM_COMPACTFRAMEWORK [Browsable(false)] #endif public override CatalogLocation CatalogLocation { get { return base.CatalogLocation; } set { base.CatalogLocation = value; } } /// /// Overridden to hide its property from the designer /// #if !PLATFORM_COMPACTFRAMEWORK [Browsable(false)] #endif public override string CatalogSeparator { get { return base.CatalogSeparator; } set { base.CatalogSeparator = value; } } /// /// Overridden to hide its property from the designer /// #if !PLATFORM_COMPACTFRAMEWORK [Browsable(false)] #endif [DefaultValue("[")] public override string QuotePrefix { get { return base.QuotePrefix; } set { base.QuotePrefix = value; } } /// /// Overridden to hide its property from the designer /// #if !PLATFORM_COMPACTFRAMEWORK [Browsable(false)] #endif public override string QuoteSuffix { get { return base.QuoteSuffix; } set { base.QuoteSuffix = value; } } /// /// Places brackets around an identifier /// /// The identifier to quote /// The bracketed identifier public override string QuoteIdentifier(string unquotedIdentifier) { if (String.IsNullOrEmpty(QuotePrefix) || String.IsNullOrEmpty(QuoteSuffix) || String.IsNullOrEmpty(unquotedIdentifier)) return unquotedIdentifier; return QuotePrefix + unquotedIdentifier.Replace(QuoteSuffix, QuoteSuffix + QuoteSuffix) + QuoteSuffix; } /// /// Removes brackets around an identifier /// /// The quoted (bracketed) identifier /// The undecorated identifier public override string UnquoteIdentifier(string quotedIdentifier) { if (String.IsNullOrEmpty(QuotePrefix) || String.IsNullOrEmpty(QuoteSuffix) || String.IsNullOrEmpty(quotedIdentifier)) return quotedIdentifier; if (quotedIdentifier.StartsWith(QuotePrefix, StringComparison.InvariantCultureIgnoreCase) == false || quotedIdentifier.EndsWith(QuoteSuffix, StringComparison.InvariantCultureIgnoreCase) == false) return quotedIdentifier; return quotedIdentifier.Substring(QuotePrefix.Length, quotedIdentifier.Length - (QuotePrefix.Length + QuoteSuffix.Length)).Replace(QuoteSuffix + QuoteSuffix, QuoteSuffix); } /// /// Overridden to hide its property from the designer /// #if !PLATFORM_COMPACTFRAMEWORK [Browsable(false)] #endif public override string SchemaSeparator { get { return base.SchemaSeparator; } set { base.SchemaSeparator = value; } } /// /// Override helper, which can help the base command builder choose the right keys for the given query /// /// /// protected override DataTable GetSchemaTable(DbCommand sourceCommand) { using (IDataReader reader = sourceCommand.ExecuteReader(CommandBehavior.KeyInfo | CommandBehavior.SchemaOnly)) { DataTable schema = reader.GetSchemaTable(); // If the query contains a primary key, turn off the IsUnique property // for all the non-key columns if (HasSchemaPrimaryKey(schema)) ResetIsUniqueSchemaColumn(schema); // if table has no primary key we use unique columns as a fall back return schema; } } private bool HasSchemaPrimaryKey(DataTable schema) { DataColumn IsKeyColumn = schema.Columns[SchemaTableColumn.IsKey]; foreach (DataRow schemaRow in schema.Rows) { if ((bool)schemaRow[IsKeyColumn] == true) return true; } return false; } private void ResetIsUniqueSchemaColumn(DataTable schema) { DataColumn IsUniqueColumn = schema.Columns[SchemaTableColumn.IsUnique]; DataColumn IsKeyColumn = schema.Columns[SchemaTableColumn.IsKey]; foreach (DataRow schemaRow in schema.Rows) { if ((bool)schemaRow[IsKeyColumn] == false) schemaRow[IsUniqueColumn] = false; } schema.AcceptChanges(); } } } #endif hyena-0.5/configure0000755000175000001440000041743411453150777014535 0ustar00gabeusers00000000000000#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.63 for hyena 0.5. # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, # 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## --------------------- ## ## M4sh Initialization. ## ## --------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac fi # PATH needs CR # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo if (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. case $0 in *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 { (exit 1); exit 1; } fi # Work around bugs in pre-3.0 UWIN ksh. for as_var in ENV MAIL MAILPATH do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi # Name of the executable. as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # CDPATH. $as_unset CDPATH if test "x$CONFIG_SHELL" = x; then if (eval ":") 2>/dev/null; then as_have_required=yes else as_have_required=no fi if test $as_have_required = yes && (eval ": (as_func_return () { (exit \$1) } as_func_success () { as_func_return 0 } as_func_failure () { as_func_return 1 } as_func_ret_success () { return 0 } as_func_ret_failure () { return 1 } exitcode=0 if as_func_success; then : else exitcode=1 echo as_func_success failed. fi if as_func_failure; then exitcode=1 echo as_func_failure succeeded. fi if as_func_ret_success; then : else exitcode=1 echo as_func_ret_success failed. fi if as_func_ret_failure; then exitcode=1 echo as_func_ret_failure succeeded. fi if ( set x; as_func_ret_success y && test x = \"\$1\" ); then : else exitcode=1 echo positional parameters were not saved. fi test \$exitcode = 0) || { (exit 1); exit 1; } ( as_lineno_1=\$LINENO as_lineno_2=\$LINENO test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" && test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; } ") 2> /dev/null; then : else as_candidate_shells= as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. case $as_dir in /*) for as_base in sh bash ksh sh5; do as_candidate_shells="$as_candidate_shells $as_dir/$as_base" done;; esac done IFS=$as_save_IFS for as_shell in $as_candidate_shells $SHELL; do # Try only shells that exist, to save several forks. if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { ("$as_shell") 2> /dev/null <<\_ASEOF if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac fi : _ASEOF }; then CONFIG_SHELL=$as_shell as_have_required=yes if { "$as_shell" 2> /dev/null <<\_ASEOF if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac fi : (as_func_return () { (exit $1) } as_func_success () { as_func_return 0 } as_func_failure () { as_func_return 1 } as_func_ret_success () { return 0 } as_func_ret_failure () { return 1 } exitcode=0 if as_func_success; then : else exitcode=1 echo as_func_success failed. fi if as_func_failure; then exitcode=1 echo as_func_failure succeeded. fi if as_func_ret_success; then : else exitcode=1 echo as_func_ret_success failed. fi if as_func_ret_failure; then exitcode=1 echo as_func_ret_failure succeeded. fi if ( set x; as_func_ret_success y && test x = "$1" ); then : else exitcode=1 echo positional parameters were not saved. fi test $exitcode = 0) || { (exit 1); exit 1; } ( as_lineno_1=$LINENO as_lineno_2=$LINENO test "x$as_lineno_1" != "x$as_lineno_2" && test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; } _ASEOF }; then break fi fi done if test "x$CONFIG_SHELL" != x; then for as_var in BASH_ENV ENV do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var done export CONFIG_SHELL exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} fi if test $as_have_required = no; then echo This script requires a shell more modern than all the echo shells that I found on your system. Please install a echo modern shell, or manually run the script under such a echo shell if you do have one. { (exit 1); exit 1; } fi fi fi (eval "as_func_return () { (exit \$1) } as_func_success () { as_func_return 0 } as_func_failure () { as_func_return 1 } as_func_ret_success () { return 0 } as_func_ret_failure () { return 1 } exitcode=0 if as_func_success; then : else exitcode=1 echo as_func_success failed. fi if as_func_failure; then exitcode=1 echo as_func_failure succeeded. fi if as_func_ret_success; then : else exitcode=1 echo as_func_ret_success failed. fi if as_func_ret_failure; then exitcode=1 echo as_func_ret_failure succeeded. fi if ( set x; as_func_ret_success y && test x = \"\$1\" ); then : else exitcode=1 echo positional parameters were not saved. fi test \$exitcode = 0") || { echo No shell found that supports shell functions. echo Please tell bug-autoconf@gnu.org about your system, echo including any error possibly output before this message. echo This can help us improve future autoconf versions. echo Configuration will now proceed without shell functions. } as_lineno_1=$LINENO as_lineno_2=$LINENO test "x$as_lineno_1" != "x$as_lineno_2" && test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line after each line using $LINENO; the second 'sed' # does the real work. The second script uses 'N' to pair each # line-number line with the line containing $LINENO, and appends # trailing '-' during substitution so that $LINENO is not a special # case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # scripts with optimization help from Paolo Bonzini. Blame Lee # E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in -n*) case `echo 'x\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. *) ECHO_C='\c';; esac;; *) ECHO_N='-n';; esac if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p=: else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= SHELL=${CONFIG_SHELL-/bin/sh} # Identity of this package. PACKAGE_NAME='hyena' PACKAGE_TARNAME='hyena' PACKAGE_VERSION='0.5' PACKAGE_STRING='hyena 0.5' PACKAGE_BUGREPORT='' ac_subst_vars='LTLIBOBJS LIBOBJS NUNIT_LIBS NUNIT_CFLAGS ENABLE_TESTS_FALSE ENABLE_TESTS_TRUE HYENA_PKG_CONFIG_FALSE HYENA_PKG_CONFIG_TRUE GCONF_SCHEMAS_INSTALL_FALSE GCONF_SCHEMAS_INSTALL_TRUE ENABLE_ATK_FALSE ENABLE_ATK_TRUE GTKSHARP_A11Y_LIBS GTKSHARP_A11Y_CFLAGS GLIBSHARP_LIBS GLIBSHARP_CFLAGS GTKSHARP_LIBS GTKSHARP_CFLAGS MONO MCS MONO_MODULE_LIBS MONO_MODULE_CFLAGS ENABLE_WINDOWS_FALSE ENABLE_WINDOWS_TRUE ENABLE_RELEASE_FALSE ENABLE_RELEASE_TRUE ENABLE_DEBUG_FALSE ENABLE_DEBUG_TRUE expanded_datadir expanded_bindir expanded_libdir PKG_CONFIG ACLOCAL_AMFLAGS MAINT MAINTAINER_MODE_FALSE MAINTAINER_MODE_TRUE am__untar am__tar AMTAR am__leading_dot SET_MAKE AWK mkdir_p MKDIR_P INSTALL_STRIP_PROGRAM STRIP install_sh MAKEINFO AUTOHEADER AUTOMAKE AUTOCONF ACLOCAL VERSION PACKAGE CYGPATH_W am__isrc INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking enable_maintainer_mode enable_debug enable_release enable_windows enable_tests ' ac_precious_vars='build_alias host_alias target_alias PKG_CONFIG MONO_MODULE_CFLAGS MONO_MODULE_LIBS GTKSHARP_CFLAGS GTKSHARP_LIBS GLIBSHARP_CFLAGS GLIBSHARP_LIBS GTKSHARP_A11Y_CFLAGS GTKSHARP_A11Y_LIBS NUNIT_CFLAGS NUNIT_LIBS' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && { $as_echo "$as_me: error: invalid feature name: $ac_useropt" >&2 { (exit 1); exit 1; }; } ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && { $as_echo "$as_me: error: invalid feature name: $ac_useropt" >&2 { (exit 1); exit 1; }; } ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && { $as_echo "$as_me: error: invalid package name: $ac_useropt" >&2 { (exit 1); exit 1; }; } ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && { $as_echo "$as_me: error: invalid package name: $ac_useropt" >&2 { (exit 1); exit 1; }; } ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) { $as_echo "$as_me: error: unrecognized option: $ac_option Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; } ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && { $as_echo "$as_me: error: invalid variable name: $ac_envvar" >&2 { (exit 1); exit 1; }; } eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` { $as_echo "$as_me: error: missing argument to $ac_option" >&2 { (exit 1); exit 1; }; } fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) { $as_echo "$as_me: error: unrecognized options: $ac_unrecognized_opts" >&2 { (exit 1); exit 1; }; } ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac { $as_echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 { (exit 1); exit 1; }; } done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe $as_echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. If a cross compiler is detected then cross compile mode will be used." >&2 elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || { $as_echo "$as_me: error: working directory cannot be determined" >&2 { (exit 1); exit 1; }; } test "X$ac_ls_di" = "X$ac_pwd_ls_di" || { $as_echo "$as_me: error: pwd does not report name of working directory" >&2 { (exit 1); exit 1; }; } # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." { $as_echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 { (exit 1); exit 1; }; } fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || { $as_echo "$as_me: error: $ac_msg" >&2 { (exit 1); exit 1; }; } pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures hyena 0.5 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/hyena] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF Program names: --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of hyena 0.5:";; esac cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-maintainer-mode enable make rules and dependencies not useful (and sometimes confusing) to the casual installer --enable-debug Use 'DEBUG' Configuration default=YES --enable-release Use 'RELEASE' Configuration default=NO --enable-windows Use 'WINDOWS' Configuration default=NO --enable-tests Enable NUnit tests Some influential environment variables: PKG_CONFIG path to pkg-config utility MONO_MODULE_CFLAGS C compiler flags for MONO_MODULE, overriding pkg-config MONO_MODULE_LIBS linker flags for MONO_MODULE, overriding pkg-config GTKSHARP_CFLAGS C compiler flags for GTKSHARP, overriding pkg-config GTKSHARP_LIBS linker flags for GTKSHARP, overriding pkg-config GLIBSHARP_CFLAGS C compiler flags for GLIBSHARP, overriding pkg-config GLIBSHARP_LIBS linker flags for GLIBSHARP, overriding pkg-config GTKSHARP_A11Y_CFLAGS C compiler flags for GTKSHARP_A11Y, overriding pkg-config GTKSHARP_A11Y_LIBS linker flags for GTKSHARP_A11Y, overriding pkg-config NUNIT_CFLAGS C compiler flags for NUNIT, overriding pkg-config NUNIT_LIBS linker flags for NUNIT, overriding pkg-config Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF hyena configure 0.5 generated by GNU Autoconf 2.63 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by hyena $as_me 0.5, which was generated by GNU Autoconf 2.63. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. $as_echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; 2) ac_configure_args1="$ac_configure_args1 '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi ac_configure_args="$ac_configure_args '$ac_arg'" ;; esac done done $as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } $as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo cat <<\_ASBOX ## ---------------- ## ## Cache variables. ## ## ---------------- ## _ASBOX echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:$LINENO: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) $as_unset $ac_var ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo cat <<\_ASBOX ## ----------------- ## ## Output variables. ## ## ----------------- ## _ASBOX echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then cat <<\_ASBOX ## ------------------- ## ## File substitutions. ## ## ------------------- ## _ASBOX echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then cat <<\_ASBOX ## ----------- ## ## confdefs.h. ## ## ----------- ## _ASBOX echo cat confdefs.h echo fi test "$ac_signal" != 0 && $as_echo "$as_me: caught signal $ac_signal" $as_echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then ac_site_file1=$CONFIG_SITE elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site else ac_site_file1=$ac_default_prefix/share/config.site ac_site_file2=$ac_default_prefix/etc/config.site fi for ac_site_file in "$ac_site_file1" "$ac_site_file2" do test "x$ac_site_file" = xNONE && continue if test -r "$ac_site_file"; then { $as_echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special # files actually), so we avoid doing that. if test -f "$cache_file"; then { $as_echo "$as_me:$LINENO: loading cache $cache_file" >&5 $as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { $as_echo "$as_me:$LINENO: creating cache $cache_file" >&5 $as_echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { $as_echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { $as_echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { $as_echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 $as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { $as_echo "$as_me:$LINENO: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 $as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { $as_echo "$as_me:$LINENO: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:$LINENO: current value: \`$ac_new_val'" >&5 $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} { { $as_echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 $as_echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} { (exit 1); exit 1; }; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu am__api_version='1.10' ac_aux_dir= for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do if test -f "$ac_dir/install-sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f "$ac_dir/install.sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f "$ac_dir/shtool"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then { { $as_echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&5 $as_echo "$as_me: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&2;} { (exit 1); exit 1; }; } fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. # Reject install programs that cannot install multiple files. { $as_echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 $as_echo_n "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if test "${ac_cv_path_install+set}" = set; then $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in ./ | .// | /cC/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else rm -rf conftest.one conftest.two conftest.dir echo one > conftest.one echo two > conftest.two mkdir conftest.dir if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && test -s conftest.one && test -s conftest.two && test -s conftest.dir/conftest.one && test -s conftest.dir/conftest.two then ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi fi done done ;; esac done IFS=$as_save_IFS rm -rf conftest.one conftest.two conftest.dir fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi { $as_echo "$as_me:$LINENO: result: $INSTALL" >&5 $as_echo "$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' { $as_echo "$as_me:$LINENO: checking whether build environment is sane" >&5 $as_echo_n "checking whether build environment is sane... " >&6; } # Just in case sleep 1 echo timestamp > conftest.file # Do `set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` if test "$*" = "X"; then # -L didn't work. set X `ls -t $srcdir/configure conftest.file` fi rm -f conftest.file if test "$*" != "X $srcdir/configure conftest.file" \ && test "$*" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". { { $as_echo "$as_me:$LINENO: error: ls -t appears to fail. Make sure there is not a broken alias in your environment" >&5 $as_echo "$as_me: error: ls -t appears to fail. Make sure there is not a broken alias in your environment" >&2;} { (exit 1); exit 1; }; } fi test "$2" = conftest.file ) then # Ok. : else { { $as_echo "$as_me:$LINENO: error: newly created file is older than distributed files! Check your system clock" >&5 $as_echo "$as_me: error: newly created file is older than distributed files! Check your system clock" >&2;} { (exit 1); exit 1; }; } fi { $as_echo "$as_me:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } test "$program_prefix" != NONE && program_transform_name="s&^&$program_prefix&;$program_transform_name" # Use a double $ so make ignores it. test "$program_suffix" != NONE && program_transform_name="s&\$&$program_suffix&;$program_transform_name" # Double any \ or $. # By default was `s,x,x', remove it if useless. ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" # Use eval to expand $SHELL if eval "$MISSING --run true"; then am_missing_run="$MISSING --run " else am_missing_run= { $as_echo "$as_me:$LINENO: WARNING: \`missing' script is too old or missing" >&5 $as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} fi { $as_echo "$as_me:$LINENO: checking for a thread-safe mkdir -p" >&5 $as_echo_n "checking for a thread-safe mkdir -p... " >&6; } if test -z "$MKDIR_P"; then if test "${ac_cv_path_mkdir+set}" = set; then $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in mkdir gmkdir; do for ac_exec_ext in '' $ac_executable_extensions; do { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( 'mkdir (GNU coreutils) '* | \ 'mkdir (coreutils) '* | \ 'mkdir (fileutils) '4.1*) ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext break 3;; esac done done done IFS=$as_save_IFS fi if test "${ac_cv_path_mkdir+set}" = set; then MKDIR_P="$ac_cv_path_mkdir -p" else # As a last resort, use the slow shell script. Don't cache a # value for MKDIR_P within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. test -d ./--version && rmdir ./--version MKDIR_P="$ac_install_sh -d" fi fi { $as_echo "$as_me:$LINENO: result: $MKDIR_P" >&5 $as_echo "$MKDIR_P" >&6; } mkdir_p="$MKDIR_P" case $mkdir_p in [\\/$]* | ?:[\\/]*) ;; */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; esac for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_AWK+set}" = set; then $as_echo_n "(cached) " >&6 else if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_AWK="$ac_prog" $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then { $as_echo "$as_me:$LINENO: result: $AWK" >&5 $as_echo "$AWK" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AWK" && break done { $as_echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 $as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { $as_echo "$as_me:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } SET_MAKE= else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." am__isrc=' -I$(srcdir)' # test to see if srcdir already configured if test -f $srcdir/config.status; then { { $as_echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5 $as_echo "$as_me: error: source directory already configured; run \"make distclean\" there first" >&2;} { (exit 1); exit 1; }; } fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi # Define the identity of the package. PACKAGE='hyena' VERSION='0.5' cat >>confdefs.h <<_ACEOF #define PACKAGE "$PACKAGE" _ACEOF cat >>confdefs.h <<_ACEOF #define VERSION "$VERSION" _ACEOF # Some tools Automake needs. ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} install_sh=${install_sh-"\$(SHELL) $am_aux_dir/install-sh"} # Installed binaries are usually stripped using `strip' when the user # run `make install-strip'. However `strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the `STRIP' environment variable to overrule this program. if test "$cross_compiling" != no; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_STRIP+set}" = set; then $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { $as_echo "$as_me:$LINENO: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { $as_echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:$LINENO: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" # We need awk for the "check" target. The system "awk" is bad on # some platforms. # Always define AMTAR for backward compatibility. AMTAR=${AMTAR-"${am_missing_run}tar"} { $as_echo "$as_me:$LINENO: checking how to create a ustar tar archive" >&5 $as_echo_n "checking how to create a ustar tar archive... " >&6; } # Loop over all known methods to create a tar archive until one works. _am_tools='gnutar plaintar pax cpio none' _am_tools=${am_cv_prog_tar_ustar-$_am_tools} # Do not fold the above two line into one, because Tru64 sh and # Solaris sh will not grok spaces in the rhs of `-'. for _am_tool in $_am_tools do case $_am_tool in gnutar) for _am_tar in tar gnutar gtar; do { echo "$as_me:$LINENO: $_am_tar --version" >&5 ($_am_tar --version) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && break done am__tar="$_am_tar --format=ustar -chf - "'"$$tardir"' am__tar_="$_am_tar --format=ustar -chf - "'"$tardir"' am__untar="$_am_tar -xf -" ;; plaintar) # Must skip GNU tar: if it does not support --format= it doesn't create # ustar tarball either. (tar --version) >/dev/null 2>&1 && continue am__tar='tar chf - "$$tardir"' am__tar_='tar chf - "$tardir"' am__untar='tar xf -' ;; pax) am__tar='pax -L -x ustar -w "$$tardir"' am__tar_='pax -L -x ustar -w "$tardir"' am__untar='pax -r' ;; cpio) am__tar='find "$$tardir" -print | cpio -o -H ustar -L' am__tar_='find "$tardir" -print | cpio -o -H ustar -L' am__untar='cpio -i -H ustar -d' ;; none) am__tar=false am__tar_=false am__untar=false ;; esac # If the value was cached, stop now. We just wanted to have am__tar # and am__untar set. test -n "${am_cv_prog_tar_ustar}" && break # tar/untar a dummy directory, and stop if the command works rm -rf conftest.dir mkdir conftest.dir echo GrepMe > conftest.dir/file { echo "$as_me:$LINENO: tardir=conftest.dir && eval $am__tar_ >conftest.tar" >&5 (tardir=conftest.dir && eval $am__tar_ >conftest.tar) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } rm -rf conftest.dir if test -s conftest.tar; then { echo "$as_me:$LINENO: $am__untar &5 ($am__untar &5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } grep GrepMe conftest.dir/file >/dev/null 2>&1 && break fi done rm -rf conftest.dir if test "${am_cv_prog_tar_ustar+set}" = set; then $as_echo_n "(cached) " >&6 else am_cv_prog_tar_ustar=$_am_tool fi { $as_echo "$as_me:$LINENO: result: $am_cv_prog_tar_ustar" >&5 $as_echo "$am_cv_prog_tar_ustar" >&6; } { $as_echo "$as_me:$LINENO: checking whether to enable maintainer-specific portions of Makefiles" >&5 $as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; } # Check whether --enable-maintainer-mode was given. if test "${enable_maintainer_mode+set}" = set; then enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval else USE_MAINTAINER_MODE=no fi { $as_echo "$as_me:$LINENO: result: $USE_MAINTAINER_MODE" >&5 $as_echo "$USE_MAINTAINER_MODE" >&6; } if test $USE_MAINTAINER_MODE = yes; then MAINTAINER_MODE_TRUE= MAINTAINER_MODE_FALSE='#' else MAINTAINER_MODE_TRUE='#' MAINTAINER_MODE_FALSE= fi MAINT=$MAINTAINER_MODE_TRUE ACLOCAL_AMFLAGS="-I build/m4/shamrock \${ACLOCAL_FLAGS}" # Extract the first word of "pkg-config", so it can be a program name with args. set dummy pkg-config; ac_word=$2 { $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_path_PKG_CONFIG+set}" = set; then $as_echo_n "(cached) " >&6 else case $PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_PKG_CONFIG" && ac_cv_path_PKG_CONFIG="no" ;; esac fi PKG_CONFIG=$ac_cv_path_PKG_CONFIG if test -n "$PKG_CONFIG"; then { $as_echo "$as_me:$LINENO: result: $PKG_CONFIG" >&5 $as_echo "$PKG_CONFIG" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi if test "x$PKG_CONFIG" = "xno"; then { { $as_echo "$as_me:$LINENO: error: You need to install pkg-config" >&5 $as_echo "$as_me: error: You need to install pkg-config" >&2;} { (exit 1); exit 1; }; } fi expanded_libdir=`( case $prefix in NONE) prefix=$ac_default_prefix ;; *) ;; esac case $exec_prefix in NONE) exec_prefix=$prefix ;; *) ;; esac eval echo $libdir )` expanded_bindir=`( case $prefix in NONE) prefix=$ac_default_prefix ;; *) ;; esac case $exec_prefix in NONE) exec_prefix=$prefix ;; *) ;; esac eval echo $bindir )` case $prefix in NONE) prefix=$ac_default_prefix ;; *) ;; esac case $exec_prefix in NONE) exec_prefix=$prefix ;; *) ;; esac expanded_datadir=`(eval echo $datadir)` expanded_datadir=`(eval echo $expanded_datadir)` # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. # Reject install programs that cannot install multiple files. { $as_echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 $as_echo_n "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if test "${ac_cv_path_install+set}" = set; then $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in ./ | .// | /cC/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else rm -rf conftest.one conftest.two conftest.dir echo one > conftest.one echo two > conftest.two mkdir conftest.dir if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && test -s conftest.one && test -s conftest.two && test -s conftest.dir/conftest.one && test -s conftest.dir/conftest.two then ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi fi done done ;; esac done IFS=$as_save_IFS rm -rf conftest.one conftest.two conftest.dir fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi { $as_echo "$as_me:$LINENO: result: $INSTALL" >&5 $as_echo "$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' # Check whether --enable-debug was given. if test "${enable_debug+set}" = set; then enableval=$enable_debug; enable_debug=yes else enable_debug=no fi if test x$enable_debug = xyes; then ENABLE_DEBUG_TRUE= ENABLE_DEBUG_FALSE='#' else ENABLE_DEBUG_TRUE='#' ENABLE_DEBUG_FALSE= fi if test "x$enable_debug" = "xyes" ; then CONFIG_REQUESTED="yes" fi # Check whether --enable-release was given. if test "${enable_release+set}" = set; then enableval=$enable_release; enable_release=yes else enable_release=no fi if test x$enable_release = xyes; then ENABLE_RELEASE_TRUE= ENABLE_RELEASE_FALSE='#' else ENABLE_RELEASE_TRUE='#' ENABLE_RELEASE_FALSE= fi if test "x$enable_release" = "xyes" ; then CONFIG_REQUESTED="yes" fi # Check whether --enable-windows was given. if test "${enable_windows+set}" = set; then enableval=$enable_windows; enable_windows=yes else enable_windows=no fi if test x$enable_windows = xyes; then ENABLE_WINDOWS_TRUE= ENABLE_WINDOWS_FALSE='#' else ENABLE_WINDOWS_TRUE='#' ENABLE_WINDOWS_FALSE= fi if test "x$enable_windows" = "xyes" ; then CONFIG_REQUESTED="yes" fi if test -z "$CONFIG_REQUESTED" ; then if true; then ENABLE_DEBUG_TRUE= ENABLE_DEBUG_FALSE='#' else ENABLE_DEBUG_TRUE='#' ENABLE_DEBUG_FALSE= fi enable_debug=yes fi if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 { $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_path_PKG_CONFIG+set}" = set; then $as_echo_n "(cached) " >&6 else case $PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi PKG_CONFIG=$ac_cv_path_PKG_CONFIG if test -n "$PKG_CONFIG"; then { $as_echo "$as_me:$LINENO: result: $PKG_CONFIG" >&5 $as_echo "$PKG_CONFIG" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_path_PKG_CONFIG"; then ac_pt_PKG_CONFIG=$PKG_CONFIG # Extract the first word of "pkg-config", so it can be a program name with args. set dummy pkg-config; ac_word=$2 { $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_path_ac_pt_PKG_CONFIG+set}" = set; then $as_echo_n "(cached) " >&6 else case $ac_pt_PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG if test -n "$ac_pt_PKG_CONFIG"; then { $as_echo "$as_me:$LINENO: result: $ac_pt_PKG_CONFIG" >&5 $as_echo "$ac_pt_PKG_CONFIG" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_pt_PKG_CONFIG" = x; then PKG_CONFIG="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:$LINENO: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac PKG_CONFIG=$ac_pt_PKG_CONFIG fi else PKG_CONFIG="$ac_cv_path_PKG_CONFIG" fi fi if test -n "$PKG_CONFIG"; then _pkg_min_version=0.9.0 { $as_echo "$as_me:$LINENO: checking pkg-config is at least version $_pkg_min_version" >&5 $as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; } if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then { $as_echo "$as_me:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } PKG_CONFIG="" fi fi pkg_failed=no { $as_echo "$as_me:$LINENO: checking for MONO_MODULE" >&5 $as_echo_n "checking for MONO_MODULE... " >&6; } if test -n "$MONO_MODULE_CFLAGS"; then pkg_cv_MONO_MODULE_CFLAGS="$MONO_MODULE_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { ($as_echo "$as_me:$LINENO: \$PKG_CONFIG --exists --print-errors \"mono >= 1.9.1\"") >&5 ($PKG_CONFIG --exists --print-errors "mono >= 1.9.1") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then pkg_cv_MONO_MODULE_CFLAGS=`$PKG_CONFIG --cflags "mono >= 1.9.1" 2>/dev/null` else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$MONO_MODULE_LIBS"; then pkg_cv_MONO_MODULE_LIBS="$MONO_MODULE_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { ($as_echo "$as_me:$LINENO: \$PKG_CONFIG --exists --print-errors \"mono >= 1.9.1\"") >&5 ($PKG_CONFIG --exists --print-errors "mono >= 1.9.1") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then pkg_cv_MONO_MODULE_LIBS=`$PKG_CONFIG --libs "mono >= 1.9.1" 2>/dev/null` else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then MONO_MODULE_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "mono >= 1.9.1" 2>&1` else MONO_MODULE_PKG_ERRORS=`$PKG_CONFIG --print-errors "mono >= 1.9.1" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$MONO_MODULE_PKG_ERRORS" >&5 { { $as_echo "$as_me:$LINENO: error: Package requirements (mono >= 1.9.1) were not met: $MONO_MODULE_PKG_ERRORS Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. Alternatively, you may set the environment variables MONO_MODULE_CFLAGS and MONO_MODULE_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details. " >&5 $as_echo "$as_me: error: Package requirements (mono >= 1.9.1) were not met: $MONO_MODULE_PKG_ERRORS Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. Alternatively, you may set the environment variables MONO_MODULE_CFLAGS and MONO_MODULE_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details. " >&2;} { (exit 1); exit 1; }; } elif test $pkg_failed = untried; then { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { { $as_echo "$as_me:$LINENO: error: The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. Alternatively, you may set the environment variables MONO_MODULE_CFLAGS and MONO_MODULE_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details. To get pkg-config, see . See \`config.log' for more details." >&5 $as_echo "$as_me: error: The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. Alternatively, you may set the environment variables MONO_MODULE_CFLAGS and MONO_MODULE_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details. To get pkg-config, see . See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; }; } else MONO_MODULE_CFLAGS=$pkg_cv_MONO_MODULE_CFLAGS MONO_MODULE_LIBS=$pkg_cv_MONO_MODULE_LIBS { $as_echo "$as_me:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } : fi # Extract the first word of "gmcs", so it can be a program name with args. set dummy gmcs; ac_word=$2 { $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_path_MCS+set}" = set; then $as_echo_n "(cached) " >&6 else case $MCS in [\\/]* | ?:[\\/]*) ac_cv_path_MCS="$MCS" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_MCS="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_MCS" && ac_cv_path_MCS="no" ;; esac fi MCS=$ac_cv_path_MCS if test -n "$MCS"; then { $as_echo "$as_me:$LINENO: result: $MCS" >&5 $as_echo "$MCS" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi if test "x$MCS" = "xno"; then { { $as_echo "$as_me:$LINENO: error: You need to install 'gmcs'" >&5 $as_echo "$as_me: error: You need to install 'gmcs'" >&2;} { (exit 1); exit 1; }; } fi # Extract the first word of "mono", so it can be a program name with args. set dummy mono; ac_word=$2 { $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_path_MONO+set}" = set; then $as_echo_n "(cached) " >&6 else case $MONO in [\\/]* | ?:[\\/]*) ac_cv_path_MONO="$MONO" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_MONO="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_MONO" && ac_cv_path_MONO="no" ;; esac fi MONO=$ac_cv_path_MONO if test -n "$MONO"; then { $as_echo "$as_me:$LINENO: result: $MONO" >&5 $as_echo "$MONO" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi if test "x$MONO" = "xno"; then { { $as_echo "$as_me:$LINENO: error: You need to install 'mono'" >&5 $as_echo "$as_me: error: You need to install 'mono'" >&2;} { (exit 1); exit 1; }; } fi for asm in $(echo "2.0,System.Data Mono.Cairo Mono.Posix ICSharpCode.SharpZipLib " | cut -d, -f2- | sed 's/\,/ /g') do { $as_echo "$as_me:$LINENO: checking for Mono 2.0 GAC for $asm.dll" >&5 $as_echo_n "checking for Mono 2.0 GAC for $asm.dll... " >&6; } if test \ -e "$($PKG_CONFIG --variable=libdir mono)/mono/2.0/$asm.dll" -o \ -e "$($PKG_CONFIG --variable=prefix mono)/lib/mono/2.0/$asm.dll"; \ then \ { $as_echo "$as_me:$LINENO: result: found" >&5 $as_echo "found" >&6; } else { $as_echo "$as_me:$LINENO: result: not found" >&5 $as_echo "not found" >&6; } { { $as_echo "$as_me:$LINENO: error: missing required Mono 2.0 assembly: $asm.dll" >&5 $as_echo "$as_me: error: missing required Mono 2.0 assembly: $asm.dll" >&2;} { (exit 1); exit 1; }; } fi done pkg_failed=no { $as_echo "$as_me:$LINENO: checking for GTKSHARP" >&5 $as_echo_n "checking for GTKSHARP... " >&6; } if test -n "$GTKSHARP_CFLAGS"; then pkg_cv_GTKSHARP_CFLAGS="$GTKSHARP_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { ($as_echo "$as_me:$LINENO: \$PKG_CONFIG --exists --print-errors \"gtk-sharp-2.0\"") >&5 ($PKG_CONFIG --exists --print-errors "gtk-sharp-2.0") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then pkg_cv_GTKSHARP_CFLAGS=`$PKG_CONFIG --cflags "gtk-sharp-2.0" 2>/dev/null` else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$GTKSHARP_LIBS"; then pkg_cv_GTKSHARP_LIBS="$GTKSHARP_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { ($as_echo "$as_me:$LINENO: \$PKG_CONFIG --exists --print-errors \"gtk-sharp-2.0\"") >&5 ($PKG_CONFIG --exists --print-errors "gtk-sharp-2.0") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then pkg_cv_GTKSHARP_LIBS=`$PKG_CONFIG --libs "gtk-sharp-2.0" 2>/dev/null` else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then GTKSHARP_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "gtk-sharp-2.0" 2>&1` else GTKSHARP_PKG_ERRORS=`$PKG_CONFIG --print-errors "gtk-sharp-2.0" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$GTKSHARP_PKG_ERRORS" >&5 { { $as_echo "$as_me:$LINENO: error: Package requirements (gtk-sharp-2.0) were not met: $GTKSHARP_PKG_ERRORS Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. Alternatively, you may set the environment variables GTKSHARP_CFLAGS and GTKSHARP_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details. " >&5 $as_echo "$as_me: error: Package requirements (gtk-sharp-2.0) were not met: $GTKSHARP_PKG_ERRORS Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. Alternatively, you may set the environment variables GTKSHARP_CFLAGS and GTKSHARP_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details. " >&2;} { (exit 1); exit 1; }; } elif test $pkg_failed = untried; then { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { { $as_echo "$as_me:$LINENO: error: The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. Alternatively, you may set the environment variables GTKSHARP_CFLAGS and GTKSHARP_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details. To get pkg-config, see . See \`config.log' for more details." >&5 $as_echo "$as_me: error: The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. Alternatively, you may set the environment variables GTKSHARP_CFLAGS and GTKSHARP_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details. To get pkg-config, see . See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; }; } else GTKSHARP_CFLAGS=$pkg_cv_GTKSHARP_CFLAGS GTKSHARP_LIBS=$pkg_cv_GTKSHARP_LIBS { $as_echo "$as_me:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } : fi pkg_failed=no { $as_echo "$as_me:$LINENO: checking for GLIBSHARP" >&5 $as_echo_n "checking for GLIBSHARP... " >&6; } if test -n "$GLIBSHARP_CFLAGS"; then pkg_cv_GLIBSHARP_CFLAGS="$GLIBSHARP_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { ($as_echo "$as_me:$LINENO: \$PKG_CONFIG --exists --print-errors \"glib-sharp-2.0\"") >&5 ($PKG_CONFIG --exists --print-errors "glib-sharp-2.0") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then pkg_cv_GLIBSHARP_CFLAGS=`$PKG_CONFIG --cflags "glib-sharp-2.0" 2>/dev/null` else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$GLIBSHARP_LIBS"; then pkg_cv_GLIBSHARP_LIBS="$GLIBSHARP_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { ($as_echo "$as_me:$LINENO: \$PKG_CONFIG --exists --print-errors \"glib-sharp-2.0\"") >&5 ($PKG_CONFIG --exists --print-errors "glib-sharp-2.0") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then pkg_cv_GLIBSHARP_LIBS=`$PKG_CONFIG --libs "glib-sharp-2.0" 2>/dev/null` else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then GLIBSHARP_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "glib-sharp-2.0" 2>&1` else GLIBSHARP_PKG_ERRORS=`$PKG_CONFIG --print-errors "glib-sharp-2.0" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$GLIBSHARP_PKG_ERRORS" >&5 { { $as_echo "$as_me:$LINENO: error: Package requirements (glib-sharp-2.0) were not met: $GLIBSHARP_PKG_ERRORS Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. Alternatively, you may set the environment variables GLIBSHARP_CFLAGS and GLIBSHARP_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details. " >&5 $as_echo "$as_me: error: Package requirements (glib-sharp-2.0) were not met: $GLIBSHARP_PKG_ERRORS Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. Alternatively, you may set the environment variables GLIBSHARP_CFLAGS and GLIBSHARP_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details. " >&2;} { (exit 1); exit 1; }; } elif test $pkg_failed = untried; then { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { { $as_echo "$as_me:$LINENO: error: The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. Alternatively, you may set the environment variables GLIBSHARP_CFLAGS and GLIBSHARP_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details. To get pkg-config, see . See \`config.log' for more details." >&5 $as_echo "$as_me: error: The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. Alternatively, you may set the environment variables GLIBSHARP_CFLAGS and GLIBSHARP_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details. To get pkg-config, see . See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; }; } else GLIBSHARP_CFLAGS=$pkg_cv_GLIBSHARP_CFLAGS GLIBSHARP_LIBS=$pkg_cv_GLIBSHARP_LIBS { $as_echo "$as_me:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } : fi pkg_failed=no { $as_echo "$as_me:$LINENO: checking for GTKSHARP_A11Y" >&5 $as_echo_n "checking for GTKSHARP_A11Y... " >&6; } if test -n "$GTKSHARP_A11Y_CFLAGS"; then pkg_cv_GTKSHARP_A11Y_CFLAGS="$GTKSHARP_A11Y_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { ($as_echo "$as_me:$LINENO: \$PKG_CONFIG --exists --print-errors \"gtk-sharp-2.0 >= 2.12.10\"") >&5 ($PKG_CONFIG --exists --print-errors "gtk-sharp-2.0 >= 2.12.10") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then pkg_cv_GTKSHARP_A11Y_CFLAGS=`$PKG_CONFIG --cflags "gtk-sharp-2.0 >= 2.12.10" 2>/dev/null` else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$GTKSHARP_A11Y_LIBS"; then pkg_cv_GTKSHARP_A11Y_LIBS="$GTKSHARP_A11Y_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { ($as_echo "$as_me:$LINENO: \$PKG_CONFIG --exists --print-errors \"gtk-sharp-2.0 >= 2.12.10\"") >&5 ($PKG_CONFIG --exists --print-errors "gtk-sharp-2.0 >= 2.12.10") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then pkg_cv_GTKSHARP_A11Y_LIBS=`$PKG_CONFIG --libs "gtk-sharp-2.0 >= 2.12.10" 2>/dev/null` else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then GTKSHARP_A11Y_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "gtk-sharp-2.0 >= 2.12.10" 2>&1` else GTKSHARP_A11Y_PKG_ERRORS=`$PKG_CONFIG --print-errors "gtk-sharp-2.0 >= 2.12.10" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$GTKSHARP_A11Y_PKG_ERRORS" >&5 { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } gtksharp_with_a11y=no elif test $pkg_failed = untried; then gtksharp_with_a11y=no else GTKSHARP_A11Y_CFLAGS=$pkg_cv_GTKSHARP_A11Y_CFLAGS GTKSHARP_A11Y_LIBS=$pkg_cv_GTKSHARP_A11Y_LIBS { $as_echo "$as_me:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } gtksharp_with_a11y=yes fi if test "x$gtksharp_with_a11y" = "xyes"; then ENABLE_ATK_TRUE= ENABLE_ATK_FALSE='#' else ENABLE_ATK_TRUE='#' ENABLE_ATK_FALSE= fi if false; then GCONF_SCHEMAS_INSTALL_TRUE= GCONF_SCHEMAS_INSTALL_FALSE='#' else GCONF_SCHEMAS_INSTALL_TRUE='#' GCONF_SCHEMAS_INSTALL_FALSE= fi if true; then HYENA_PKG_CONFIG_TRUE= HYENA_PKG_CONFIG_FALSE='#' else HYENA_PKG_CONFIG_TRUE='#' HYENA_PKG_CONFIG_FALSE= fi NUNIT_REQUIRED=2.4.7 # Check whether --enable-tests was given. if test "${enable_tests+set}" = set; then enableval=$enable_tests; enable_tests=$enableval else enable_tests="no" fi if test "x$enable_tests" = "xno"; then do_tests=no if false; then ENABLE_TESTS_TRUE= ENABLE_TESTS_FALSE='#' else ENABLE_TESTS_TRUE='#' ENABLE_TESTS_FALSE= fi else pkg_failed=no { $as_echo "$as_me:$LINENO: checking for NUNIT" >&5 $as_echo_n "checking for NUNIT... " >&6; } if test -n "$NUNIT_CFLAGS"; then pkg_cv_NUNIT_CFLAGS="$NUNIT_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { ($as_echo "$as_me:$LINENO: \$PKG_CONFIG --exists --print-errors \"nunit >= \$NUNIT_REQUIRED\"") >&5 ($PKG_CONFIG --exists --print-errors "nunit >= $NUNIT_REQUIRED") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then pkg_cv_NUNIT_CFLAGS=`$PKG_CONFIG --cflags "nunit >= $NUNIT_REQUIRED" 2>/dev/null` else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$NUNIT_LIBS"; then pkg_cv_NUNIT_LIBS="$NUNIT_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { ($as_echo "$as_me:$LINENO: \$PKG_CONFIG --exists --print-errors \"nunit >= \$NUNIT_REQUIRED\"") >&5 ($PKG_CONFIG --exists --print-errors "nunit >= $NUNIT_REQUIRED") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then pkg_cv_NUNIT_LIBS=`$PKG_CONFIG --libs "nunit >= $NUNIT_REQUIRED" 2>/dev/null` else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then NUNIT_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "nunit >= $NUNIT_REQUIRED" 2>&1` else NUNIT_PKG_ERRORS=`$PKG_CONFIG --print-errors "nunit >= $NUNIT_REQUIRED" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$NUNIT_PKG_ERRORS" >&5 { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } do_tests="no" elif test $pkg_failed = untried; then do_tests="no" else NUNIT_CFLAGS=$pkg_cv_NUNIT_CFLAGS NUNIT_LIBS=$pkg_cv_NUNIT_LIBS { $as_echo "$as_me:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } do_tests="yes" fi if test "x$do_tests" = "xyes"; then ENABLE_TESTS_TRUE= ENABLE_TESTS_FALSE='#' else ENABLE_TESTS_TRUE='#' ENABLE_TESTS_FALSE= fi if test "x$do_tests" = "xno"; then pkg_failed=no { $as_echo "$as_me:$LINENO: checking for NUNIT" >&5 $as_echo_n "checking for NUNIT... " >&6; } if test -n "$NUNIT_CFLAGS"; then pkg_cv_NUNIT_CFLAGS="$NUNIT_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { ($as_echo "$as_me:$LINENO: \$PKG_CONFIG --exists --print-errors \"mono-nunit >= 2.4\"") >&5 ($PKG_CONFIG --exists --print-errors "mono-nunit >= 2.4") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then pkg_cv_NUNIT_CFLAGS=`$PKG_CONFIG --cflags "mono-nunit >= 2.4" 2>/dev/null` else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$NUNIT_LIBS"; then pkg_cv_NUNIT_LIBS="$NUNIT_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { ($as_echo "$as_me:$LINENO: \$PKG_CONFIG --exists --print-errors \"mono-nunit >= 2.4\"") >&5 ($PKG_CONFIG --exists --print-errors "mono-nunit >= 2.4") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then pkg_cv_NUNIT_LIBS=`$PKG_CONFIG --libs "mono-nunit >= 2.4" 2>/dev/null` else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then NUNIT_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "mono-nunit >= 2.4" 2>&1` else NUNIT_PKG_ERRORS=`$PKG_CONFIG --print-errors "mono-nunit >= 2.4" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$NUNIT_PKG_ERRORS" >&5 { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } do_tests="no" elif test $pkg_failed = untried; then do_tests="no" else NUNIT_CFLAGS=$pkg_cv_NUNIT_CFLAGS NUNIT_LIBS=$pkg_cv_NUNIT_LIBS { $as_echo "$as_me:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } do_tests="yes" fi if test "x$do_tests" = "xyes"; then ENABLE_TESTS_TRUE= ENABLE_TESTS_FALSE='#' else ENABLE_TESTS_TRUE='#' ENABLE_TESTS_FALSE= fi if test "x$do_tests" = "xno"; then { $as_echo "$as_me:$LINENO: WARNING: Could not find nunit: tests will not be available" >&5 $as_echo "$as_me: WARNING: Could not find nunit: tests will not be available" >&2;} fi fi fi ac_config_files="$ac_config_files Makefile build/Makefile build/m4/Makefile build/pkg-config/Makefile Mono.Data.Sqlite/Makefile Hyena/Makefile Hyena.Data.Sqlite/Makefile Hyena.Gui/Makefile" cat <= ${NUNIT_REQUIRED}) Custom a11y: ${gtksharp_with_a11y} (requires gtk-sharp >= 2.12.10) EOF cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:$LINENO: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) $as_unset $ac_var ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes (double-quote # substitution turns \\\\ into \\, and sed turns \\ into \). sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then test "x$cache_file" != "x/dev/null" && { $as_echo "$as_me:$LINENO: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} cat confcache >$cache_file else { $as_echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' # Transform confdefs.h into DEFS. # Protect against shell expansion while executing Makefile rules. # Protect against Makefile macro expansion. # # If the first sed substitution is executed (which looks for macros that # take arguments), then branch to the quote section. Otherwise, # look for a macro that doesn't take arguments. ac_script=' :mline /\\$/{ N s,\\\n,, b mline } t clear :clear s/^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)/-D\1=\2/g t quote s/^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)/-D\1=\2/g t quote b any :quote s/[ `~#$^&*(){}\\|;'\''"<>?]/\\&/g s/\[/\\&/g s/\]/\\&/g s/\$/$$/g H :any ${ g s/^\n// s/\n/ /g p } ' DEFS=`sed -n "$ac_script" confdefs.h` ac_libobjs= ac_ltlibobjs= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`$as_echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext" ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then { { $as_echo "$as_me:$LINENO: error: conditional \"MAINTAINER_MODE\" was never defined. Usually this means the macro was only invoked conditionally." >&5 $as_echo "$as_me: error: conditional \"MAINTAINER_MODE\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${ENABLE_DEBUG_TRUE}" && test -z "${ENABLE_DEBUG_FALSE}"; then { { $as_echo "$as_me:$LINENO: error: conditional \"ENABLE_DEBUG\" was never defined. Usually this means the macro was only invoked conditionally." >&5 $as_echo "$as_me: error: conditional \"ENABLE_DEBUG\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${ENABLE_RELEASE_TRUE}" && test -z "${ENABLE_RELEASE_FALSE}"; then { { $as_echo "$as_me:$LINENO: error: conditional \"ENABLE_RELEASE\" was never defined. Usually this means the macro was only invoked conditionally." >&5 $as_echo "$as_me: error: conditional \"ENABLE_RELEASE\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${ENABLE_WINDOWS_TRUE}" && test -z "${ENABLE_WINDOWS_FALSE}"; then { { $as_echo "$as_me:$LINENO: error: conditional \"ENABLE_WINDOWS\" was never defined. Usually this means the macro was only invoked conditionally." >&5 $as_echo "$as_me: error: conditional \"ENABLE_WINDOWS\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${ENABLE_DEBUG_TRUE}" && test -z "${ENABLE_DEBUG_FALSE}"; then { { $as_echo "$as_me:$LINENO: error: conditional \"ENABLE_DEBUG\" was never defined. Usually this means the macro was only invoked conditionally." >&5 $as_echo "$as_me: error: conditional \"ENABLE_DEBUG\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${ENABLE_ATK_TRUE}" && test -z "${ENABLE_ATK_FALSE}"; then { { $as_echo "$as_me:$LINENO: error: conditional \"ENABLE_ATK\" was never defined. Usually this means the macro was only invoked conditionally." >&5 $as_echo "$as_me: error: conditional \"ENABLE_ATK\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${GCONF_SCHEMAS_INSTALL_TRUE}" && test -z "${GCONF_SCHEMAS_INSTALL_FALSE}"; then { { $as_echo "$as_me:$LINENO: error: conditional \"GCONF_SCHEMAS_INSTALL\" was never defined. Usually this means the macro was only invoked conditionally." >&5 $as_echo "$as_me: error: conditional \"GCONF_SCHEMAS_INSTALL\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${HYENA_PKG_CONFIG_TRUE}" && test -z "${HYENA_PKG_CONFIG_FALSE}"; then { { $as_echo "$as_me:$LINENO: error: conditional \"HYENA_PKG_CONFIG\" was never defined. Usually this means the macro was only invoked conditionally." >&5 $as_echo "$as_me: error: conditional \"HYENA_PKG_CONFIG\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${ENABLE_TESTS_TRUE}" && test -z "${ENABLE_TESTS_FALSE}"; then { { $as_echo "$as_me:$LINENO: error: conditional \"ENABLE_TESTS\" was never defined. Usually this means the macro was only invoked conditionally." >&5 $as_echo "$as_me: error: conditional \"ENABLE_TESTS\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${ENABLE_TESTS_TRUE}" && test -z "${ENABLE_TESTS_FALSE}"; then { { $as_echo "$as_me:$LINENO: error: conditional \"ENABLE_TESTS\" was never defined. Usually this means the macro was only invoked conditionally." >&5 $as_echo "$as_me: error: conditional \"ENABLE_TESTS\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${ENABLE_TESTS_TRUE}" && test -z "${ENABLE_TESTS_FALSE}"; then { { $as_echo "$as_me:$LINENO: error: conditional \"ENABLE_TESTS\" was never defined. Usually this means the macro was only invoked conditionally." >&5 $as_echo "$as_me: error: conditional \"ENABLE_TESTS\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi : ${CONFIG_STATUS=./config.status} ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { $as_echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} cat >$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ## --------------------- ## ## M4sh Initialization. ## ## --------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac fi # PATH needs CR # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo if (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. case $0 in *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 { (exit 1); exit 1; } fi # Work around bugs in pre-3.0 UWIN ksh. for as_var in ENV MAIL MAILPATH do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi # Name of the executable. as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # CDPATH. $as_unset CDPATH as_lineno_1=$LINENO as_lineno_2=$LINENO test "x$as_lineno_1" != "x$as_lineno_2" && test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line after each line using $LINENO; the second 'sed' # does the real work. The second script uses 'N' to pair each # line-number line with the line containing $LINENO, and appends # trailing '-' during substitution so that $LINENO is not a special # case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # scripts with optimization help from Paolo Bonzini. Blame Lee # E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in -n*) case `echo 'x\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. *) ECHO_C='\c';; esac;; *) ECHO_N='-n';; esac if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p=: else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 # Save the log message, to keep $[0] and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by hyena $as_me 0.5, which was generated by GNU Autoconf 2.63. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files from templates according to the current configuration. Usage: $0 [OPTION]... [FILE]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE Configuration files: $config_files Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_version="\\ hyena config.status 0.5 configured by $0, generated by GNU Autoconf 2.63, with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" Copyright (C) 2008 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' INSTALL='$INSTALL' MKDIR_P='$MKDIR_P' AWK='$AWK' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) $as_echo "$ac_cs_version"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac CONFIG_FILES="$CONFIG_FILES '$ac_optarg'" ac_need_defaults=false;; --he | --h | --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) { $as_echo "$as_me: error: unrecognized option: $1 Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; } ;; *) ac_config_targets="$ac_config_targets $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX $as_echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "build/Makefile") CONFIG_FILES="$CONFIG_FILES build/Makefile" ;; "build/m4/Makefile") CONFIG_FILES="$CONFIG_FILES build/m4/Makefile" ;; "build/pkg-config/Makefile") CONFIG_FILES="$CONFIG_FILES build/pkg-config/Makefile" ;; "Mono.Data.Sqlite/Makefile") CONFIG_FILES="$CONFIG_FILES Mono.Data.Sqlite/Makefile" ;; "Hyena/Makefile") CONFIG_FILES="$CONFIG_FILES Hyena/Makefile" ;; "Hyena.Data.Sqlite/Makefile") CONFIG_FILES="$CONFIG_FILES Hyena.Data.Sqlite/Makefile" ;; "Hyena.Gui/Makefile") CONFIG_FILES="$CONFIG_FILES Hyena.Gui/Makefile" ;; *) { { $as_echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 $as_echo "$as_me: error: invalid argument: $ac_config_target" >&2;} { (exit 1); exit 1; }; };; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= trap 'exit_status=$? { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status ' 0 trap '{ (exit 1); exit 1; }' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || { $as_echo "$as_me: cannot create a temporary directory in ." >&2 { (exit 1); exit 1; } } # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=' ' ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 $as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} { (exit 1); exit 1; }; } ac_delim_num=`echo "$ac_subst_vars" | grep -c '$'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 $as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} { (exit 1); exit 1; }; } ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 $as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} { (exit 1); exit 1; }; } else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\).*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\).*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \ || { { $as_echo "$as_me:$LINENO: error: could not setup config files machinery" >&5 $as_echo "$as_me: error: could not setup config files machinery" >&2;} { (exit 1); exit 1; }; } _ACEOF # VPATH may cause trouble with some makes, so we remove $(srcdir), # ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=/{ s/:*\$(srcdir):*/:/ s/:*\${srcdir}:*/:/ s/:*@srcdir@:*/:/ s/^\([^=]*=[ ]*\):*/\1/ s/:*$// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" eval set X " :F $CONFIG_FILES " shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) { { $as_echo "$as_me:$LINENO: error: invalid tag $ac_tag" >&5 $as_echo "$as_me: error: invalid tag $ac_tag" >&2;} { (exit 1); exit 1; }; };; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || { { $as_echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5 $as_echo "$as_me: error: cannot find input file: $ac_f" >&2;} { (exit 1); exit 1; }; };; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac ac_file_inputs="$ac_file_inputs '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { $as_echo "$as_me:$LINENO: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`$as_echo "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$tmp/stdin" \ || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 $as_echo "$as_me: error: could not create $ac_file" >&2;} { (exit 1); exit 1; }; } ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` { as_dir="$ac_dir" case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || { { $as_echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 $as_echo "$as_me: error: cannot create directory $as_dir" >&2;} { (exit 1); exit 1; }; }; } ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac ac_MKDIR_P=$MKDIR_P case $MKDIR_P in [\\/$]* | ?:[\\/]* ) ;; */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p ' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { $as_echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 $as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t s&@MKDIR_P@&$ac_MKDIR_P&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \ || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 $as_echo "$as_me: error: could not create $ac_file" >&2;} { (exit 1); exit 1; }; } test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined." >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined." >&2;} rm -f "$tmp/stdin" case $ac_file in -) cat "$tmp/out" && rm -f "$tmp/out";; *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";; esac \ || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 $as_echo "$as_me: error: could not create $ac_file" >&2;} { (exit 1); exit 1; }; } ;; esac done # for ac_tag { (exit 0); exit 0; } _ACEOF chmod +x $CONFIG_STATUS ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || { { $as_echo "$as_me:$LINENO: error: write failure creating $CONFIG_STATUS" >&5 $as_echo "$as_me: error: write failure creating $CONFIG_STATUS" >&2;} { (exit 1); exit 1; }; } # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || { (exit 1); exit 1; } fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:$LINENO: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi hyena-0.5/Hyena.Data.Sqlite/0000777000175000001440000000000011453151002015747 5ustar00gabeusers00000000000000hyena-0.5/Hyena.Data.Sqlite/Makefile.in0000644000175000001440000003404211453150777020035 0ustar00gabeusers00000000000000# Makefile.in generated by automake 1.10.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(top_srcdir)/build/build.environment.mk \ $(top_srcdir)/build/build.mk \ $(top_srcdir)/build/build.rules.mk @ENABLE_TESTS_TRUE@am__append_1 = " $(NUNIT_LIBS)" subdir = Hyena.Data.Sqlite ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/build/m4/shamrock/expansions.m4 \ $(top_srcdir)/build/m4/shamrock/mono.m4 \ $(top_srcdir)/build/m4/shamrock/programs.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = am__installdirs = "$(DESTDIR)$(moduledir)" moduleSCRIPT_INSTALL = $(INSTALL_SCRIPT) SCRIPTS = $(module_SCRIPTS) DIST_SOURCES = DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ GLIBSHARP_CFLAGS = @GLIBSHARP_CFLAGS@ GLIBSHARP_LIBS = @GLIBSHARP_LIBS@ GTKSHARP_A11Y_CFLAGS = @GTKSHARP_A11Y_CFLAGS@ GTKSHARP_A11Y_LIBS = @GTKSHARP_A11Y_LIBS@ GTKSHARP_CFLAGS = @GTKSHARP_CFLAGS@ GTKSHARP_LIBS = @GTKSHARP_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MCS = @MCS@ MKDIR_P = @MKDIR_P@ MONO = @MONO@ MONO_MODULE_CFLAGS = @MONO_MODULE_CFLAGS@ MONO_MODULE_LIBS = @MONO_MODULE_LIBS@ NUNIT_CFLAGS = @NUNIT_CFLAGS@ NUNIT_LIBS = @NUNIT_LIBS@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ am__leading_dot = @am__leading_dot@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ expanded_bindir = @expanded_bindir@ expanded_datadir = @expanded_datadir@ expanded_libdir = @expanded_libdir@ host_alias = @host_alias@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ ASSEMBLY = Hyena.Data.Sqlite TARGET = library LINK = -r:Mono.Posix -r:System -r:System.Core -r:System.Data \ -r:$(DIR_BIN)/Mono.Data.Sqlite.dll -r:$(DIR_BIN)/Hyena.dll \ $(am__append_1) SOURCES = \ Hyena.Data.Sqlite/DatabaseColumn.cs \ Hyena.Data.Sqlite/DatabaseColumnAttribute.cs \ Hyena.Data.Sqlite/HyenaSqliteArrayDataReader.cs \ Hyena.Data.Sqlite/HyenaSqliteCommand.cs \ Hyena.Data.Sqlite/HyenaSqliteConnection.cs \ Hyena.Data.Sqlite/ICacheableDatabaseModel.cs \ Hyena.Data.Sqlite/SqliteModelCache.cs \ Hyena.Data.Sqlite/SqliteModelProvider.cs \ Hyena.Data.Sqlite/SqliteUtils.cs \ Hyena.Data.Sqlite/Tests/DbBoundType.cs \ Hyena.Data.Sqlite/Tests/SqliteCommandTests.cs \ Hyena.Data.Sqlite/Tests/SqliteModelProviderTests.cs \ Hyena.Data.Sqlite/Tests/SqliteUtilTests.cs \ Hyena.Metrics/DbSampleStore.cs \ Hyena.Metrics/HttpPoster.cs \ Hyena.Metrics/ISampleStore.cs \ Hyena.Metrics/MemorySampleStore.cs \ Hyena.Metrics/Metric.cs \ Hyena.Metrics/MetricsCollection.cs \ Hyena.Metrics/Sample.cs \ Hyena.Metrics/Tests/MetricsTests.cs # Initializers MONO_BASE_PATH = MONO_ADDINS_PATH = # Install Paths DEFAULT_INSTALL_DIR = $(pkglibdir) DIR_BIN = $(top_builddir)/bin # Cute hack to replace a space with something colon := : empty := space := $(empty) $(empty) UNIQUE_FILTER_PIPE = tr [:space:] \\n | sort | uniq BUILD_DATA_DIR = $(top_builddir)/bin/share/$(PACKAGE) SOURCES_BUILD = $(addprefix $(srcdir)/, $(SOURCES)) RESOURCES_EXPANDED = $(addprefix $(srcdir)/, $(RESOURCES)) RESOURCES_BUILD = $(foreach resource, $(RESOURCES_EXPANDED), \ -resource:$(resource),$(notdir $(resource))) INSTALL_ICONS = $(top_srcdir)/build/private-icon-theme-installer "$(mkinstalldirs)" "$(INSTALL_DATA)" THEME_ICONS_SOURCE = $(wildcard $(srcdir)/ThemeIcons/*/*/*.png) $(wildcard $(srcdir)/ThemeIcons/scalable/*/*.svg) THEME_ICONS_RELATIVE = $(subst $(srcdir)/ThemeIcons/, , $(THEME_ICONS_SOURCE)) ASSEMBLY_EXTENSION = $(strip $(patsubst library, dll, $(TARGET))) ASSEMBLY_FILE = $(top_builddir)/bin/$(ASSEMBLY).$(ASSEMBLY_EXTENSION) INSTALL_DIR_RESOLVED = $(firstword $(subst , $(DEFAULT_INSTALL_DIR), $(INSTALL_DIR))) @ENABLE_TESTS_TRUE@ENABLE_TESTS_FLAG = "-define:ENABLE_TESTS" @ENABLE_ATK_TRUE@ENABLE_ATK_FLAG = "-define:ENABLE_ATK" FILTERED_LINK = $(shell echo "$(LINK)" | $(UNIQUE_FILTER_PIPE)) DEP_LINK = $(shell echo "$(LINK)" | $(UNIQUE_FILTER_PIPE) | sed s,-r:,,g | grep '$(top_builddir)/bin/') OUTPUT_FILES = \ $(ASSEMBLY_FILE) \ $(ASSEMBLY_FILE).mdb moduledir = $(INSTALL_DIR_RESOLVED) module_SCRIPTS = $(OUTPUT_FILES) EXTRA_DIST = $(SOURCES_BUILD) $(RESOURCES_EXPANDED) $(THEME_ICONS_SOURCE) CLEANFILES = $(OUTPUT_FILES) DISTCLEANFILES = *.pidb MAINTAINERCLEANFILES = Makefile.in all: all-am .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/build/build.mk $(top_srcdir)/build/build.environment.mk $(top_srcdir)/build/build.rules.mk $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Hyena.Data.Sqlite/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --foreign Hyena.Data.Sqlite/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh install-moduleSCRIPTS: $(module_SCRIPTS) @$(NORMAL_INSTALL) test -z "$(moduledir)" || $(MKDIR_P) "$(DESTDIR)$(moduledir)" @list='$(module_SCRIPTS)'; for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ if test -f $$d$$p; then \ f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \ echo " $(moduleSCRIPT_INSTALL) '$$d$$p' '$(DESTDIR)$(moduledir)/$$f'"; \ $(moduleSCRIPT_INSTALL) "$$d$$p" "$(DESTDIR)$(moduledir)/$$f"; \ else :; fi; \ done uninstall-moduleSCRIPTS: @$(NORMAL_UNINSTALL) @list='$(module_SCRIPTS)'; for p in $$list; do \ f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \ echo " rm -f '$(DESTDIR)$(moduledir)/$$f'"; \ rm -f "$(DESTDIR)$(moduledir)/$$f"; \ done tags: TAGS TAGS: ctags: CTAGS CTAGS: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(SCRIPTS) installdirs: for dir in "$(DESTDIR)$(moduledir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) clean: clean-am clean-am: clean-generic mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am info: info-am info-am: install-data-am: install-data-local install-moduleSCRIPTS install-dvi: install-dvi-am install-exec-am: install-html: install-html-am install-info: install-info-am install-man: install-pdf: install-pdf-am install-ps: install-ps-am installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-local uninstall-moduleSCRIPTS .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic distclean \ distclean-generic distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am \ install-data-local install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-moduleSCRIPTS install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ pdf-am ps ps-am uninstall uninstall-am uninstall-local \ uninstall-moduleSCRIPTS dnl SOURCES_BUILD += $(top_srcdir)/src/AssemblyInfo.cs all: $(ASSEMBLY_FILE) theme-icons run: @pushd $(top_builddir); \ make run; \ popd; test: @pushd $(top_builddir)/tests; \ make $(ASSEMBLY); \ popd; build-debug: @echo $(DEP_LINK) $(ASSEMBLY_FILE).mdb: $(ASSEMBLY_FILE) $(ASSEMBLY_FILE): $(SOURCES_BUILD) $(RESOURCES_EXPANDED) $(DEP_LINK) @mkdir -p $(top_builddir)/bin @if [ ! "x$(ENABLE_RELEASE)" = "xyes" ]; then \ $(top_srcdir)/build/dll-map-makefile-verifier $(srcdir)/Makefile.am $(srcdir)/$(notdir $@.config) && \ $(MONO) $(top_builddir)/build/dll-map-verifier.exe $(srcdir)/$(notdir $@.config) -iwinmm -ilibbanshee -ilibbnpx11 -ilibc -ilibc.so.6 -iintl -ilibmtp.dll -ilibigemacintegration.dylib -iCFRelease $(SOURCES_BUILD); \ fi; $(MCS) \ $(GMCS_FLAGS) \ $(ASSEMBLY_BUILD_FLAGS) \ -nowarn:0278 -nowarn:0078 $$warn \ -define:HAVE_GTK_2_10 -define:NET_2_0 \ -debug -target:$(TARGET) -out:$@ \ $(BUILD_DEFINES) $(ENABLE_TESTS_FLAG) $(ENABLE_ATK_FLAG) \ $(FILTERED_LINK) $(RESOURCES_BUILD) $(SOURCES_BUILD) @if [ -e $(srcdir)/$(notdir $@.config) ]; then \ cp $(srcdir)/$(notdir $@.config) $(top_builddir)/bin; \ fi; @if [ ! -z "$(EXTRA_BUNDLE)" ]; then \ cp $(EXTRA_BUNDLE) $(top_builddir)/bin; \ fi; theme-icons: $(THEME_ICONS_SOURCE) @$(INSTALL_ICONS) -il "$(BUILD_DATA_DIR)" "$(srcdir)" $(THEME_ICONS_RELATIVE) install-data-local: $(THEME_ICONS_SOURCE) @$(INSTALL_ICONS) -i "$(DESTDIR)$(pkgdatadir)" "$(srcdir)" $(THEME_ICONS_RELATIVE) uninstall-local: $(THEME_ICONS_SOURCE) @$(INSTALL_ICONS) -u "$(DESTDIR)$(pkgdatadir)" "$(srcdir)" $(THEME_ICONS_RELATIVE) # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: hyena-0.5/Hyena.Data.Sqlite/Makefile.am0000644000175000001440000000207411416417225020015 0ustar00gabeusers00000000000000ASSEMBLY = Hyena.Data.Sqlite TARGET = library LINK = -r:Mono.Posix -r:System -r:System.Core -r:System.Data \ -r:$(DIR_BIN)/Mono.Data.Sqlite.dll \ -r:$(DIR_BIN)/Hyena.dll SOURCES = \ Hyena.Data.Sqlite/DatabaseColumn.cs \ Hyena.Data.Sqlite/DatabaseColumnAttribute.cs \ Hyena.Data.Sqlite/HyenaSqliteArrayDataReader.cs \ Hyena.Data.Sqlite/HyenaSqliteCommand.cs \ Hyena.Data.Sqlite/HyenaSqliteConnection.cs \ Hyena.Data.Sqlite/ICacheableDatabaseModel.cs \ Hyena.Data.Sqlite/SqliteModelCache.cs \ Hyena.Data.Sqlite/SqliteModelProvider.cs \ Hyena.Data.Sqlite/SqliteUtils.cs \ Hyena.Data.Sqlite/Tests/DbBoundType.cs \ Hyena.Data.Sqlite/Tests/SqliteCommandTests.cs \ Hyena.Data.Sqlite/Tests/SqliteModelProviderTests.cs \ Hyena.Data.Sqlite/Tests/SqliteUtilTests.cs \ Hyena.Metrics/DbSampleStore.cs \ Hyena.Metrics/HttpPoster.cs \ Hyena.Metrics/ISampleStore.cs \ Hyena.Metrics/MemorySampleStore.cs \ Hyena.Metrics/Metric.cs \ Hyena.Metrics/MetricsCollection.cs \ Hyena.Metrics/Sample.cs \ Hyena.Metrics/Tests/MetricsTests.cs include $(top_srcdir)/build/build.mk hyena-0.5/Hyena.Data.Sqlite/Hyena.Metrics/0000777000175000001440000000000011453151002020420 5ustar00gabeusers00000000000000hyena-0.5/Hyena.Data.Sqlite/Hyena.Metrics/MemorySampleStore.cs0000644000175000001440000000337111377073567024426 0ustar00gabeusers00000000000000// // MemorySampleStore.cs // // Author: // Gabriel Burt // // Copyright (c) 2010 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. using System; using System.Collections.Generic; namespace Hyena.Metrics { public class MemorySampleStore : Dictionary>, ISampleStore { public MemorySampleStore () { } public void Add (Sample sample) { if (!ContainsKey (sample.MetricName)) { this[sample.MetricName] = new List (); } this[sample.MetricName].Add (sample); } public IEnumerable GetFor (Metric metric) { return this[metric.Name]; } } } hyena-0.5/Hyena.Data.Sqlite/Hyena.Metrics/ISampleStore.cs0000644000175000001440000000262111377101256023326 0ustar00gabeusers00000000000000// // ISampleStore.cs // // Author: // Gabriel Burt // // Copyright (c) 2010 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. using System; using System.Collections.Generic; namespace Hyena.Metrics { public interface ISampleStore { void Add (Sample sample); IEnumerable GetFor (Metric metric); void Clear (); } } hyena-0.5/Hyena.Data.Sqlite/Hyena.Metrics/Sample.cs0000644000175000001440000000426211377101133022175 0ustar00gabeusers00000000000000// // Sample.cs // // Author: // Gabriel Burt // // Copyright (c) 2010 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. using System; using Hyena.Data.Sqlite; namespace Hyena.Metrics { public class Sample { [DatabaseColumn (Constraints = DatabaseColumnConstraints.PrimaryKey)] protected long Id { get; set; } [DatabaseColumn] public string MetricName { get; protected set; } [DatabaseColumn] public DateTime Stamp { get; protected set; } [DatabaseColumn] public string Value { get; protected set; } // For SqliteModelProvider's use public Sample () {} public Sample (Metric metric, object value) { MetricName = metric.Name; Stamp = DateTime.Now; SetValue (value); } protected void SetValue (object value) { if (value == null) { Value = ""; } else if (value is DateTime) { Value = Hyena.DateTimeUtil.ToInvariantString ((DateTime) value); } else { Value = value.ToString (); } } } }hyena-0.5/Hyena.Data.Sqlite/Hyena.Metrics/Tests/0000777000175000001440000000000011453151002021522 5ustar00gabeusers00000000000000hyena-0.5/Hyena.Data.Sqlite/Hyena.Metrics/Tests/MetricsTests.cs0000644000175000001440000000514211377073567024530 0ustar00gabeusers00000000000000// // MetricsTests.cs // // Author: // Gabriel Burt // // Copyright (C) 2010 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // #if ENABLE_TESTS using System; using System.Linq; using System.IO; using NUnit.Framework; using Hyena; using Hyena.Json; using Hyena.Metrics; namespace Hyena.Tests { [TestFixture] public class MetricsTests { [Test] public void MetricsCollection () { string id = "myuniqueid"; var metrics = new MetricsCollection (id, new MemorySampleStore ()); Assert.AreEqual ("myuniqueid", metrics.AnonymousUserId); metrics.AddDefaults (); Assert.IsTrue (metrics.Count > 0); string metrics_str = metrics.ToJsonString (); Assert.IsTrue (metrics_str.Contains ("\"ID\":\"myuniqueid\"")); // tests/Makefile.am runs the tests with Locale=it_IT Assert.IsTrue (metrics_str.Contains ("it-IT")); // Make sure DateTime samples are saved as invariant strings var now = DateTime.Now; var time_metric = metrics.Add ("Foo", now); Assert.AreEqual (Hyena.DateTimeUtil.ToInvariantString (now), metrics.Store.GetFor (time_metric).First ().Value); // Make sure we can read the JSON back in var ds = new Json.Deserializer (); ds.SetInput (metrics.ToJsonString ()); var json_obj = ds.Deserialize () as JsonObject; Assert.AreEqual (id, json_obj["ID"]); Assert.IsTrue (json_obj["Metrics"] is JsonObject); } } } #endif hyena-0.5/Hyena.Data.Sqlite/Hyena.Metrics/HttpPoster.cs0000644000175000001440000000527211415712051023072 0ustar00gabeusers00000000000000// // HttpPoster.cs // // Author: // Gabriel Burt // // Copyright (c) 2010 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. using System; using System.IO; using System.Net; namespace Hyena.Metrics { public class HttpPoster { private string url; private MetricsCollection metrics; public HttpPoster (string url, MetricsCollection metrics) { this.url = url; this.metrics = metrics; // Sending the Expect header causes lighttpd to fail with a 417 header. ServicePointManager.Expect100Continue = false; } public bool Post () { var request = (HttpWebRequest) WebRequest.Create (url); request.Timeout = 30 * 1000; request.Method = "POST"; request.KeepAlive = false; request.ContentType = "text/json"; request.AllowAutoRedirect = true; try { using (var stream = request.GetRequestStream ()) { using (var writer = new StreamWriter (stream)) { // TODO gzip the data writer.Write (metrics.ToJsonString ()); } } var response = (HttpWebResponse) request.GetResponse (); using (var strm = new StreamReader (response.GetResponseStream ())) { Console.WriteLine (strm.ReadToEnd ()); } return response.StatusCode == HttpStatusCode.OK; } catch (Exception e) { Log.Exception ("Error posting metrics", e); } return false; } } } hyena-0.5/Hyena.Data.Sqlite/Hyena.Metrics/MetricsCollection.cs0000644000175000001440000000747411377073567024431 0ustar00gabeusers00000000000000// // MetricsCollection.cs // // Author: // Gabriel Burt // // Copyright (c) 2010 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. using System; using System.Linq; using System.Collections.Generic; using System.Text; using System.Reflection; using Hyena; using Hyena.Json; namespace Hyena.Metrics { public sealed class MetricsCollection : List, IDisposable { public static readonly int FormatVersion = 1; public string AnonymousUserId { get; private set; } public ISampleStore Store { get; private set; } public MetricsCollection (string uniqueUserId, ISampleStore store) { AnonymousUserId = uniqueUserId; Store = store; } public Metric Add (string name) { return Add (new Metric (name, Store)); } public Metric Add (string name, object value) { return Add (new Metric (name, Store, value)); } public Metric Add (string name, Func sampleFunc) { return Add (new Metric (name, Store, sampleFunc)); } public new Metric Add (Metric metric) { base.Add (metric); return metric; } public void Dispose () { foreach (var m in this) { m.Dispose (); } Clear (); } public string ToJsonString () { var report = new Dictionary (); report["ID"] = AnonymousUserId; report["Now"] = DateTimeUtil.ToInvariantString (DateTime.Now); report["FormatVersion"] = FormatVersion; var metrics = new Dictionary (); foreach (var metric in this.OrderBy (m => m.Name)) { metrics[metric.Name] = Store.GetFor (metric).Select (s => new object [] { DateTimeUtil.ToInvariantString (s.Stamp), s.Value ?? "" }); } report["Metrics"] = metrics; return new Serializer (report).Serialize (); } public void AddDefaults () { Add ("Env/OS Platform", PlatformDetection.SystemName); Add ("Env/OS Version", System.Environment.OSVersion); Add ("Env/Processor Count", System.Environment.ProcessorCount); Add ("Env/.NET Runtime Version", System.Environment.Version); Add ("Env/Debugging", ApplicationContext.Debugging); Add ("Env/CultureInfo", System.Globalization.CultureInfo.CurrentCulture.Name); foreach (var asm in AppDomain.CurrentDomain.GetAssemblies ()) { var name = asm.GetName (); Add (String.Format ("Assemblies/{0}", name.Name), name.Version); } } } }hyena-0.5/Hyena.Data.Sqlite/Hyena.Metrics/DbSampleStore.cs0000644000175000001440000000365211377073567023505 0ustar00gabeusers00000000000000// // DbSampleStore.cs // // Author: // Gabriel Burt // // Copyright (c) 2010 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. using System; using Hyena.Data.Sqlite; using System.Collections.Generic; namespace Hyena.Metrics { public class DbSampleStore : SqliteModelProvider, ISampleStore { private HyenaSqliteConnection conn; public DbSampleStore (HyenaSqliteConnection conn, string tableName) : base(conn, tableName, true) { this.conn = conn; } public void Add (Sample sample) { Save (sample); } public IEnumerable GetFor (Metric metric) { return FetchAllMatching ("MetricName = ? ORDER BY Stamp ASC", metric.Name); } public void Clear () { conn.Execute (String.Format ("DELETE FROM {0}", TableName)); } } } hyena-0.5/Hyena.Data.Sqlite/Hyena.Metrics/Metric.cs0000644000175000001440000000526111377101121022174 0ustar00gabeusers00000000000000// // Metric.cs // // Author: // Gabriel Burt // // Copyright (c) 2010 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. using System; using System.Collections.Generic; using System.Reflection; namespace Hyena.Metrics { public sealed class Metric : IDisposable { public string Name { get; private set; } public bool CanTakeSample { get { return sample_func != null; } } private ISampleStore store; private Func sample_func; internal Metric (string name, ISampleStore store) { Name = name; this.store = store; } internal Metric (string name, ISampleStore store, Func sampleFunc) : this (name, store) { sample_func = sampleFunc; } internal Metric (string name, ISampleStore store, object value) : this (name, store) { PushSample (value); } public void Dispose () { } public void PushSample (object sampleValue) { try { store.Add (new Sample (this, sampleValue)); } catch (Exception e) { Log.Exception ("Error taking sample", e); } } public void TakeSample () { if (sample_func == null) { Log.Warning ("sampleFunc is null. Are you calling TakeSample on a non-event-driven metric?"); return; } try { store.Add (new Sample (this, sample_func ())); } catch (Exception e) { Log.Exception ("Error taking sample", e); } } } } hyena-0.5/Hyena.Data.Sqlite/Hyena.Data.Sqlite/0000777000175000001440000000000011453151002021123 5ustar00gabeusers00000000000000hyena-0.5/Hyena.Data.Sqlite/Hyena.Data.Sqlite/DatabaseColumnAttribute.cs0000644000175000001440000000722711377105536026244 0ustar00gabeusers00000000000000// // DatabaseColumnAttribute.cs // // Author: // Scott Peterson // // Copyright (C) 2007 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Collections.Generic; using System.Data; using System.Reflection; using System.Text; namespace Hyena.Data.Sqlite { [Flags] public enum DatabaseColumnConstraints { NotNull = 1, PrimaryKey = 2, Unique = 4 } public abstract class AbstractDatabaseColumnAttribute : Attribute { private string column_name; private bool select = true; public AbstractDatabaseColumnAttribute () { } public AbstractDatabaseColumnAttribute (string column_name) { this.column_name = column_name; } public string ColumnName { get { return column_name; } } public bool Select { get { return select; } set { select = value; } } } [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)] public sealed class DatabaseColumnAttribute : AbstractDatabaseColumnAttribute { private DatabaseColumnConstraints contraints; private string default_value; private string index; public DatabaseColumnAttribute () { } public DatabaseColumnAttribute (string column_name) : base (column_name) { } public DatabaseColumnConstraints Constraints { get { return contraints; } set { contraints = value; } } public string DefaultValue { get { return default_value; } set { default_value = value; } } public string Index { get { return index; } set { index = value; } } } [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)] public sealed class VirtualDatabaseColumnAttribute : AbstractDatabaseColumnAttribute { private string target_table; private string local_key; private string foreign_key; public VirtualDatabaseColumnAttribute (string column_name, string target_table, string local_key, string foreign_key) : base (column_name) { this.target_table = target_table; this.local_key = local_key; this.foreign_key = foreign_key; } public string TargetTable { get { return target_table; } } public string LocalKey { get { return local_key; } } public string ForeignKey { get { return foreign_key; } } } } hyena-0.5/Hyena.Data.Sqlite/Hyena.Data.Sqlite/Tests/0000777000175000001440000000000011453151002022225 5ustar00gabeusers00000000000000hyena-0.5/Hyena.Data.Sqlite/Hyena.Data.Sqlite/Tests/SqliteUtilTests.cs0000644000175000001440000000527511377105536025723 0ustar00gabeusers00000000000000// // SqliteUtilTests.cs // // Author: // John Millikin // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // #if ENABLE_TESTS using NUnit.Framework; using Hyena.Data.Sqlite; namespace Hyena.Data.Sqlite.Tests { [TestFixture] public class CollationKeyTests { protected void CollationKeyTest (object before, object after) { Assert.AreEqual (after, (new CollationKeyFunction ()).Invoke (new object[] {before})); } [Test] public void TestNull () { CollationKeyTest (null, null); CollationKeyTest (System.DBNull.Value, null); } [Test] public void TestKey () { // See Hyena.StringUtil.Tests for full tests. This just checks that // the collation function is actually being used. CollationKeyTest ("", new byte[] {1, 1, 1, 1, 0}); CollationKeyTest ("\u0104", new byte[] {14, 2, 1, 27, 1, 1, 1, 0}); } } [TestFixture] public class SearchKeyTests { protected void SearchKeyTest (object before, object after) { Assert.AreEqual (after, (new SearchKeyFunction ()).Invoke (new object[] {before})); } [Test] public void TestNull () { SearchKeyTest (null, null); SearchKeyTest (System.DBNull.Value, null); } [Test] public void TestKey () { // See Hyena.StringUtil.Tests for full tests. This just checks that // the search key function is actually being used. SearchKeyTest ("", ""); SearchKeyTest ("\u0104", "a"); } } } #endif hyena-0.5/Hyena.Data.Sqlite/Hyena.Data.Sqlite/Tests/DbBoundType.cs0000644000175000001440000002531511377105536024755 0ustar00gabeusers00000000000000// // DbBoundType.cs // // Author: // Scott Peterson // // Copyright (C) 2008 Scott Peterson // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // #if ENABLE_TESTS using System; using Hyena.Data.Sqlite; namespace Hyena.Data.Sqlite.Tests { internal enum IntEnum : int { Zero, One, Two, Three } internal enum LongEnum : long { Cero, Uno, Dos, Tres } internal class ModelProvider : SqliteModelProvider { public ModelProvider (HyenaSqliteConnection connection) : base (connection) { Init (); } public override string TableName { get { return "TestTable"; } } protected override int ModelVersion { get { return 1; } } protected override int DatabaseVersion { get { return 1; } } protected override void MigrateTable (int old_version) { } protected override void MigrateDatabase (int old_version) { } protected override DbBoundType MakeNewObject () { return new DbBoundType (); } } internal class DbBoundType { [DatabaseColumn ("PrimaryKey", Constraints = DatabaseColumnConstraints.PrimaryKey)] public int PrimaryKey; [DatabaseColumn ("PublicIntField")] public int PublicIntField; [DatabaseColumn ("PublicLongField")] public long PublicLongField; [DatabaseColumn ("PublicStringField")] public string PublicStringField; [DatabaseColumn ("PublicDateTimeField")] public DateTime PublicDateTimeField; [DatabaseColumn ("PublicTimeSpanField")] public TimeSpan PublicTimeSpanField; [DatabaseColumn ("PublicIntEnumField")] public IntEnum PublicIntEnumField; [DatabaseColumn ("PublicLongEnumField")] public LongEnum PublicLongEnumField; private int public_int_property_field; [DatabaseColumn ("PublicIntProperty")] public int PublicIntProperty { get { return public_int_property_field; } set { public_int_property_field = value; } } private long public_long_property_field; [DatabaseColumn ("PublicLongProperty")] public long PublicLongProperty { get { return public_long_property_field; } set { public_long_property_field = value; } } private string public_string_property_field; [DatabaseColumn ("PublicStringProperty")] public string PublicStringProperty { get { return public_string_property_field; } set { public_string_property_field = value; } } private DateTime public_date_time_proprety_field; [DatabaseColumn ("PublicDateTimeProperty")] public DateTime PublicDateTimeProperty { get { return public_date_time_proprety_field; } set { public_date_time_proprety_field = value; } } private TimeSpan public_time_span_property_field; [DatabaseColumn ("PublicTimeSpanProperty")] public TimeSpan PublicTimeSpanProperty { get { return public_time_span_property_field; } set { public_time_span_property_field = value; } } private IntEnum public_int_enum_property_field; [DatabaseColumn ("PublicIntEnumProperty")] public IntEnum PublicIntEnumProperty { get { return public_int_enum_property_field; } set { public_int_enum_property_field = value; } } private LongEnum public_long_enum_property_field; [DatabaseColumn ("PublicLongEnumProperty")] public LongEnum PublicLongEnumProperty { get { return public_long_enum_property_field; } set { public_long_enum_property_field = value; } } [DatabaseColumn ("PrivateIntField")] private int private_int_field; [DatabaseColumn ("PrivateLongField")] private long private_long_field; [DatabaseColumn ("PrivateStringField")] private string private_string_field; [DatabaseColumn ("PrivateDateTimeField")] private DateTime private_date_time_field; [DatabaseColumn ("PrivateTimeSpanField")] private TimeSpan private_time_span_field; [DatabaseColumn ("PrivateIntEnumField")] private IntEnum private_int_enum_field; [DatabaseColumn ("PrivateLongEnumField")] private LongEnum private_long_enum_field; public int GetPrivateIntField () { return private_int_field; } public void SetPrivateIntField (int value) { private_int_field = value; } public long GetPrivateLongField () { return private_long_field; } public void SetPrivateLongField (long value) { private_long_field = value; } public string GetPrivateStringField () { return private_string_field; } public void SetPrivateStringField (string value) { private_string_field = value; } public DateTime GetPrivateDateTimeField () { return private_date_time_field; } public void SetPrivateDateTimeField (DateTime value) { private_date_time_field = value; } public TimeSpan GetPrivateTimeSpanField () { return private_time_span_field; } public void SetPrivateTimeSpanField (TimeSpan value) { private_time_span_field = value; } public IntEnum GetPrivateIntEnumField () { return private_int_enum_field; } public void SetPrivateIntEnumField (IntEnum value) { private_int_enum_field = value; } public LongEnum GetPrivateLongEnumField () { return private_long_enum_field; } public void SetPrivateLongEnumField (LongEnum value) { private_long_enum_field = value; } private int private_int_property_field; [DatabaseColumn ("PrivateIntProperty")] private int private_int_property { get { return private_int_property_field; } set { private_int_property_field = value; } } private long private_long_property_field; [DatabaseColumn ("PrivateLongProperty")] private long private_long_property { get { return private_long_property_field; } set { private_long_property_field = value; } } private string private_string_property_field; [DatabaseColumn ("PrivateStringProperty")] private string private_string_property { get { return private_string_property_field; } set { private_string_property_field = value; } } private DateTime private_date_time_property_field; [DatabaseColumn ("PrivateDateTimeProperty")] private DateTime private_date_time_property { get { return private_date_time_property_field; } set { private_date_time_property_field = value; } } private TimeSpan private_time_span_property_field; [DatabaseColumn ("PrivateTimeSpanProperty")] private TimeSpan private_time_span_property { get { return private_time_span_property_field; } set { private_time_span_property_field = value; } } private IntEnum private_int_enum_property_field; [DatabaseColumn ("PrivateIntEnumProperty")] private IntEnum private_int_enum_property { get { return private_int_enum_property_field; } set { private_int_enum_property_field = value; } } private LongEnum private_long_enum_property_field; [DatabaseColumn ("PrivateLongEnumProperty")] private LongEnum private_long_enum_property { get { return private_long_enum_property_field; } set { private_long_enum_property_field = value; } } public int GetPrivateIntProperty () { return private_int_property; } public void SetPrivateIntProperty (int value) { private_int_property = value; } public long GetPrivateLongProperty () { return private_long_property; } public void SetPrivateLongProperty (long value) { private_long_property = value; } public string GetPrivateStringProperty () { return private_string_property; } public void SetPrivateStringProperty (string value) { private_string_property = value; } public DateTime GetPrivateDateTimeProperty () { return private_date_time_property; } public void SetPrivateDateTimeProperty (DateTime value) { private_date_time_property = value; } public TimeSpan GetPrivateTimeSpanProperty () { return private_time_span_property; } public void SetPrivateTimeSpanProperty (TimeSpan value) { private_time_span_property = value; } public IntEnum GetPrivateIntEnumProperty () { return private_int_enum_property; } public void SetPrivateIntEnumProperty (IntEnum value) { private_int_enum_property = value; } public LongEnum GetPrivateLongEnumProperty () { return private_long_enum_property; } public void SetPrivateLongEnumProperty (LongEnum value) { private_long_enum_property = value; } } } #endif hyena-0.5/Hyena.Data.Sqlite/Hyena.Data.Sqlite/Tests/SqliteModelProviderTests.cs0000644000175000001440000002576411377105536027566 0ustar00gabeusers00000000000000// // SqliteModelProviderTests.cs // // Author: // Scott Peterson // // Copyright (C) 2008 Scott Peterson // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // #if ENABLE_TESTS using System; using System.Data; using System.IO; using NUnit.Framework; using Hyena.Data.Sqlite; namespace Hyena.Data.Sqlite.Tests { [TestFixture] public class SqliteModelProviderTests { private HyenaSqliteConnection connection; private ModelProvider provider; [TestFixtureSetUp] public void Init () { connection = new HyenaSqliteConnection ("test.db"); provider = new ModelProvider (connection); } [TestFixtureTearDown] public void Dispose () { connection.Dispose (); File.Delete ("test.db"); } [Test] public void IntMembers () { DbBoundType newed_item = new DbBoundType (); newed_item.PublicIntField = 3141592; newed_item.PublicIntProperty = 13; newed_item.SetPrivateIntField (128); newed_item.SetPrivateIntProperty (42); provider.Save (newed_item); DbBoundType loaded_item = provider.FetchSingle (newed_item.PrimaryKey); Assert.AreEqual (newed_item.PublicIntField, loaded_item.PublicIntField); Assert.AreEqual (newed_item.PublicIntProperty, loaded_item.PublicIntProperty); Assert.AreEqual (newed_item.GetPrivateIntField (), loaded_item.GetPrivateIntField ()); Assert.AreEqual (newed_item.GetPrivateIntProperty (), loaded_item.GetPrivateIntProperty ()); } [Test] public void LongMembers () { DbBoundType newed_item = new DbBoundType (); newed_item.PublicLongField = 4926227057; newed_item.PublicLongProperty = -932; newed_item.SetPrivateLongField (3243); newed_item.SetPrivateLongProperty (1); provider.Save (newed_item); DbBoundType loaded_item = provider.FetchSingle (newed_item.PrimaryKey); Assert.AreEqual (newed_item.PublicLongField, loaded_item.PublicLongField); Assert.AreEqual (newed_item.PublicLongProperty, loaded_item.PublicLongProperty); Assert.AreEqual (newed_item.GetPrivateLongField (), loaded_item.GetPrivateLongField ()); Assert.AreEqual (newed_item.GetPrivateLongProperty (), loaded_item.GetPrivateLongProperty ()); } [Test] public void StringMembers () { DbBoundType newed_item = new DbBoundType (); newed_item.PublicStringField = "Surely you're joking, Mr. Feynman."; newed_item.PublicStringProperty = "Even as a splitted bark, so sunder we: This way fall I to death."; newed_item.SetPrivateStringField ("Who is John Galt?"); newed_item.SetPrivateStringProperty ("The most formidable weapon against errors of every kind is Reason."); provider.Save (newed_item); DbBoundType loaded_item = provider.FetchSingle (newed_item.PrimaryKey); Assert.AreEqual (newed_item.PublicStringField, loaded_item.PublicStringField); Assert.AreEqual (newed_item.PublicStringProperty, loaded_item.PublicStringProperty); Assert.AreEqual (newed_item.GetPrivateStringField (), loaded_item.GetPrivateStringField ()); Assert.AreEqual (newed_item.GetPrivateStringProperty (), loaded_item.GetPrivateStringProperty ()); } [Test] public void BlankStringMembers () { DbBoundType newed_item = new DbBoundType (); newed_item.PublicStringField = ""; newed_item.PublicStringProperty = null; newed_item.SetPrivateStringField (" \t "); newed_item.SetPrivateStringProperty (" foo "); provider.Save (newed_item); DbBoundType loaded_item = provider.FetchSingle (newed_item.PrimaryKey); Assert.AreEqual (null, loaded_item.PublicStringField); Assert.AreEqual (null, loaded_item.PublicStringProperty); Assert.AreEqual (null, loaded_item.GetPrivateStringField ()); Assert.AreEqual (" foo ", loaded_item.GetPrivateStringProperty ()); } [Test] public void NullStringMembers () { DbBoundType newed_item = new DbBoundType (); newed_item.PublicStringField = null; newed_item.PublicStringProperty = null; newed_item.SetPrivateStringField (null); newed_item.SetPrivateStringProperty (null); provider.Save (newed_item); DbBoundType loaded_item = provider.FetchSingle (newed_item.PrimaryKey); Assert.AreEqual (newed_item.PublicStringField, loaded_item.PublicStringField); Assert.AreEqual (newed_item.PublicStringProperty, loaded_item.PublicStringProperty); Assert.AreEqual (newed_item.GetPrivateStringField (), loaded_item.GetPrivateStringField ()); Assert.AreEqual (newed_item.GetPrivateStringProperty (), loaded_item.GetPrivateStringProperty ()); } // Some fidelity is lost in the conversion from DT to DB time format private void AssertArePrettyClose (DateTime time1, DateTime time2) { Assert.AreEqual (time1.Year, time2.Year); Assert.AreEqual (time1.Month, time2.Month); Assert.AreEqual (time1.Day, time2.Day); Assert.AreEqual (time1.Hour, time2.Hour); Assert.AreEqual (time1.Minute, time2.Minute); Assert.AreEqual (time1.Second, time2.Second); } [Test] public void DateTimeMembers () { DbBoundType newed_item = new DbBoundType (); newed_item.PublicDateTimeField = DateTime.Now; newed_item.PublicDateTimeProperty = new DateTime (1986, 4, 23); newed_item.SetPrivateDateTimeField (DateTime.MinValue); newed_item.SetPrivateDateTimeProperty (DateTime.Now); provider.Save (newed_item); string command = String.Format ("SELECT PrivateDateTimeField FROM {0} WHERE PrimaryKey = {1}", provider.TableName, newed_item.PrimaryKey); using (IDataReader reader = connection.Query (command)) { reader.Read (); Assert.IsTrue (reader.IsDBNull (0)); } DbBoundType loaded_item = provider.FetchSingle (newed_item.PrimaryKey); AssertArePrettyClose (newed_item.PublicDateTimeField, loaded_item.PublicDateTimeField); AssertArePrettyClose (newed_item.PublicDateTimeProperty, loaded_item.PublicDateTimeProperty); AssertArePrettyClose (newed_item.GetPrivateDateTimeField (), loaded_item.GetPrivateDateTimeField ()); AssertArePrettyClose (newed_item.GetPrivateDateTimeProperty (), loaded_item.GetPrivateDateTimeProperty ()); } [Test] public void TimeSpanMembers () { DbBoundType newed_item = new DbBoundType (); newed_item.PublicTimeSpanField = new TimeSpan (0, 0, 1); newed_item.PublicTimeSpanProperty = new TimeSpan (1, 0, 0); newed_item.SetPrivateTimeSpanField (new TimeSpan (1, 39, 12)); newed_item.SetPrivateTimeSpanProperty (TimeSpan.MinValue); provider.Save (newed_item); string command = String.Format ("SELECT PrivateTimeSpanProperty FROM {0} WHERE PrimaryKey = {1}", provider.TableName, newed_item.PrimaryKey); using (IDataReader reader = connection.Query (command)) { reader.Read (); Assert.IsTrue (reader.IsDBNull (0)); } // NUnit boxes and uses reference equality, rather than Equals() DbBoundType loaded_item = provider.FetchSingle (newed_item.PrimaryKey); Assert.AreEqual (newed_item.PublicTimeSpanField, loaded_item.PublicTimeSpanField); Assert.AreEqual (newed_item.PublicTimeSpanProperty, loaded_item.PublicTimeSpanProperty); Assert.AreEqual (newed_item.GetPrivateTimeSpanField (), loaded_item.GetPrivateTimeSpanField ()); Assert.AreEqual (newed_item.GetPrivateTimeSpanProperty (), loaded_item.GetPrivateTimeSpanProperty ()); } [Test] public void IntEnumMembers () { DbBoundType newed_item = new DbBoundType (); newed_item.PublicIntEnumField = IntEnum.Zero; newed_item.PublicIntEnumProperty = IntEnum.One; newed_item.SetPrivateIntEnumField (IntEnum.Two); newed_item.SetPrivateIntEnumProperty (IntEnum.Three); provider.Save (newed_item); DbBoundType loaded_item = provider.FetchSingle (newed_item.PrimaryKey); Assert.AreEqual (newed_item.PublicIntEnumField, loaded_item.PublicIntEnumField); Assert.AreEqual (newed_item.PublicIntEnumProperty, loaded_item.PublicIntEnumProperty); Assert.AreEqual (newed_item.GetPrivateIntEnumField (), loaded_item.GetPrivateIntEnumField ()); Assert.AreEqual (newed_item.GetPrivateIntEnumProperty (), loaded_item.GetPrivateIntEnumProperty ()); } [Test] public void LongEnumMembers () { DbBoundType newed_item = new DbBoundType (); newed_item.PublicLongEnumField = LongEnum.Cero; newed_item.PublicLongEnumProperty = LongEnum.Uno; newed_item.SetPrivateLongEnumField (LongEnum.Dos); newed_item.SetPrivateLongEnumProperty (LongEnum.Tres); provider.Save (newed_item); DbBoundType loaded_item = provider.FetchSingle (newed_item.PrimaryKey); Assert.AreEqual (newed_item.PublicLongEnumField, loaded_item.PublicLongEnumField); Assert.AreEqual (newed_item.PublicLongEnumProperty, loaded_item.PublicLongEnumProperty); Assert.AreEqual (newed_item.GetPrivateLongEnumField (), loaded_item.GetPrivateLongEnumField ()); Assert.AreEqual (newed_item.GetPrivateLongEnumProperty (), loaded_item.GetPrivateLongEnumProperty ()); } } } #endif hyena-0.5/Hyena.Data.Sqlite/Hyena.Data.Sqlite/Tests/SqliteCommandTests.cs0000644000175000001440000001566511377105536026370 0ustar00gabeusers00000000000000// // SqliteCommandTests.cs // // Author: // Gabriel Burt // // Copyright (C) 2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // #if ENABLE_TESTS using System; using System.Reflection; using NUnit.Framework; using Hyena.Data.Sqlite; namespace Hyena.Data.Sqlite.Tests { [TestFixture] public class SqliteCommandTests { [Test] public void IdentifiesParameters () { HyenaSqliteCommand cmd = null; try { cmd = new HyenaSqliteCommand ("select foo from bar where baz = ?, bbz = ?, this = ?", "a", 32); Assert.Fail ("Should not have been able to pass 2 values to ApplyValues without exception"); } catch {} try { cmd = new HyenaSqliteCommand ("select foo from bar where baz = ?, bbz = ?, this = ?", "a", 32, "22"); } catch { Assert.Fail ("Should have been able to pass 3 values to ApplyValues without exception"); } Assert.AreEqual ("select foo from bar where baz = 'a', bbz = 32, this = '22'", GetGeneratedSql (cmd)); } [Test] public void Constructor () { HyenaSqliteCommand cmd = new HyenaSqliteCommand ("select foo from bar where baz = ?, bbz = ?, this = ?", "a", 32, "22"); Assert.AreEqual ("select foo from bar where baz = 'a', bbz = 32, this = '22'", GetGeneratedSql (cmd)); } [Test] public void CultureInvariant () { HyenaSqliteCommand cmd = new HyenaSqliteCommand ("select foo from bar where baz = ?", 32.2); Assert.AreEqual ("select foo from bar where baz = 32.2", GetGeneratedSql (cmd)); } [Test] public void ParameterSerialization () { HyenaSqliteCommand cmd = new HyenaSqliteCommand ("select foo from bar where baz = ?"); Assert.AreEqual ("select foo from bar where baz = NULL", GetGeneratedSql (cmd, null)); Assert.AreEqual ("select foo from bar where baz = 'It''s complicated, \"but\" ''''why not''''?'", GetGeneratedSql (cmd, "It's complicated, \"but\" ''why not''?")); Assert.AreEqual ("select foo from bar where baz = 0", GetGeneratedSql (cmd, new DateTime (1970, 1, 1).ToLocalTime ())); Assert.AreEqual ("select foo from bar where baz = 931309200", GetGeneratedSql (cmd, new DateTime (1999, 7, 7).ToLocalTime ())); Assert.AreEqual ("select foo from bar where baz = 555.55", GetGeneratedSql (cmd, 555.55f)); Assert.AreEqual ("select foo from bar where baz = 555.55", GetGeneratedSql (cmd, 555.55)); Assert.AreEqual ("select foo from bar where baz = 555", GetGeneratedSql (cmd, 555)); Assert.AreEqual ("select foo from bar where baz = 1", GetGeneratedSql (cmd, true)); Assert.AreEqual ("select foo from bar where baz = 0", GetGeneratedSql (cmd, false)); HyenaSqliteCommand cmd2 = new HyenaSqliteCommand ("select foo from bar where baz = ?, bar = ?, boo = ?"); Assert.AreEqual ("select foo from bar where baz = NULL, bar = NULL, boo = 22", GetGeneratedSql (cmd2, null, null, 22)); HyenaSqliteCommand cmd3 = new HyenaSqliteCommand ("select foo from bar where id in (?) and foo not in (?)"); Assert.AreEqual ("select foo from bar where id in (1,2,4) and foo not in ('foo','baz')", GetGeneratedSql (cmd3, new int [] {1, 2, 4}, new string [] {"foo", "baz"})); } [Test] public void ExecuteMustDisposeSqliteCommand () { using(var connection = new HyenaSqliteConnection (":memory:")) { bool disposed = false; connection.Executing += delegate (object sender, ExecutingEventArgs args) { args.Command.Disposed += delegate { disposed = true; }; }; connection.Query ("SELECT 42"); Assert.IsTrue (disposed); } } static PropertyInfo tf = typeof(HyenaSqliteCommand).GetProperty ("CurrentSqlText", BindingFlags.Instance | BindingFlags.NonPublic); private static string GetGeneratedSql (HyenaSqliteCommand cmd, params object [] p) { return tf.GetValue ((new HyenaSqliteCommand (cmd.Text, p)), null) as string; } private static string GetGeneratedSql (HyenaSqliteCommand cmd) { return tf.GetValue (cmd, null) as string; } } [TestFixture] public class ObjectToSqlTests { protected void AssertToSql (object o, object expected) { Assert.AreEqual (expected, HyenaSqliteCommand.SqlifyObject (o)); } [Test] public void TestNull () { AssertToSql (null, "NULL"); } [Test] public void TestBool () { AssertToSql (false, "0"); AssertToSql (true, "1"); } [Test] public void TestString () { AssertToSql ("", "''"); AssertToSql ("test", "'test'"); AssertToSql ("te'st", "'te''st'"); } [Test] public void TestByteArray () { // BLOB notation AssertToSql (new byte[] {}, "X''"); AssertToSql (new byte[] {0x10, 0x20, 0x30}, "X'102030'"); } [Test] public void TestOtherArray () { AssertToSql (new object[] {}, ""); AssertToSql (new object[] {"a"}, "'a'"); AssertToSql (new object[] {"a", "b"}, "'a','b'"); } [Test] public void TestDateTime () { // Returned using local time, not UTC AssertToSql (new DateTime (2000, 1, 2), 946792800); // Disregards milliseconds AssertToSql (new DateTime (2000, 1, 2, 10, 9, 8, 7), 946829348); } } } #endif hyena-0.5/Hyena.Data.Sqlite/Hyena.Data.Sqlite/SqliteModelProvider.cs0000644000175000001440000006725111377105536025436 0ustar00gabeusers00000000000000// // SqliteModelProvider.cs // // Author: // Scott Peterson // // Copyright (C) 2007 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Collections.Generic; using System.Data; using System.Reflection; using System.Text; namespace Hyena.Data.Sqlite { public class SqliteModelProvider where T : new () { private readonly List columns = new List (); private readonly List select_columns = new List (); private readonly List virtual_columns = new List (); private DatabaseColumn key; private int key_select_column_index; private HyenaSqliteConnection connection; private bool check_table = true; private HyenaSqliteCommand create_command; private HyenaSqliteCommand insert_command; private HyenaSqliteCommand update_command; private HyenaSqliteCommand delete_command; private HyenaSqliteCommand select_command; private HyenaSqliteCommand select_range_command; private HyenaSqliteCommand select_single_command; private string table_name; private string primary_key; private string select; private string from; private string where; private const string HYENA_DATABASE_NAME = "hyena_database_master"; public virtual string TableName { get { return table_name; } } protected virtual int ModelVersion { get { return 1; } } protected virtual int DatabaseVersion { get { return 1; } } protected virtual void MigrateTable (int old_version) { } protected virtual void MigrateDatabase (int old_version) { } protected virtual T MakeNewObject () { return new T (); } protected virtual string HyenaTableName { get { return "HyenaModelVersions"; } } public HyenaSqliteConnection Connection { get { return connection; } } protected SqliteModelProvider (HyenaSqliteConnection connection) { this.connection = connection; } public SqliteModelProvider (HyenaSqliteConnection connection, string table_name) : this (connection, table_name, true) { } public SqliteModelProvider (HyenaSqliteConnection connection, string table_name, bool checkTable) : this (connection) { this.table_name = table_name; this.check_table = checkTable; Init (); } protected void Init () { foreach (FieldInfo field in typeof(T).GetFields (BindingFlags.Instance | BindingFlags.Public)) { foreach (Attribute attribute in field.GetCustomAttributes (true)) { AddColumn (field, attribute); } } foreach (FieldInfo field in typeof(T).GetFields (BindingFlags.Instance | BindingFlags.NonPublic)) { foreach (Attribute attribute in field.GetCustomAttributes (true)) { AddColumn (field, attribute); } } foreach (PropertyInfo property in typeof(T).GetProperties (BindingFlags.Instance | BindingFlags.Public)) { foreach (Attribute attribute in property.GetCustomAttributes (true)) { AddColumn (property, attribute); } } foreach (PropertyInfo property in typeof(T).GetProperties (BindingFlags.Instance | BindingFlags.NonPublic)) { foreach (Attribute attribute in property.GetCustomAttributes (true)) { AddColumn (property, attribute); } } if (key == null) { throw new Exception (String.Format ("The {0} table does not have a primary key", TableName)); } key_select_column_index = select_columns.IndexOf (key); if (check_table) { CheckVersion (); CheckTable (); } } protected virtual void CheckVersion () { if (connection.TableExists (HyenaTableName)) { using (IDataReader reader = connection.Query (SelectVersionSql (TableName))) { if (reader.Read ()) { int table_version = reader.GetInt32 (0); if (table_version < ModelVersion) { MigrateTable (table_version); UpdateVersion (TableName, ModelVersion); } } else { InsertVersion (TableName, ModelVersion); } } int db_version = connection.Query (SelectVersionSql (HYENA_DATABASE_NAME)); if (db_version < DatabaseVersion) { MigrateDatabase (db_version); UpdateVersion (HYENA_DATABASE_NAME, DatabaseVersion); } } else { connection.Execute (String.Format ( @"CREATE TABLE {0} ( id INTEGER PRIMARY KEY, name TEXT UNIQUE, version INTEGER)", HyenaTableName) ); InsertVersion (HYENA_DATABASE_NAME, DatabaseVersion); InsertVersion (TableName, ModelVersion); } } private string SelectVersionSql (string name) { return String.Format ( "SELECT version FROM {0} WHERE name='{1}'", HyenaTableName, name); } private void UpdateVersion (string name, int version) { connection.Execute (String.Format ( "UPDATE {0} SET version={1} WHERE name='{2}'", HyenaTableName, version, name)); } private void InsertVersion (string name, int version) { connection.Execute (String.Format ( "INSERT INTO {0} (name, version) VALUES ('{1}', {2})", HyenaTableName, name, version)); } protected void CheckTable () { //Console.WriteLine ("In {0} checking for table {1}", this, TableName); IDictionary schema = connection.GetSchema (TableName); if (schema.Count > 0) { foreach (DatabaseColumn column in columns) { if (!schema.ContainsKey (column.Name.ToLower ())) { AddColumnToTable (column.Schema); } if (column.Index != null && !connection.IndexExists (column.Index)) { connection.Execute (String.Format ( "CREATE INDEX {0} ON {1}({2})", column.Index, TableName, column.Name) ); } } } else { CreateTable (); } } private void AddColumn (MemberInfo member, Attribute attribute) { DatabaseColumnAttribute column = attribute as DatabaseColumnAttribute; if (column != null) { DatabaseColumn c = member is FieldInfo ? new DatabaseColumn ((FieldInfo)member, column) : new DatabaseColumn ((PropertyInfo)member, column); AddColumn (c, column.Select); } VirtualDatabaseColumnAttribute virtual_column = attribute as VirtualDatabaseColumnAttribute; if (virtual_column != null) { if (member is FieldInfo) { virtual_columns.Add (new VirtualDatabaseColumn ((FieldInfo) member, virtual_column)); } else { virtual_columns.Add (new VirtualDatabaseColumn ((PropertyInfo) member, virtual_column)); } } } protected void AddColumn (DatabaseColumn c, bool select) { foreach (DatabaseColumn col in columns) { if (col.Name == c.Name) { throw new Exception (String.Format ( "{0} has multiple columns named {1}", TableName, c.Name) ); } if (col.Index != null && col.Index == c.Index) { throw new Exception (String.Format ( "{0} has multiple indecies named {1}", TableName, c.Name) ); } } columns.Add (c); if (select) { select_columns.Add (c); } if ((c.Constraints & DatabaseColumnConstraints.PrimaryKey) > 0) { if (key != null) { throw new Exception (String.Format ( "Multiple primary keys in the {0} table", TableName) ); } key = c; } } protected virtual void CreateTable () { connection.Execute (CreateCommand); foreach (DatabaseColumn column in columns) { if (column.Index != null) { connection.Execute (String.Format ( "CREATE INDEX {0} ON {1}({2})", column.Index, TableName, column.Name) ); } } } protected void CreateIndex (string name, string columns) { Connection.Execute (String.Format ( "CREATE INDEX {0} ON {1} ({2})", name, TableName, columns )); } public virtual void Save (T target, bool force_insert) { try { if (Convert.ToInt32 (key.GetRawValue (target)) > 0 && !force_insert) { Update (target); } else { key.SetValue (target, Insert (target)); } } catch (Exception e) { Hyena.Log.Exception (e); Hyena.Log.DebugFormat ("type of key value: {0}", key.GetRawValue (target).GetType ()); throw; } } public virtual void Save (T target) { Save (target, false); } protected virtual object [] GetInsertParams (T target) { // TODO create an instance variable object array and reuse it? beware threading issues object [] values = new object [columns.Count - 1]; int j = 0; for (int i = 0; i < columns.Count; i++) { if (columns[i] != key) { values[j] = columns[i].GetValue (target); j++; } } return values; } protected int Insert (T target) { return connection.Execute (InsertCommand, GetInsertParams (target)); } protected object [] GetUpdateParams (T target) { // TODO create an instance variable object array and reuse it? beware threading issues object [] values = new object [columns.Count]; int j = 0; for (int i = 0; i < columns.Count; i++) { if (columns[i] != key) { values[j] = columns[i].GetValue (target); j++; } } values[j] = key.GetValue (target); return values; } protected void Update (T target) { connection.Execute (UpdateCommand, GetUpdateParams (target)); } public virtual T Load (IDataReader reader) { T item = MakeNewObject (); Load (reader, item); return item; } public void Load (IDataReader reader, T target) { int i = 0; AbstractDatabaseColumn bad_column = null; try { foreach (DatabaseColumn column in select_columns) { bad_column = column; column.SetValue (target, reader, i++); } foreach (VirtualDatabaseColumn column in virtual_columns) { bad_column = column; column.SetValue (target, reader, i++); } } catch (Exception e) { Log.Debug ( String.Format ("Caught exception trying to load database column {0}", bad_column == null ? "[unknown]" : bad_column.Name), e.ToString () ); } } public IEnumerable FetchAll () { using (IDataReader reader = connection.Query (SelectCommand)) { while (reader.Read ()) { yield return Load (reader); } } } public T FetchFirstMatching (string condition, params object [] vals) { foreach (T item in FetchAllMatching (String.Format ("{0} LIMIT 1", condition), vals)) { return item; } return default(T); } public IEnumerable FetchAllMatching (string condition, params object [] vals) { HyenaSqliteCommand fetch_matching_command = CreateFetchCommand (condition); using (IDataReader reader = connection.Query (fetch_matching_command, vals)) { while (reader.Read ()) { yield return Load (reader); } } } public HyenaSqliteCommand CreateFetchCommand (string condition) { return new HyenaSqliteCommand (String.Format ("{0} AND {1}", SelectCommand.Text, condition)); } public IEnumerable FetchRange (int offset, int limit) { using (IDataReader reader = connection.Query (SelectRangeCommand, offset, limit)) { while (reader.Read ()) { yield return Load (reader); } } } public T FetchSingle (int id) { return FetchSingle ((long) id); } public virtual T FetchSingle (long id) { using (IDataReader reader = connection.Query (SelectSingleCommand, id)) { if (reader.Read ()) { return Load (reader); } } return default(T); } protected long PrimaryKeyFor (T item) { return Convert.ToInt64 (key.GetValue (item)); } protected long PrimaryKeyFor (IDataReader reader) { return Convert.ToInt64 (reader[key_select_column_index]); } public virtual void Delete (long id) { if (id > 0) connection.Execute (DeleteCommand, id); } public void Delete (T item) { Delete (PrimaryKeyFor (item)); } public void Delete (string condition, params object [] vals) { connection.Execute (String.Format ("DELETE FROM {0} WHERE {1}", TableName, condition), vals); } public virtual void Delete (IEnumerable items) { List ids = new List (); long id; foreach (T item in items) { id = PrimaryKeyFor (item); if (id > 0) ids.Add (id); } if (ids.Count > 0) connection.Execute (DeleteCommand, ids.ToArray ()); } public bool Refresh (T item) { if (key == null || item == null) return false; int id = (int) key.GetValue (item); if (id < 1) return false; using (IDataReader reader = connection.Query (SelectSingleCommand, id)) { if (reader.Read ()) { Load (reader, item); return true; } } return false; } public void Copy (T original, T copy) { foreach (DatabaseColumn column in select_columns) { if (column != key) { column.SetValue (copy, column.GetRawValue (original)); } } foreach (var column in virtual_columns) { column.SetValue (copy, column.GetRawValue (original)); } } protected virtual HyenaSqliteCommand CreateCommand { get { if (create_command == null) { StringBuilder builder = new StringBuilder (); builder.Append ("CREATE TABLE "); builder.Append (TableName); builder.Append ('('); bool first = true; foreach (DatabaseColumn column in columns) { if (first) { first = false; } else { builder.Append (','); } builder.Append (column.Schema); } builder.Append (')'); create_command = new HyenaSqliteCommand (builder.ToString ()); } return create_command; } } protected virtual HyenaSqliteCommand InsertCommand { get { // FIXME can this string building be done more nicely? if (insert_command == null) { StringBuilder cols = new StringBuilder (); StringBuilder vals = new StringBuilder (); bool first = true; foreach (DatabaseColumn column in columns) { if (column != key) { if (first) { first = false; } else { cols.Append (','); vals.Append (','); } cols.Append (column.Name); vals.Append ('?'); } } insert_command = new HyenaSqliteCommand (String.Format ( "INSERT INTO {0} ({1}) VALUES ({2})", TableName, cols.ToString (), vals.ToString ()) ); } return insert_command; } } protected virtual HyenaSqliteCommand UpdateCommand { get { if (update_command == null) { StringBuilder builder = new StringBuilder (); builder.Append ("UPDATE "); builder.Append (TableName); builder.Append (" SET "); bool first = true; foreach (DatabaseColumn column in columns) { if (column != key) { if (first) { first = false; } else { builder.Append (','); } builder.Append (column.Name); builder.Append (" = ?"); } } builder.Append (" WHERE "); builder.Append (key.Name); builder.Append (" = ?"); update_command = new HyenaSqliteCommand (builder.ToString ()); } return update_command; } } protected virtual HyenaSqliteCommand SelectCommand { get { if (select_command == null) { select_command = new HyenaSqliteCommand ( String.Format ( "SELECT {0} FROM {1} WHERE {2}", Select, From, String.IsNullOrEmpty (Where) ? "1=1" : Where ) ); } return select_command; } } protected virtual HyenaSqliteCommand SelectRangeCommand { get { if (select_range_command == null) { select_range_command = new HyenaSqliteCommand ( String.Format ( "SELECT {0} FROM {1}{2}{3} LIMIT ?, ?", Select, From, (String.IsNullOrEmpty (Where) ? String.Empty : " WHERE "), Where ) ); } return select_range_command; } } protected virtual HyenaSqliteCommand SelectSingleCommand { get { if (select_single_command == null) { select_single_command = new HyenaSqliteCommand ( String.Format ( "SELECT {0} FROM {1} WHERE {2}{3}{4} = ?", Select, From, Where, (String.IsNullOrEmpty (Where) ? String.Empty : " AND "), PrimaryKey ) ); } return select_single_command; } } protected virtual HyenaSqliteCommand DeleteCommand { get { if (delete_command == null) { delete_command = new HyenaSqliteCommand (String.Format ( "DELETE FROM {0} WHERE {1} IN (?)", TableName, PrimaryKey )); } return delete_command; } } public virtual string Select { get { if (select == null) { BuildQuerySql (); } return select; } } public virtual string From { get { if (from == null) { BuildQuerySql (); } return from; } } public virtual string Where { get { if (where == null) { BuildQuerySql (); } return where; } } public string PrimaryKey { get { if (primary_key == null) { primary_key = String.Format ("{0}.{1}", TableName, key.Name); } return primary_key; } protected set { primary_key = value; } } private void BuildQuerySql () { StringBuilder select_builder = new StringBuilder (); bool first = true; foreach (DatabaseColumn column in select_columns) { if (first) { first = false; } else { select_builder.Append (','); } select_builder.Append (TableName); select_builder.Append ('.'); select_builder.Append (column.Name); } StringBuilder where_builder = new StringBuilder (); Dictionary tables = new Dictionary (virtual_columns.Count + 1); bool first_virtual = true; foreach (VirtualDatabaseColumn column in virtual_columns) { if (first) { first = false; } else { select_builder.Append (','); } select_builder.Append (column.TargetTable); select_builder.Append ('.'); select_builder.Append (column.Name); bool table_not_joined = !tables.ContainsKey (column.TargetTable); if (first_virtual) { first_virtual = false; } else if (table_not_joined) { where_builder.Append (" AND "); } if (table_not_joined) { where_builder.Append (column.TargetTable); where_builder.Append ('.'); where_builder.Append (column.ForeignKey); where_builder.Append (" = "); where_builder.Append (TableName); where_builder.Append ('.'); where_builder.Append (column.LocalKey); tables.Add (column.TargetTable, null); } } StringBuilder from_builder = new StringBuilder (); from_builder.Append (TableName); foreach (KeyValuePair pair in tables) { from_builder.Append (','); from_builder.Append (pair.Key); } select = select_builder.ToString (); from = from_builder.ToString (); where = where_builder.ToString (); } public U GetProperty (T item, DbColumn column) { CheckProperty (typeof (U), column); return connection.Query (String.Format ( "SELECT {0} FROM {1} WHERE {2}={3}", column.Name, TableName, key.Name, key.GetValue (item))); } public void SetProperty (T item, U value, DbColumn column) { CheckProperty (typeof (U), column); connection.Execute (String.Format ( "UPDATE {0} SET {1}='{2}' WHERE {3}={4}", TableName, column.Name, SqliteUtils.ToDbFormat (typeof (U), value), key.Name, key.GetValue (item))); } public void ClearProperty (DbColumn column) { if (!connection.ColumnExists (TableName, column.Name)) { AddColumnToTable (SqliteUtils.BuildColumnSchema ( SqliteUtils.GetType (typeof (U)), column.Name, column.DefaultValue, column.Constraints)); } else { connection.Execute (string.Format ( "UPDATE {0} SET {1}='{2}'", TableName, column.Name, column.DefaultValue)); } } private void CheckProperty (Type type, DbColumn column) { if (!connection.ColumnExists (TableName, column.Name)) { AddColumnToTable (SqliteUtils.BuildColumnSchema ( SqliteUtils.GetType (type), column.Name, column.DefaultValue, column.Constraints)); } } private void AddColumnToTable (string column_schema) { connection.Execute (String.Format ( "ALTER TABLE {0} ADD {1}", TableName, column_schema) ); } } } hyena-0.5/Hyena.Data.Sqlite/Hyena.Data.Sqlite/DatabaseColumn.cs0000644000175000001440000001514211377105536024353 0ustar00gabeusers00000000000000// // DatabaseColumn.cs // // Author: // Scott Peterson // // Copyright (C) 2007 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Data; using System.Reflection; using System.Text; namespace Hyena.Data.Sqlite { public abstract class AbstractDatabaseColumn { private readonly FieldInfo field_info; private readonly PropertyInfo property_info; private readonly Type type; private readonly string column_type; private readonly string name; protected AbstractDatabaseColumn (FieldInfo field_info, AbstractDatabaseColumnAttribute attribute) : this (attribute, field_info, field_info.FieldType) { this.field_info = field_info; } protected AbstractDatabaseColumn (PropertyInfo property_info, AbstractDatabaseColumnAttribute attribute) : this (attribute, property_info, property_info.PropertyType) { if (!property_info.CanRead || (attribute.Select && !property_info.CanWrite)) { throw new Exception (String.Format ( "{0}: The property {1} must have both a get and a set " + "block in order to be bound to a database column.", property_info.DeclaringType, property_info.Name) ); } this.property_info = property_info; } private AbstractDatabaseColumn (AbstractDatabaseColumnAttribute attribute, MemberInfo member_info, Type type) { try { column_type = SqliteUtils.GetType (type); } catch (Exception e) { throw new Exception(string.Format( "{0}.{1}: {2}", member_info.DeclaringType, member_info.Name, e.Message)); } this.name = attribute.ColumnName ?? member_info.Name; this.type = type; } public object GetRawValue (object target) { return field_info != null ? field_info.GetValue (target) : property_info.GetValue (target, null); } public object GetValue (object target) { object result = field_info != null ? field_info.GetValue (target) : property_info.GetValue (target, null); return SqliteUtils.ToDbFormat (type, result); } public void SetValue (object target, IDataReader reader, int column) { // FIXME should we insist on nullable types? object value = reader.IsDBNull (column) ? null : reader.GetValue (column); SetValue (target, SqliteUtils.FromDbFormat(type, value)); } public void SetValue (object target, object value) { if (field_info != null) { field_info.SetValue (target, value); } else { property_info.SetValue (target, value, null); } } public string Name { get { return name; } } public string Type { get { return column_type; } } } public sealed class DatabaseColumn : AbstractDatabaseColumn { private DatabaseColumnAttribute attribute; public DatabaseColumn (FieldInfo field_info, DatabaseColumnAttribute attribute) : base (field_info, attribute) { this.attribute = attribute; } public DatabaseColumn (PropertyInfo property_info, DatabaseColumnAttribute attribute) : base (property_info, attribute) { this.attribute = attribute; } public DatabaseColumnConstraints Constraints { get { return attribute.Constraints; } } public string DefaultValue { get { return attribute.DefaultValue; } } public string Index { get { return attribute.Index; } } public string Schema { get { return SqliteUtils.BuildColumnSchema (Type, Name, attribute.DefaultValue, attribute.Constraints); } } public override bool Equals (object o) { DatabaseColumn column = o as DatabaseColumn; return o != null && column.Name.Equals (Name); } public override int GetHashCode () { return Name.GetHashCode (); } } internal sealed class VirtualDatabaseColumn : AbstractDatabaseColumn { private VirtualDatabaseColumnAttribute attribute; public VirtualDatabaseColumn (FieldInfo field_info, VirtualDatabaseColumnAttribute attribute) : base (field_info, attribute) { this.attribute = attribute; } public VirtualDatabaseColumn (PropertyInfo property_info, VirtualDatabaseColumnAttribute attribute) : base (property_info, attribute) { this.attribute = attribute; } public string TargetTable { get { return attribute.TargetTable; } } public string LocalKey { get { return attribute.LocalKey; } } public string ForeignKey { get { return attribute.ForeignKey; } } } public struct DbColumn { public readonly string Name; public readonly DatabaseColumnConstraints Constraints; public readonly string DefaultValue; public DbColumn(string name, DatabaseColumnConstraints constraints, string default_value) { Name = name; Constraints = constraints; DefaultValue = default_value; } } } hyena-0.5/Hyena.Data.Sqlite/Hyena.Data.Sqlite/HyenaSqliteArrayDataReader.cs0000644000175000001440000003063511377105536026637 0ustar00gabeusers00000000000000// // HyenaSqliteArrayDataReader.cs // // Authors: // Vladimir Vukicevic // Everaldo Canuto // Joshua Tauberer // John Millikin // // Copyright (C) 2002 Vladimir Vukicevic // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Data; using System.Data.Common; using System.Text; using System.Collections; using System.Collections.Generic; using Mono.Data.Sqlite; namespace Hyena.Data.Sqlite { /* * Adapted from Mono.Data.SqliteClient.SqliteDataReader * * The new data reader in Mono.Data.Sqlite lazily loads the resultset * from the underlying database cursor. This class reads the entire * resultset into memory, allowing further queries to be executed before * all data readers have been exhausted. * */ internal class HyenaSqliteArrayDataReader : MarshalByRefObject, IEnumerable, IDataReader, IDisposable, IDataRecord { #region Fields private List rows; private string[] columns; private Dictionary column_names; private int current_row; private bool closed; private int records_affected; private string[] decltypes; #endregion #region Constructors and destructors internal HyenaSqliteArrayDataReader (SqliteDataReader reader) { rows = new List (); column_names = new Dictionary (); closed = false; current_row = -1; ReadAllRows (reader); reader.Dispose (); } #endregion #region Properties public int Depth { get { return 0; } } public int FieldCount { get { return columns.Length; } } public object this[string name] { get { return GetValue (GetOrdinal (name)); } } public object this[int i] { get { return GetValue (i); } } public bool IsClosed { get { return closed; } } public int RecordsAffected { get { return records_affected; } } #endregion private void ReadAllRows (SqliteDataReader reader) { int ii, field_count = reader.FieldCount; /* Metadata */ records_affected = reader.RecordsAffected; decltypes = new string[field_count]; for (ii = 0; ii < field_count; ii++) { decltypes[ii] = reader.GetDataTypeName (ii); } columns = new string[field_count]; for (ii = 0; ii < field_count; ii++) { string column_name = reader.GetName (ii); columns[ii] = column_name; column_names[column_name] = ii; column_names[column_name.ToUpper ()] = ii; } /* Read all rows, store in this->rows */ while (reader.Read ()) { object[] data_row = new object[field_count]; for (ii = 0; ii < field_count; ii++) { object value = reader.GetValue (ii); if (Convert.IsDBNull (value)) value = null; data_row[ii] = value; } rows.Add (data_row); } } #region Public Methods public void Close () { closed = true; } public void Dispose () { Close (); } IEnumerator IEnumerable.GetEnumerator () { return new DbEnumerator (this); } public DataTable GetSchemaTable () { DataTable dataTableSchema = new DataTable (); dataTableSchema.Columns.Add ("ColumnName", typeof (String)); dataTableSchema.Columns.Add ("ColumnOrdinal", typeof (Int32)); dataTableSchema.Columns.Add ("ColumnSize", typeof (Int32)); dataTableSchema.Columns.Add ("NumericPrecision", typeof (Int32)); dataTableSchema.Columns.Add ("NumericScale", typeof (Int32)); dataTableSchema.Columns.Add ("IsUnique", typeof (Boolean)); dataTableSchema.Columns.Add ("IsKey", typeof (Boolean)); dataTableSchema.Columns.Add ("BaseCatalogName", typeof (String)); dataTableSchema.Columns.Add ("BaseColumnName", typeof (String)); dataTableSchema.Columns.Add ("BaseSchemaName", typeof (String)); dataTableSchema.Columns.Add ("BaseTableName", typeof (String)); dataTableSchema.Columns.Add ("DataType", typeof(Type)); dataTableSchema.Columns.Add ("AllowDBNull", typeof (Boolean)); dataTableSchema.Columns.Add ("ProviderType", typeof (Int32)); dataTableSchema.Columns.Add ("IsAliased", typeof (Boolean)); dataTableSchema.Columns.Add ("IsExpression", typeof (Boolean)); dataTableSchema.Columns.Add ("IsIdentity", typeof (Boolean)); dataTableSchema.Columns.Add ("IsAutoIncrement", typeof (Boolean)); dataTableSchema.Columns.Add ("IsRowVersion", typeof (Boolean)); dataTableSchema.Columns.Add ("IsHidden", typeof (Boolean)); dataTableSchema.Columns.Add ("IsLong", typeof (Boolean)); dataTableSchema.Columns.Add ("IsReadOnly", typeof (Boolean)); dataTableSchema.BeginLoadData(); for (int i = 0; i < this.FieldCount; i += 1 ) { DataRow schemaRow = dataTableSchema.NewRow (); schemaRow["ColumnName"] = columns[i]; schemaRow["ColumnOrdinal"] = i; schemaRow["ColumnSize"] = 0; schemaRow["NumericPrecision"] = 0; schemaRow["NumericScale"] = 0; schemaRow["IsUnique"] = false; schemaRow["IsKey"] = false; schemaRow["BaseCatalogName"] = ""; schemaRow["BaseColumnName"] = columns[i]; schemaRow["BaseSchemaName"] = ""; schemaRow["BaseTableName"] = ""; schemaRow["DataType"] = typeof(string); schemaRow["AllowDBNull"] = true; schemaRow["ProviderType"] = 0; schemaRow["IsAliased"] = false; schemaRow["IsExpression"] = false; schemaRow["IsIdentity"] = false; schemaRow["IsAutoIncrement"] = false; schemaRow["IsRowVersion"] = false; schemaRow["IsHidden"] = false; schemaRow["IsLong"] = false; schemaRow["IsReadOnly"] = false; dataTableSchema.Rows.Add (schemaRow); schemaRow.AcceptChanges(); } dataTableSchema.EndLoadData(); return dataTableSchema; } public bool NextResult () { current_row++; return current_row < rows.Count; } public bool Read () { return NextResult (); } #endregion #region IDataRecord getters public bool GetBoolean (int i) { return Convert.ToBoolean (rows[current_row][i]); } public byte GetByte (int i) { return Convert.ToByte (rows[current_row][i]); } public long GetBytes (int i, long fieldOffset, byte[] buffer, int bufferOffset, int length) { byte[] data = (byte[])(rows[current_row][i]); if (buffer != null) Array.Copy (data, fieldOffset, buffer, bufferOffset, length); return data.LongLength - fieldOffset; } public char GetChar (int i) { return Convert.ToChar (rows[current_row][i]); } public long GetChars (int i, long fieldOffset, char[] buffer, int bufferOffset, int length) { char[] data = (char[])(rows[current_row][i]); if (buffer != null) Array.Copy (data, fieldOffset, buffer, bufferOffset, length); return data.LongLength - fieldOffset; } public IDataReader GetData (int i) { return ((IDataReader) this [i]); } public string GetDataTypeName (int i) { if (decltypes != null && decltypes[i] != null) return decltypes[i]; return "text"; // SQL Lite data type } public DateTime GetDateTime (int i) { return Convert.ToDateTime (rows[current_row][i]); } public decimal GetDecimal (int i) { return Convert.ToDecimal (rows[current_row][i]); } public double GetDouble (int i) { return Convert.ToDouble (rows[current_row][i]); } public Type GetFieldType (int i) { int row = current_row; if (row == -1 && rows.Count == 0) return typeof(string); if (row == -1) row = 0; object element = rows[row][i]; if (element != null) return element.GetType(); else return typeof (string); // Note that the return value isn't guaranteed to // be the same as the rows are read if different // types of information are stored in the column. } public float GetFloat (int i) { return Convert.ToSingle (rows[current_row][i]); } public Guid GetGuid (int i) { object value = GetValue (i); if (!(value is Guid)) { if (value is DBNull) throw new SqliteException ("Column value must not be null"); throw new InvalidCastException ("Type is " + value.GetType ().ToString ()); } return ((Guid) value); } public short GetInt16 (int i) { return Convert.ToInt16 (rows[current_row][i]); } public int GetInt32 (int i) { return Convert.ToInt32 (rows[current_row][i]); } public long GetInt64 (int i) { return Convert.ToInt64 (rows[current_row][i]); } public string GetName (int i) { return columns[i]; } public int GetOrdinal (string name) { int v = -1; if (!column_names.TryGetValue (name, out v)) { if (!column_names.TryGetValue (name.ToUpper (), out v)) { throw new ArgumentException("Column does not exist."); } } return v; } public string GetString (int i) { return rows[current_row][i].ToString(); } public object GetValue (int i) { return rows[current_row][i]; } public int GetValues (object[] values) { int num_to_fill = System.Math.Min (values.Length, columns.Length); for (int i = 0; i < num_to_fill; i++) { if (rows[current_row][i] != null) { values[i] = rows[current_row][i]; } else { values[i] = null; } } return num_to_fill; } public bool IsDBNull (int i) { return rows[current_row][i] == null; } #endregion } } // vi:tabstop=4:expandtab hyena-0.5/Hyena.Data.Sqlite/Hyena.Data.Sqlite/SqliteUtils.cs0000644000175000001440000001764111377105536023761 0ustar00gabeusers00000000000000// // SqliteUtils.cs // // Author: // Scott Peterson // // Copyright (C) 2007 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Reflection; using System.Text; using Mono.Data.Sqlite; using System.Collections.Generic; namespace Hyena.Data.Sqlite { public static class SqliteUtils { internal static string GetType (Type type) { if (type == typeof (string)) { return "TEXT"; } else if (type == typeof (int) || type == typeof (long) || type == typeof (bool) || type == typeof (DateTime) || type == typeof (TimeSpan) || type.IsEnum) { return "INTEGER"; } else if (type == typeof (int?) || type == typeof (long?) || type == typeof (bool?) || type == typeof (uint?)) { return "INTEGER NULL"; } else if (type == typeof (byte[])) { return "BLOB"; } else if (type == typeof (double)) { return "REAL"; } else if (type == typeof (double?)) { return "REAL NULL"; } else { throw new Exception (String.Format ( "The type {0} cannot be bound to a database column.", type.Name)); } } public static object ToDbFormat (Type type, object value) { if (type == typeof (string)) { // Treat blank strings or strings with only whitespace as null return value == null || String.IsNullOrEmpty (((string)value).Trim ()) ? null : value; } else if (type == typeof (DateTime)) { return DateTime.MinValue.Equals ((DateTime)value) ? (object)null : DateTimeUtil.FromDateTime ((DateTime)value); } else if (type == typeof (TimeSpan)) { return TimeSpan.MinValue.Equals ((TimeSpan)value) ? (object)null : ((TimeSpan)value).TotalMilliseconds; } else if (type.IsEnum) { return Convert.ChangeType (value, Enum.GetUnderlyingType (type)); } else if (type == typeof (bool)) { return ((bool)value) ? 1 : 0; } return value; } public static object FromDbFormat (Type type, object value) { if (Convert.IsDBNull (value)) value = null; if (type == typeof (DateTime)) { return value == null ? DateTime.MinValue : DateTimeUtil.ToDateTime (Convert.ToInt64 (value)); } else if (type == typeof (TimeSpan)) { return value == null ? TimeSpan.MinValue : TimeSpan.FromMilliseconds (Convert.ToInt64 (value)); } else if (value == null) { if (type.IsValueType) { return Activator.CreateInstance (type); } else { return null; } } else if (type.IsEnum) { return Enum.ToObject (type, value); } else if (type == typeof (bool)) { return ((long)value == 1); } else if (type == typeof (double?)) { if (value == null) return null; double double_value = ((Single?) value).Value; return (double?) double_value; } else { return Convert.ChangeType (value, type); } } internal static string BuildColumnSchema (string type, string name, string default_value, DatabaseColumnConstraints constraints) { StringBuilder builder = new StringBuilder (); builder.Append (name); builder.Append (' '); builder.Append (type); if ((constraints & DatabaseColumnConstraints.NotNull) > 0) { builder.Append (" NOT NULL"); } if ((constraints & DatabaseColumnConstraints.Unique) > 0) { builder.Append (" UNIQUE"); } if ((constraints & DatabaseColumnConstraints.PrimaryKey) > 0) { builder.Append (" PRIMARY KEY"); } if (default_value != null) { builder.Append (" DEFAULT "); builder.Append (default_value); } return builder.ToString (); } } [SqliteFunction (Name = "HYENA_BINARY_FUNCTION", FuncType = FunctionType.Scalar, Arguments = 3)] public sealed class BinaryFunction : SqliteFunction { private static Dictionary> funcs = new Dictionary> (); public static void Add (string functionId, Func func) { lock (funcs) { if (funcs.ContainsKey (functionId)) { throw new ArgumentException (String.Format ("{0} is already taken", functionId), "functionId"); } funcs[functionId] = func; } } public static void Remove (string functionId) { lock (funcs) { if (!funcs.ContainsKey (functionId)) { throw new ArgumentException (String.Format ("{0} does not exist", functionId), "functionId"); } funcs.Remove (functionId); } } public override object Invoke (object[] args) { Func func; if (!funcs.TryGetValue (args[0] as string, out func)) throw new ArgumentException (args[0] as string, "HYENA_BINARY_FUNCTION name (arg 0)"); return func (args[1], args[2]); } } [SqliteFunction (Name = "HYENA_COLLATION_KEY", FuncType = FunctionType.Scalar, Arguments = 1)] internal class CollationKeyFunction : SqliteFunction { public override object Invoke (object[] args) { return Hyena.StringUtil.SortKey (args[0] as string); } } [SqliteFunction (Name = "HYENA_SEARCH_KEY", FuncType = FunctionType.Scalar, Arguments = 1)] internal class SearchKeyFunction : SqliteFunction { public override object Invoke (object[] args) { return Hyena.StringUtil.SearchKey (args[0] as string); } } [SqliteFunction (Name = "HYENA_MD5", FuncType = FunctionType.Scalar, Arguments = -1)] internal class Md5Function : SqliteFunction { public override object Invoke (object[] args) { int n_args = (int)(long) args[0]; var sb = new StringBuilder (); for (int i = 1; i <= n_args; i++) { sb.Append (args[i]); } return Hyena.CryptoUtil.Md5Encode (sb.ToString (), System.Text.Encoding.UTF8); } } } hyena-0.5/Hyena.Data.Sqlite/Hyena.Data.Sqlite/ICacheableDatabaseModel.cs0000644000175000001440000000316711377105536026043 0ustar00gabeusers00000000000000// // ICacheableDatabaseModel.cs // // Author: // Gabriel Burt // // Copyright (C) 2007 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System.Data; using Hyena.Data; namespace Hyena.Data.Sqlite { public interface ICacheableDatabaseModel : ICacheableModel { string ReloadFragment { get; } string SelectAggregates { get; } string JoinTable { get; } string JoinFragment { get; } string JoinPrimaryKey { get; } string JoinColumn { get; } bool CachesJoinTableEntries { get; } bool CachesValues { get; } } } hyena-0.5/Hyena.Data.Sqlite/Hyena.Data.Sqlite/SqliteModelCache.cs0000644000175000001440000004621511377105536024644 0ustar00gabeusers00000000000000// // SqliteModelCache.cs // // Authors: // Gabriel Burt // Scott Peterson // // Copyright (C) 2007-2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Collections.Generic; using System.Data; using System.Text; using Hyena.Query; namespace Hyena.Data.Sqlite { public class SqliteModelCache : DictionaryModelCache where T : ICacheableItem, new () { private HyenaSqliteConnection connection; private ICacheableDatabaseModel model; private SqliteModelProvider provider; private HyenaSqliteCommand select_range_command; private HyenaSqliteCommand select_single_command; private HyenaSqliteCommand select_first_command; private HyenaSqliteCommand count_command; private HyenaSqliteCommand delete_selection_command; private HyenaSqliteCommand save_selection_command; private HyenaSqliteCommand get_selection_command; private HyenaSqliteCommand indexof_command; private string select_str; private string reload_sql; private string last_indexof_where_fragment; private long uid; private long selection_uid; private long rows; // private bool warm; private long first_order_id; public event Action AggregatesUpdated; public SqliteModelCache (HyenaSqliteConnection connection, string uuid, ICacheableDatabaseModel model, SqliteModelProvider provider) : base (model) { this.connection = connection; this.model = model; this.provider = provider; CheckCacheTable (); if (model.SelectAggregates != null) { if (model.CachesJoinTableEntries) { count_command = new HyenaSqliteCommand (String.Format (@" SELECT count(*), {0} FROM {1}{2} j WHERE j.{4} IN (SELECT ItemID FROM {3} WHERE ModelID = ?) AND {5} = j.{6}", model.SelectAggregates, // eg sum(FileSize), sum(Duration) provider.TableName, // eg CoreTracks model.JoinFragment, // eg , CorePlaylistEntries CacheTableName, // eg CoreCache model.JoinPrimaryKey, // eg EntryID provider.PrimaryKey, // eg CoreTracks.TrackID model.JoinColumn // eg TrackID )); } else { count_command = new HyenaSqliteCommand (String.Format ( "SELECT count(*), {0} FROM {1} WHERE {2} IN (SELECT ItemID FROM {3} WHERE ModelID = ?)", model.SelectAggregates, provider.TableName, provider.PrimaryKey, CacheTableName )); } } else { count_command = new HyenaSqliteCommand (String.Format ( "SELECT COUNT(*) FROM {0} WHERE ModelID = ?", CacheTableName )); } uid = FindOrCreateCacheModelId (String.Format ("{0}-{1}", uuid, typeof(T).Name)); if (model.Selection != null) { selection_uid = FindOrCreateCacheModelId (String.Format ("{0}-{1}-Selection", uuid, typeof(T).Name)); } if (model.CachesJoinTableEntries) { select_str = String.Format ( @"SELECT {0} {10}, OrderID, {5}.ItemID FROM {1} INNER JOIN {2} ON {3} = {2}.{4} INNER JOIN {5} ON {2}.{6} = {5}.ItemID {11} WHERE {5}.ModelID = {7} {8} {9}", provider.Select, provider.From, model.JoinTable, provider.PrimaryKey, model.JoinColumn, CacheTableName, model.JoinPrimaryKey, uid, String.IsNullOrEmpty (provider.Where) ? null : "AND", provider.Where, "{0}", "{1}" ); reload_sql = String.Format (@" DELETE FROM {0} WHERE ModelID = {1}; INSERT INTO {0} (ModelID, ItemID) SELECT {1}, {2} ", CacheTableName, uid, model.JoinPrimaryKey ); } else if (model.CachesValues) { // The duplication of OrderID/ItemID in the select below is intentional! // The first is used construct the QueryFilterInfo value, the last internally // to this class select_str = String.Format ( @"SELECT OrderID, ItemID {2}, OrderID, ItemID FROM {0} {3} WHERE {0}.ModelID = {1}", CacheTableName, uid, "{0}", "{1}" ); reload_sql = String.Format (@" DELETE FROM {0} WHERE ModelID = {1}; INSERT INTO {0} (ModelID, ItemID) SELECT DISTINCT {1}, {2} ", CacheTableName, uid, provider.Select ); } else { select_str = String.Format ( @"SELECT {0} {7}, OrderID, {2}.ItemID FROM {1} INNER JOIN {2} ON {3} = {2}.ItemID {8} WHERE {2}.ModelID = {4} {5} {6}", provider.Select, provider.From, CacheTableName, provider.PrimaryKey, uid, String.IsNullOrEmpty (provider.Where) ? String.Empty : "AND", provider.Where, "{0}", "{1}" ); reload_sql = String.Format (@" DELETE FROM {0} WHERE ModelID = {1}; INSERT INTO {0} (ModelID, ItemID) SELECT {1}, {2} ", CacheTableName, uid, provider.PrimaryKey ); } select_single_command = new HyenaSqliteCommand ( String.Format (@" SELECT OrderID FROM {0} WHERE ModelID = {1} AND ItemID = ?", CacheTableName, uid ) ); select_range_command = new HyenaSqliteCommand ( String.Format (String.Format ("{0} {1}", select_str, "LIMIT ?, ?"), null, null) ); select_first_command = new HyenaSqliteCommand ( String.Format ( "SELECT OrderID FROM {0} WHERE ModelID = {1} LIMIT 1", CacheTableName, uid ) ); if (model.Selection != null) { delete_selection_command = new HyenaSqliteCommand (String.Format ( "DELETE FROM {0} WHERE ModelID = {1}", CacheTableName, selection_uid )); save_selection_command = new HyenaSqliteCommand (String.Format ( "INSERT INTO {0} (ModelID, ItemID) SELECT {1}, ItemID FROM {0} WHERE ModelID = {2} LIMIT ?, ?", CacheTableName, selection_uid, uid )); get_selection_command = new HyenaSqliteCommand (String.Format ( "SELECT OrderID FROM {0} WHERE ModelID = {1} AND ItemID IN (SELECT ItemID FROM {0} WHERE ModelID = {2})", CacheTableName, uid, selection_uid )); } } private bool has_select_all_item = false; public bool HasSelectAllItem { get { return has_select_all_item; } set { has_select_all_item = value; } } // The idea behind this was we could preserve the CoreCache table across restarts of Banshee, // and indicate whether the cache was already primed via this property. It's not used, and may never be. public bool Warm { //get { return warm; } get { return false; } } public long Count { get { return rows; } } public long CacheId { get { return uid; } } protected virtual string CacheModelsTableName { get { return "HyenaCacheModels"; } } protected virtual string CacheTableName { get { return "HyenaCache"; } } private long FirstOrderId { get { lock (this) { if (first_order_id == -1) { first_order_id = connection.Query (select_first_command); } return first_order_id; } } } public long IndexOf (string where_fragment, long offset) { if (String.IsNullOrEmpty (where_fragment)) { return -1; } if (!where_fragment.Equals (last_indexof_where_fragment)) { last_indexof_where_fragment = where_fragment; if (!where_fragment.Trim ().ToLower ().StartsWith ("and ")) { where_fragment = " AND " + where_fragment; } string sql = String.Format ("{0} {1} LIMIT ?, 1", select_str, where_fragment); indexof_command = new HyenaSqliteCommand (String.Format (sql, null, null)); } lock (this) { using (IDataReader reader = connection.Query (indexof_command, offset)) { if (reader.Read ()) { long target_id = (long) reader[reader.FieldCount - 2]; if (target_id == 0) { return -1; } return target_id - FirstOrderId; } } return -1; } } public long IndexOf (ICacheableItem item) { if (item == null || item.CacheModelId != CacheId) { return -1; } return IndexOf (item.CacheEntryId); } public long IndexOf (object item_id) { lock (this) { if (rows == 0) { return -1; } long target_id = connection.Query (select_single_command, item_id); if (target_id == 0) { return -1; } return target_id - FirstOrderId; } } public T GetSingleWhere (string conditionOrderFragment, params object [] args) { return GetSingle (null, null, conditionOrderFragment, args); } private HyenaSqliteCommand get_single_command; private string last_get_single_select_fragment, last_get_single_condition_fragment, last_get_single_from_fragment; public T GetSingle (string selectFragment, string fromFragment, string conditionOrderFragment, params object [] args) { if (selectFragment != last_get_single_select_fragment || conditionOrderFragment != last_get_single_condition_fragment ||fromFragment != last_get_single_from_fragment || get_single_command == null) { last_get_single_select_fragment = selectFragment; last_get_single_condition_fragment = conditionOrderFragment; last_get_single_from_fragment = fromFragment; get_single_command = new HyenaSqliteCommand (String.Format (String.Format ( "{0} {1} {2}", select_str, conditionOrderFragment, "LIMIT 1"), selectFragment, fromFragment )); } using (IDataReader reader = connection.Query (get_single_command, args)) { if (reader.Read ()) { T item = provider.Load (reader); item.CacheEntryId = reader[reader.FieldCount - 1]; item.CacheModelId = uid; return item; } } return default(T); } private HyenaSqliteCommand last_reload_command; private string last_reload_fragment; public override void Reload () { lock (this) { if (last_reload_fragment != model.ReloadFragment || last_reload_command == null) { last_reload_fragment = model.ReloadFragment; last_reload_command = new HyenaSqliteCommand (String.Format ("{0}{1}", reload_sql, last_reload_fragment)); } Clear (); //Log.DebugFormat ("Reloading {0} with {1}", model, last_reload_command.Text); connection.Execute (last_reload_command); } } public override void Clear () { lock (this) { base.Clear (); first_order_id = -1; } } private bool saved_selection = false; private ICacheableItem saved_focus_item = null; public void SaveSelection () { if (model.Selection != null && model.Selection.Count > 0 && !(has_select_all_item && model.Selection.AllSelected)) { connection.Execute (delete_selection_command); saved_selection = true; if (!has_select_all_item && model.Selection.FocusedIndex != -1) { T item = GetValue (model.Selection.FocusedIndex); if (item != null) { saved_focus_item = GetValue (model.Selection.FocusedIndex); } } long start, end; foreach (Hyena.Collections.RangeCollection.Range range in model.Selection.Ranges) { start = range.Start; end = range.End; // Compensate for the first, fake 'All *' item if (has_select_all_item) { start -= 1; end -= 1; } connection.Execute (save_selection_command, start, end - start + 1); } } else { saved_selection = false; } } public void RestoreSelection () { if (saved_selection) { long selected_id = -1; long first_id = FirstOrderId; // Compensate for the first, fake 'All *' item if (has_select_all_item) { first_id -= 1; } model.Selection.Clear (false); foreach (long order_id in connection.QueryEnumerable (get_selection_command)) { selected_id = order_id - first_id; model.Selection.QuietSelect ((int)selected_id); } if (has_select_all_item && model.Selection.Count == 0) { model.Selection.QuietSelect (0); } if (saved_focus_item != null) { long i = IndexOf (saved_focus_item); if (i != -1) { // TODO get rid of int cast model.Selection.FocusedIndex = (int)i; } } saved_selection = false; saved_focus_item = null; } } protected override void FetchSet (long offset, long limit) { lock (this) { using (IDataReader reader = connection.Query (select_range_command, offset, limit)) { T item; while (reader.Read ()) { if (!ContainsKey (offset)) { item = provider.Load (reader); item.CacheEntryId = reader[reader.FieldCount - 1]; item.CacheModelId = uid; Add (offset, item); } offset++; } } } } public void UpdateAggregates () { using (IDataReader reader = connection.Query (count_command, uid)) { if (reader.Read ()) { rows = Convert.ToInt64 (reader[0]); Action handler = AggregatesUpdated; if (handler != null) { handler (reader); } } } } private long FindOrCreateCacheModelId (string id) { long model_id = connection.Query (String.Format ( "SELECT CacheID FROM {0} WHERE ModelID = '{1}'", CacheModelsTableName, id )); if (model_id == 0) { //Console.WriteLine ("Didn't find existing cache for {0}, creating", id); model_id = connection.Execute (new HyenaSqliteCommand (String.Format ( "INSERT INTO {0} (ModelID) VALUES (?)", CacheModelsTableName ), id )); } else { //Console.WriteLine ("Found existing cache for {0}: {1}", id, uid); //warm = true; //Clear (); //UpdateAggregates (); } return model_id; } private static string checked_cache_table; private void CheckCacheTable () { if (CacheTableName == checked_cache_table) { return; } if (!connection.TableExists (CacheTableName)) { connection.Execute (String.Format (@" CREATE TEMP TABLE {0} ( OrderID INTEGER PRIMARY KEY, ModelID INTEGER, ItemID TEXT)", CacheTableName )); } if (!connection.TableExists (CacheModelsTableName)) { connection.Execute (String.Format ( "CREATE TABLE {0} (CacheID INTEGER PRIMARY KEY, ModelID TEXT UNIQUE)", CacheModelsTableName )); } checked_cache_table = CacheTableName; } } } hyena-0.5/Hyena.Data.Sqlite/Hyena.Data.Sqlite/HyenaSqliteConnection.cs0000644000175000001440000003762211436010340025726 0ustar00gabeusers00000000000000// // HyenaSqliteConnection.cs // // Authors: // Aaron Bockover // Gabriel Burt // // Copyright (C) 2005-2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Data; using System.Threading; using System.Collections.Generic; using Mono.Data.Sqlite; namespace Hyena.Data.Sqlite { public class HyenaDataReader : IDisposable { private IDataReader reader; private bool read = false; public IDataReader Reader { get { return reader; } } public HyenaDataReader (IDataReader reader) { this.reader = reader; } public T Get (int i) { if (!read) { Read (); } return (T) SqliteUtils.FromDbFormat (typeof(T), reader[i]); } public bool Read () { read = true; return reader.Read (); } public void Dispose () { reader.Dispose (); reader = null; } } public class ExecutingEventArgs : EventArgs { public readonly SqliteCommand Command; public ExecutingEventArgs (SqliteCommand command) { Command = command; } } public enum HyenaCommandType { Reader, Scalar, Execute, } public class HyenaSqliteConnection : IDisposable { private SqliteConnection connection; private string dbpath; // These are 'parallel' queues; that is, when a value is pushed or popped to // one, a value is pushed or popped to all three. // The 1st contains the command object itself, and the 2nd and 3rd contain the // arguments to be applied to that command (filled in for any ? placeholder in the command). // The 3rd exists as an optimization to avoid making an object [] for a single arg. private Queue command_queue = new Queue(); private Queue args_queue = new Queue(); private Queue arg_queue = new Queue(); private Thread queue_thread; private volatile bool dispose_requested = false; private volatile int results_ready = 0; private AutoResetEvent queue_signal = new AutoResetEvent (false); internal ManualResetEvent ResultReadySignal = new ManualResetEvent (false); private volatile Thread transaction_thread = null; private ManualResetEvent transaction_signal = new ManualResetEvent (true); private Thread warn_if_called_from_thread; public Thread WarnIfCalledFromThread { get { return warn_if_called_from_thread; } set { warn_if_called_from_thread = value; } } public string ServerVersion { get { return connection.ServerVersion; } } public event EventHandler Executing; public HyenaSqliteConnection(string dbpath) { this.dbpath = dbpath; queue_thread = new Thread(ProcessQueue); queue_thread.Name = String.Format ("HyenaSqliteConnection ({0})", dbpath); queue_thread.IsBackground = true; queue_thread.Start(); } #region Public Query Methods // TODO special case for single object param to avoid object [] // SELECT multiple column queries public IDataReader Query (HyenaSqliteCommand command) { command.CommandType = HyenaCommandType.Reader; QueueCommand (command); return command.WaitForResult (this) as IDataReader; } public IDataReader Query (HyenaSqliteCommand command, params object [] param_values) { command.CommandType = HyenaCommandType.Reader; QueueCommand (command, param_values); return command.WaitForResult (this) as IDataReader; } public IDataReader Query (string command_str, params object [] param_values) { return Query (new HyenaSqliteCommand (command_str, param_values)); } public IDataReader Query (object command) { return Query (new HyenaSqliteCommand (command.ToString ())); } // SELECT single column, multiple rows queries public IEnumerable QueryEnumerable (HyenaSqliteCommand command) { Type type = typeof (T); using (IDataReader reader = Query (command)) { while (reader.Read ()) { yield return (T) SqliteUtils.FromDbFormat (type, reader[0]); } } } public IEnumerable QueryEnumerable (HyenaSqliteCommand command, params object [] param_values) { Type type = typeof (T); using (IDataReader reader = Query (command, param_values)) { while (reader.Read ()) { yield return (T) SqliteUtils.FromDbFormat (type, reader[0]); } } } public IEnumerable QueryEnumerable (string command_str, params object [] param_values) { return QueryEnumerable (new HyenaSqliteCommand (command_str, param_values)); } public IEnumerable QueryEnumerable (object command) { return QueryEnumerable (new HyenaSqliteCommand (command.ToString ())); } // SELECT single column, single row queries public T Query (HyenaSqliteCommand command) { command.CommandType = HyenaCommandType.Scalar; QueueCommand (command); object result = command.WaitForResult (this); return (T)SqliteUtils.FromDbFormat (typeof (T), result); } public T Query (HyenaSqliteCommand command, params object [] param_values) { command.CommandType = HyenaCommandType.Scalar; QueueCommand (command, param_values); object result = command.WaitForResult (this); return (T)SqliteUtils.FromDbFormat (typeof (T), result); } public T Query (string command_str, params object [] param_values) { return Query (new HyenaSqliteCommand (command_str, param_values)); } public T Query (object command) { return Query (new HyenaSqliteCommand (command.ToString ())); } // INSERT, UPDATE, DELETE queries public int Execute (HyenaSqliteCommand command) { command.CommandType = HyenaCommandType.Execute;; QueueCommand(command); return Convert.ToInt32 (command.WaitForResult (this)); } public int Execute (HyenaSqliteCommand command, params object [] param_values) { command.CommandType = HyenaCommandType.Execute;; QueueCommand(command, param_values); return Convert.ToInt32 (command.WaitForResult (this)); } public int Execute (string command_str, params object [] param_values) { return Execute (new HyenaSqliteCommand (command_str, param_values)); } public int Execute (object command) { return Execute (new HyenaSqliteCommand (command.ToString ())); } #endregion #region Public Utility Methods public void BeginTransaction () { if (transaction_thread == Thread.CurrentThread) { throw new Exception ("Can't start a recursive transaction"); } while (transaction_thread != Thread.CurrentThread) { if (transaction_thread != null) { // Wait for the existing transaction to finish before this thread proceeds transaction_signal.WaitOne (); } lock (command_queue) { if (transaction_thread == null) { transaction_thread = Thread.CurrentThread; transaction_signal.Reset (); } } } Execute ("BEGIN TRANSACTION"); } public void CommitTransaction () { if (transaction_thread != Thread.CurrentThread) { throw new Exception ("Can't commit from outside a transaction"); } Execute ("COMMIT TRANSACTION"); lock (command_queue) { transaction_thread = null; // Let any other threads continue transaction_signal.Set (); } } public void RollbackTransaction () { if (transaction_thread != Thread.CurrentThread) { throw new Exception ("Can't rollback from outside a transaction"); } Execute ("ROLLBACK"); lock (command_queue) { transaction_thread = null; // Let any other threads continue transaction_signal.Set (); } } public bool TableExists (string tableName) { return Exists ("table", tableName); } public bool IndexExists (string indexName) { return Exists ("index", indexName); } private bool Exists (string type, string name) { return Exists (type, name, "sqlite_master") || Exists (type, name, "sqlite_temp_master"); } private bool Exists (string type, string name, string master) { return Query (String.Format ( "SELECT COUNT(*) FROM {0} WHERE Type='{1}' AND Name='{2}'", master, type, name) ) > 0; } private delegate void SchemaHandler (string column); private void SchemaClosure (string table_name, SchemaHandler code) { string sql = Query (String.Format ( "SELECT sql FROM sqlite_master WHERE Name='{0}'", table_name)); if (String.IsNullOrEmpty (sql)) { return; } sql = sql.Substring (sql.IndexOf ('(') + 1); foreach (string column_def in sql.Split (',')) { string column_def_t = column_def.Trim (); int ws_index = column_def_t.IndexOfAny (ws_chars); code (column_def_t.Substring (0, ws_index)); } } public bool ColumnExists (string tableName, string columnName) { bool value = false; SchemaClosure (tableName, delegate (string column) { if (column == columnName) { value = true; return; } }); return value; } private static readonly char [] ws_chars = new char [] { ' ', '\t', '\n', '\r' }; public IDictionary GetSchema (string table_name) { Dictionary schema = new Dictionary (); SchemaClosure (table_name, delegate (string column) { schema.Add (column.ToLower (), null); }); return schema; } #endregion #region Private Queue Methods private void QueueCommand(HyenaSqliteCommand command, object [] args) { QueueCommand (command, null, args); } // TODO optimize object vs object [] code paths? /*private void QueueCommand(HyenaSqliteCommand command, object arg) { QueueCommand (command, arg, null); }*/ private void QueueCommand(HyenaSqliteCommand command) { QueueCommand (command, null, null); } private void QueueCommand(HyenaSqliteCommand command, object arg, object [] args) { if (warn_if_called_from_thread != null && Thread.CurrentThread == warn_if_called_from_thread) { Hyena.Log.Warning ("HyenaSqliteConnection command issued from the main thread"); } while (true) { lock (command_queue) { if (dispose_requested) { // No point in queueing the command if we're already disposing. // This helps avoid using the probably-disposed queue_signal below too return; } else if (transaction_thread == null || Thread.CurrentThread == transaction_thread) { command_queue.Enqueue (command); args_queue.Enqueue (args); arg_queue.Enqueue (arg); break; } } transaction_signal.WaitOne (); } queue_signal.Set (); } internal void ClaimResult () { lock (command_queue) { results_ready--; if (results_ready == 0) { ResultReadySignal.Reset (); } } } private void ProcessQueue() { if (connection == null) { connection = new SqliteConnection (String.Format ("Version=3,URI=file:{0}", dbpath)); connection.Open (); } // Keep handling queries while (!dispose_requested) { while (command_queue.Count > 0) { HyenaSqliteCommand command; object [] args; object arg; lock (command_queue) { command = command_queue.Dequeue (); args = args_queue.Dequeue (); arg = arg_queue.Dequeue (); } // Ensure the command is not altered while applying values or executing lock (command) { command.WaitIfNotFinished (); if (arg != null) { command.ApplyValues (arg); } else if (args != null) { command.ApplyValues (args); } command.Execute (this, connection); } lock (command_queue) { results_ready++; ResultReadySignal.Set (); } } queue_signal.WaitOne (); } // Finish connection.Close (); } internal void OnExecuting (SqliteCommand command) { EventHandler handler = Executing; if (handler != null) { handler (this, new ExecutingEventArgs (command)); } } #endregion public void Dispose() { dispose_requested = true; queue_signal.Set (); queue_thread.Join (); queue_signal.Close (); ResultReadySignal.Close (); transaction_signal.Close (); } } } hyena-0.5/Hyena.Data.Sqlite/Hyena.Data.Sqlite/HyenaSqliteCommand.cs0000644000175000001440000002321011377105536025211 0ustar00gabeusers00000000000000// // HyenaSqliteCommand.cs // // Authors: // Aaron Bockover // Gabriel Burt // // Copyright (C) 2007-2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.IO; using System.Data; using System.Text; using System.Threading; using Mono.Data.Sqlite; namespace Hyena.Data.Sqlite { public class CommandExecutedArgs : EventArgs { public CommandExecutedArgs (string sql, int ms) { Sql = sql; Ms = ms; } public string Sql; public int Ms; } public class HyenaSqliteCommand { private object result = null; private Exception execution_exception = null; private bool finished = false; private ManualResetEvent finished_event = new ManualResetEvent (true); private string command; private string command_format = null; private string command_formatted = null; private int parameter_count = 0; private object [] current_values; private int ticks; public string Text { get { return command; } } internal HyenaCommandType CommandType; public HyenaSqliteCommand (string command) { this.command = command; } public HyenaSqliteCommand (string command, params object [] param_values) { this.command = command; ApplyValues (param_values); } internal void Execute (HyenaSqliteConnection hconnection, SqliteConnection connection) { if (finished) { throw new Exception ("Command is already set to finished; result needs to be claimed before command can be rerun"); } execution_exception = null; result = null; int execution_ms = 0; using (SqliteCommand sql_command = new SqliteCommand (CurrentSqlText)) { sql_command.Connection = connection; hconnection.OnExecuting (sql_command); try { ticks = System.Environment.TickCount; switch (CommandType) { case HyenaCommandType.Reader: using (SqliteDataReader reader = sql_command.ExecuteReader ()) { result = new HyenaSqliteArrayDataReader (reader); } break; case HyenaCommandType.Scalar: result = sql_command.ExecuteScalar (); break; case HyenaCommandType.Execute: default: sql_command.ExecuteNonQuery (); result = sql_command.LastInsertRowID (); break; } execution_ms = System.Environment.TickCount - ticks; if (log_all) { Log.DebugFormat ("Executed in {0}ms {1}", execution_ms, sql_command.CommandText); } } catch (Exception e) { Log.DebugFormat ("Exception executing command: {0}", sql_command.CommandText); execution_exception = e; } } // capture the text string raise_text = null; if (raise_command_executed && execution_ms >= raise_command_executed_threshold_ms) { raise_text = Text; } finished_event.Reset (); finished = true; if (raise_command_executed && execution_ms >= raise_command_executed_threshold_ms) { var handler = CommandExecuted; if (handler != null) { // Don't raise this on this thread; this thread is dedicated for use by the db connection ThreadAssist.ProxyToMain (delegate { handler (this, new CommandExecutedArgs (raise_text, execution_ms)); }); } } } internal object WaitForResult (HyenaSqliteConnection conn) { while (!finished) { conn.ResultReadySignal.WaitOne (); } // Reference the results since they could be overwritten object ret = result; var exception = execution_exception; // Reset to false in case run again finished = false; conn.ClaimResult (); finished_event.Set (); if (exception != null) { throw exception; } return ret; } internal void WaitIfNotFinished () { finished_event.WaitOne (); } internal HyenaSqliteCommand ApplyValues (params object [] param_values) { if (command_format == null) { CreateParameters (); } // Special case for if a single null values is the paramter array if (parameter_count == 1 && param_values == null) { current_values = new object [] { "NULL" }; command_formatted = null; return this; } if (param_values.Length != parameter_count) { throw new ArgumentException (String.Format ( "Command {2} has {0} parameters, but {1} values given.", parameter_count, param_values.Length, command )); } // Transform values as necessary - not needed for numerical types for (int i = 0; i < parameter_count; i++) { param_values[i] = SqlifyObject (param_values[i]); } current_values = param_values; command_formatted = null; return this; } public static object SqlifyObject (object o) { if (o is string) { return String.Format ("'{0}'", (o as string).Replace ("'", "''")); } else if (o is DateTime) { return DateTimeUtil.FromDateTime ((DateTime) o); } else if (o is bool) { return ((bool)o) ? "1" : "0"; } else if (o == null) { return "NULL"; } else if (o is byte[]) { string hex = BitConverter.ToString (o as byte[]).Replace ("-", ""); return String.Format ("X'{0}'", hex); } else if (o is Array) { StringBuilder sb = new StringBuilder (); bool first = true; foreach (object i in (o as Array)) { if (!first) sb.Append (","); else first = false; sb.Append (SqlifyObject (i)); } return sb.ToString (); } else { return o; } } private string CurrentSqlText { get { if (command_format == null) { return command; } if (command_formatted == null) { command_formatted = String.Format (System.Globalization.CultureInfo.InvariantCulture, command_format, current_values); } return command_formatted; } } private void CreateParameters () { StringBuilder sb = new StringBuilder (); foreach (char c in command) { if (c == '?') { sb.Append ('{'); sb.Append (parameter_count++); sb.Append ('}'); } else { sb.Append (c); } } command_format = sb.ToString (); } #region Static Debugging Facilities private static bool log_all = false; public static bool LogAll { get { return log_all; } set { log_all = value; } } public delegate void CommandExecutedHandler (object o, CommandExecutedArgs args); public static event CommandExecutedHandler CommandExecuted; private static bool raise_command_executed = false; public static bool RaiseCommandExecuted { get { return raise_command_executed; } set { raise_command_executed = value; } } private static int raise_command_executed_threshold_ms = 400; public static int RaiseCommandExecutedThresholdMs { get { return raise_command_executed_threshold_ms; } set { raise_command_executed_threshold_ms = value; } } #endregion } } hyena-0.5/COPYING0000644000175000001440000000204511377073562013646 0ustar00gabeusers00000000000000Copyright (C) 2005-2010 Novell, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. hyena-0.5/Hyena.Gui/0000777000175000001440000000000011453151003014363 5ustar00gabeusers00000000000000hyena-0.5/Hyena.Gui/Hyena.Widgets/0000777000175000001440000000000011453151003017034 5ustar00gabeusers00000000000000hyena-0.5/Hyena.Gui/Hyena.Widgets/MessageBar.cs0000644000175000001440000001340111377105500021375 0ustar00gabeusers00000000000000// // MessageBar.cs // // Author: // Aaron Bockover // // Copyright (C) 2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using Gtk; using Hyena.Gui; using Hyena.Gui.Theming; namespace Hyena.Widgets { public class MessageBar : Alignment { private HBox box; private HBox button_box; private AnimatedImage image; private WrapLabel label; private Button close_button; private Window win; private Theme theme; public event EventHandler CloseClicked { add { close_button.Clicked += value; } remove { close_button.Clicked -= value; } } public MessageBar () : base (0.0f, 0.5f, 1.0f, 0.0f) { win = new Window (WindowType.Popup); win.Name = "gtk-tooltips"; win.EnsureStyle (); win.StyleSet += delegate { Style = win.Style; }; HBox shell_box = new HBox (); shell_box.Spacing = 10; box = new HBox (); box.Spacing = 10; image = new AnimatedImage (); try { image.Pixbuf = Gtk.IconTheme.Default.LoadIcon ("process-working", 22, IconLookupFlags.NoSvg); image.FrameHeight = 22; image.FrameWidth = 22; Spinning = false; image.Load (); } catch { } label = new WrapLabel (); label.Show (); box.PackStart (image, false, false, 0); box.PackStart (label, true, true, 0); box.Show (); button_box = new HBox (); button_box.Spacing = 3; close_button = new Button (new Image (Stock.Close, IconSize.Menu)); close_button.Relief = ReliefStyle.None; close_button.Clicked += delegate { Hide (); }; close_button.ShowAll (); close_button.Hide (); shell_box.PackStart (box, true, true, 0); shell_box.PackStart (button_box, false, false, 0); shell_box.PackStart (close_button, false, false, 0); shell_box.Show (); Add (shell_box); EnsureStyle (); BorderWidth = 3; } protected override void OnShown () { base.OnShown (); image.Show (); } protected override void OnHidden () { base.OnHidden (); image.Hide (); } protected override void OnRealized () { base.OnRealized (); theme = Hyena.Gui.Theming.ThemeEngine.CreateTheme (this); } protected override void OnSizeAllocated (Gdk.Rectangle allocation) { base.OnSizeAllocated (allocation); QueueDraw (); } protected override bool OnExposeEvent (Gdk.EventExpose evnt) { if (!IsDrawable) { return false; } Cairo.Context cr = Gdk.CairoHelper.Create (evnt.Window); try { Gdk.Color color = Style.Background (StateType.Normal); theme.DrawFrame (cr, Allocation, CairoExtensions.GdkColorToCairoColor (color)); return base.OnExposeEvent (evnt); } finally { CairoExtensions.DisposeContext (cr); } } private bool changing_style = false; protected override void OnStyleSet (Gtk.Style previousStyle) { if (changing_style) { return; } changing_style = true; Style = win.Style; label.Style = Style; changing_style = false; } public void RemoveButton (Button button) { button_box.Remove (button); } public void ClearButtons () { foreach (Widget child in button_box.Children) { button_box.Remove (child); } } public void AddButton (Button button) { button_box.Show (); button.Show (); button_box.PackStart (button, false, false, 0); } public bool ShowCloseButton { set { close_button.Visible = value; QueueDraw (); } } public string Message { set { label.Markup = value; QueueDraw (); } } public Gdk.Pixbuf Pixbuf { set { image.InactivePixbuf = value; QueueDraw (); } } public bool Spinning { get { return image.Active; } set { image.Active = value; } } } } hyena-0.5/Hyena.Gui/Hyena.Widgets/RatingEntry.cs0000644000175000001440000003653511436010340021640 0ustar00gabeusers00000000000000// // RatingEntry.cs // // Authors: // Aaron Bockover // Gabriel Burt // // Copyright (C) 2006-2008 Novell, Inc. // Copyright (C) 2006 Gabriel Burt // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using Gtk; using System; using Hyena.Gui; namespace Hyena.Widgets { public class RatingEntry : Widget { private RatingRenderer renderer; private Gdk.Rectangle event_alloc; private int hover_value = -1; private bool interior_focus; private int focus_width; private Gdk.Window event_window; public event EventHandler Changing; public event EventHandler Changed; static RatingEntry () { #if ENABLE_ATK RatingAccessibleFactory.Init (); #endif } public RatingEntry () : this (0) { WidgetFlags |= Gtk.WidgetFlags.NoWindow; } public RatingEntry (int rating) : this (rating, new RatingRenderer ()) { } protected RatingEntry (int rating, RatingRenderer renderer) { this.renderer = renderer; this.renderer.Value = rating; CanFocus = true; Name = "GtkEntry"; } protected virtual void OnChanging () { EventHandler handler = Changing; if (handler != null) { handler (this, new EventArgs ()); } } protected virtual void OnChanged () { QueueDraw (); EventHandler handler = Changed; if (handler != null) { handler (this, new EventArgs ()); } } internal void SetValueFromPosition (int x) { Value = renderer.RatingFromPosition (event_alloc, x); } #region Public Properties private bool always_show_empty_stars = false; public bool AlwaysShowEmptyStars { get { return always_show_empty_stars; } set { always_show_empty_stars = value; } } private bool preview_on_hover = true; public bool PreviewOnHover { get { return preview_on_hover; } set { preview_on_hover = value; } } private bool has_frame = true; public bool HasFrame { get { return has_frame; } set { has_frame = value; QueueResize (); } } public int Value { get { return renderer.Value; } set { if (renderer.Value != value && renderer.Value >= renderer.MinRating && value <= renderer.MaxRating) { renderer.Value = value; OnChanging (); OnChanged (); } } } public int MaxRating { get { return renderer.MaxRating; } set { renderer.MaxRating = value; } } public int MinRating { get { return renderer.MinRating; } set { renderer.MinRating = value; } } public int RatingLevels { get { return renderer.RatingLevels; } } private object rated_object; public object RatedObject { get { return rated_object; } set { rated_object = value; } } #endregion #region Protected Gtk.Widget Overrides protected override void OnRealized () { WidgetFlags |= WidgetFlags.Realized | WidgetFlags.NoWindow; GdkWindow = Parent.GdkWindow; Gdk.WindowAttr attributes = new Gdk.WindowAttr (); attributes.WindowType = Gdk.WindowType.Child; attributes.X = Allocation.X; attributes.Y = Allocation.Y; attributes.Width = Allocation.Width; attributes.Height = Allocation.Height; attributes.Wclass = Gdk.WindowClass.InputOnly; attributes.EventMask = (int)( Gdk.EventMask.PointerMotionMask | Gdk.EventMask.EnterNotifyMask | Gdk.EventMask.LeaveNotifyMask | Gdk.EventMask.KeyPressMask | Gdk.EventMask.KeyReleaseMask | Gdk.EventMask.ButtonPressMask | Gdk.EventMask.ButtonReleaseMask | Gdk.EventMask.ExposureMask); Gdk.WindowAttributesType attributes_mask = Gdk.WindowAttributesType.X | Gdk.WindowAttributesType.Y | Gdk.WindowAttributesType.Wmclass; event_window = new Gdk.Window (GdkWindow, attributes, attributes_mask); event_window.UserData = Handle; Style = Gtk.Rc.GetStyleByPaths (Settings, "*.GtkEntry", "*.GtkEntry", GType); base.OnRealized (); } protected override void OnUnrealized () { WidgetFlags &= ~WidgetFlags.Realized; event_window.UserData = IntPtr.Zero; Hyena.Gui.GtkWorkarounds.WindowDestroy (event_window); event_window = null; base.OnUnrealized (); } protected override void OnMapped () { WidgetFlags |= WidgetFlags.Mapped; event_window.Show (); } protected override void OnUnmapped () { WidgetFlags &= ~WidgetFlags.Mapped; event_window.Hide (); } private bool changing_style; protected override void OnStyleSet (Style previous_style) { if (changing_style) { return; } base.OnStyleSet (previous_style); changing_style = true; focus_width = (int)StyleGetProperty ("focus-line-width"); interior_focus = (bool)StyleGetProperty ("interior-focus"); changing_style = false; } protected override void OnSizeAllocated (Gdk.Rectangle allocation) { base.OnSizeAllocated (allocation); event_alloc = new Gdk.Rectangle (0, 0, allocation.Width, allocation.Height); if (IsRealized) { event_window.MoveResize (allocation); } } protected override void OnSizeRequested (ref Gtk.Requisition requisition) { EnsureStyle (); Pango.FontMetrics metrics = PangoContext.GetMetrics (Style.FontDescription, PangoContext.Language); renderer.Size = ((int)(metrics.Ascent + metrics.Descent) + 512) >> 10; // PANGO_PIXELS(d) metrics.Dispose (); if (HasFrame) { renderer.Xpad = Style.Xthickness + (interior_focus ? focus_width : 0) + 2; renderer.Ypad = Style.Ythickness + (interior_focus ? focus_width : 0) + 2; } else { renderer.Xpad = 0; renderer.Ypad = 0; } requisition.Width = renderer.Width; requisition.Height = renderer.Height; } protected override bool OnExposeEvent (Gdk.EventExpose evnt) { if (evnt.Window != GdkWindow) { return true; } if (HasFrame) { int y_mid = (int)Math.Round ((Allocation.Height - renderer.Height) / 2.0); Gtk.Style.PaintFlatBox (Style, GdkWindow, State, ShadowType.None, evnt.Area, this, "entry", Allocation.X, Allocation.Y + y_mid, Allocation.Width, renderer.Height); Gtk.Style.PaintShadow (Style, GdkWindow, State, ShadowType.In, evnt.Area, this, "entry", Allocation.X, Allocation.Y + y_mid, Allocation.Width, renderer.Height); } Cairo.Context cr = Gdk.CairoHelper.Create (GdkWindow); renderer.Render (cr, Allocation, CairoExtensions.GdkColorToCairoColor (HasFrame ? Parent.Style.Text (State) : Parent.Style.Foreground (State)), AlwaysShowEmptyStars, PreviewOnHover && hover_value >= renderer.MinRating, hover_value, State == StateType.Insensitive ? 1 : 0.90, State == StateType.Insensitive ? 1 : 0.55, State == StateType.Insensitive ? 1 : 0.45); CairoExtensions.DisposeContext (cr); return true; } protected override bool OnButtonPressEvent (Gdk.EventButton evnt) { if (evnt.Button != 1) { return false; } HasFocus = true; Value = renderer.RatingFromPosition (event_alloc, evnt.X); return true; } protected override bool OnEnterNotifyEvent (Gdk.EventCrossing evnt) { hover_value = renderer.MinRating; QueueDraw (); return true; } protected override bool OnLeaveNotifyEvent (Gdk.EventCrossing crossing) { return HandleLeaveNotify (crossing); } protected override bool OnMotionNotifyEvent (Gdk.EventMotion motion) { return HandleMotionNotify (motion.State, motion.X); } protected override bool OnKeyPressEvent (Gdk.EventKey evnt) { switch (evnt.Key) { case Gdk.Key.Up: case Gdk.Key.Right: case Gdk.Key.plus: case Gdk.Key.equal: Value++; return true; case Gdk.Key.Down: case Gdk.Key.Left: case Gdk.Key.minus: Value--; return true; } if (evnt.KeyValue >= (48 + MinRating) && evnt.KeyValue <= (48 + MaxRating) && evnt.KeyValue <= 59) { Value = (int)evnt.KeyValue - 48; return true; } return false; } protected override bool OnScrollEvent (Gdk.EventScroll args) { return HandleScroll (args); } #endregion #region Internal API, primarily for RatingMenuItem internal void ClearHover () { hover_value = renderer.MinRating - 1; } internal bool HandleKeyPress (Gdk.EventKey evnt) { return this.OnKeyPressEvent (evnt); } internal bool HandleScroll (Gdk.EventScroll args) { switch (args.Direction) { case Gdk.ScrollDirection.Up: case Gdk.ScrollDirection.Right: Value++; return true; case Gdk.ScrollDirection.Down: case Gdk.ScrollDirection.Left: Value--; return true; } return false; } internal bool HandleMotionNotify (Gdk.ModifierType state, double x) { hover_value = renderer.RatingFromPosition (event_alloc, x); /*if ((state & Gdk.ModifierType.Button1Mask) != 0) { Value = hover_value; }*/ QueueDraw (); return true; } internal bool HandleLeaveNotify (Gdk.EventCrossing crossing) { ClearHover (); QueueDraw (); return true; } #endregion } #region Test Module #if ENABLE_ATK public class RatingAccessible : Atk.Object, Atk.Value, Atk.ValueImplementor { private RatingEntry rating; public RatingAccessible (IntPtr raw) : base (raw) { Hyena.Log.Information ("RatingAccessible raw ctor.."); } public RatingAccessible (GLib.Object widget): base () { rating = widget as RatingEntry; Name = "Rating entry"; Description = "Rating entry, from 0 to 5 stars"; Role = Atk.Role.Slider; } public void GetMaximumValue (ref GLib.Value val) { val = new GLib.Value (5); } public void GetMinimumIncrement (ref GLib.Value val) { val = new GLib.Value (1); } public void GetMinimumValue (ref GLib.Value val) { val = new GLib.Value (0); } public void GetCurrentValue (ref GLib.Value val) { val = new GLib.Value (rating.Value); } public bool SetCurrentValue (GLib.Value val) { int r = (int) val.Val; if (r <= 0 || r > 5) { return false; } rating.Value = (int) val.Val; return true; } } #endif #if ENABLE_ATK internal class RatingAccessibleFactory : Atk.ObjectFactory { public static void Init () { new RatingAccessibleFactory (); Atk.Global.DefaultRegistry.SetFactoryType ((GLib.GType)typeof (RatingEntry), (GLib.GType)typeof (RatingAccessibleFactory)); } protected override Atk.Object OnCreateAccessible (GLib.Object obj) { return new RatingAccessible (obj); } protected override GLib.GType OnGetAccessibleType () { return RatingAccessible.GType; } } #endif [Hyena.Gui.TestModule ("Rating Entry")] internal class RatingEntryTestModule : Gtk.Window { public RatingEntryTestModule () : base ("Rating Entry") { VBox pbox = new VBox (); Add (pbox); Menu m = new Menu (); MenuBar b = new MenuBar (); MenuItem item = new MenuItem ("Rate Me!"); item.Submenu = m; b.Append (item); m.Append (new MenuItem ("Apples")); m.Append (new MenuItem ("Pears")); m.Append (new RatingMenuItem ()); m.Append (new ImageMenuItem ("gtk-remove", null)); m.ShowAll (); pbox.PackStart (b, false, false, 0); VBox box = new VBox (); box.BorderWidth = 10; box.Spacing = 10; pbox.PackStart (box, true, true, 0); RatingEntry entry1 = new RatingEntry (); box.PackStart (entry1, true, true, 0); RatingEntry entry2 = new RatingEntry (); box.PackStart (entry2, false, false, 0); box.PackStart (new Entry ("Normal GtkEntry"), false, false, 0); RatingEntry entry3 = new RatingEntry (); Pango.FontDescription fd = entry3.PangoContext.FontDescription.Copy (); fd.Size = (int)(fd.Size * Pango.Scale.XXLarge); entry3.ModifyFont (fd); fd.Dispose (); box.PackStart (entry3, true, true, 0); pbox.ShowAll (); } } #endregion } hyena-0.5/Hyena.Gui/Hyena.Widgets/HigMessageDialog.cs0000644000175000001440000002025311377105500022523 0ustar00gabeusers00000000000000// // HigMessageDialog.cs // // Authors: // Aaron Bockover // // Copyright (C) 2007 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; namespace Hyena.Widgets { public class HigMessageDialog : Gtk.Dialog { private Gtk.Image image; private Gtk.VBox inner_vbox; private Gtk.VBox label_vbox; private Gtk.Label message_label; public HigMessageDialog(Gtk.Window parent, Gtk.DialogFlags flags, Gtk.MessageType type, Gtk.ButtonsType buttons, string header, string msg) : base() { HasSeparator = false; BorderWidth = 5; Resizable = false; Title = ""; SkipTaskbarHint = true; VBox.Spacing = 12; ActionArea.Layout = Gtk.ButtonBoxStyle.End; Gtk.HBox hbox = new Gtk.HBox (false, 12); hbox.BorderWidth = 5; hbox.Show (); VBox.PackStart (hbox, false, false, 0); image = null; switch (type) { case Gtk.MessageType.Error: image = new Gtk.Image (Gtk.Stock.DialogError, Gtk.IconSize.Dialog); break; case Gtk.MessageType.Question: image = new Gtk.Image (Gtk.Stock.DialogQuestion, Gtk.IconSize.Dialog); break; case Gtk.MessageType.Info: image = new Gtk.Image (Gtk.Stock.DialogInfo, Gtk.IconSize.Dialog); break; case Gtk.MessageType.Warning: image = new Gtk.Image (Gtk.Stock.DialogWarning, Gtk.IconSize.Dialog); break; } image.Yalign = 0.1f; image.Show (); hbox.PackStart (image, false, false, 0); inner_vbox = new Gtk.VBox (false, 12); inner_vbox.Show (); hbox.PackStart (inner_vbox, true, true, 0); label_vbox = new Gtk.VBox (false, 0); label_vbox.Show (); inner_vbox.PackStart (label_vbox, true, true, 0); string title = String.Format ("{0}" + "\n", header); Gtk.Label label; label = new Gtk.Label (title); label.UseMarkup = true; label.Justify = Gtk.Justification.Left; label.LineWrap = true; label.SetAlignment (0.0f, 0.5f); label.Show (); label_vbox.PackStart (label, false, false, 0); message_label = label = new Gtk.Label (); label.Markup = msg; label.UseMarkup = true; label.Justify = Gtk.Justification.Left; label.LineWrap = true; label.SetAlignment (0.0f, 0.5f); label.Show (); label_vbox.PackStart (label, false, false, 0); switch (buttons) { case Gtk.ButtonsType.None: break; case Gtk.ButtonsType.Ok: AddButton (Gtk.Stock.Ok, Gtk.ResponseType.Ok, true); break; case Gtk.ButtonsType.Close: AddButton (Gtk.Stock.Close, Gtk.ResponseType.Close, true); break; case Gtk.ButtonsType.Cancel: AddButton (Gtk.Stock.Cancel, Gtk.ResponseType.Cancel, true); break; case Gtk.ButtonsType.YesNo: AddButton (Gtk.Stock.No, Gtk.ResponseType.No, false); AddButton (Gtk.Stock.Yes, Gtk.ResponseType.Yes, true); break; case Gtk.ButtonsType.OkCancel: AddButton (Gtk.Stock.Cancel, Gtk.ResponseType.Cancel, false); AddButton (Gtk.Stock.Ok, Gtk.ResponseType.Ok, true); break; } if (parent != null) TransientFor = parent; if ((int) (flags & Gtk.DialogFlags.Modal) != 0) Modal = true; if ((int) (flags & Gtk.DialogFlags.DestroyWithParent) != 0) DestroyWithParent = true; } // constructor for a HIG confirmation alert with two buttons public HigMessageDialog (Gtk.Window parent, Gtk.DialogFlags flags, Gtk.MessageType type, string header, string msg, string ok_caption) : this (parent, flags, type, Gtk.ButtonsType.Cancel, header, msg) { AddButton (ok_caption, Gtk.ResponseType.Ok, false); } public Gtk.Button AddCustomButton (string message, Gtk.ResponseType response, bool isDefault) { Gtk.Button button = new Gtk.Button (); button.Label = message; button.CanDefault = true; button.Show (); AddButton (button, response, isDefault); return button; } public void AddButton (string stock_id, Gtk.ResponseType response, bool isDefault) { Gtk.Button button = new Gtk.Button (stock_id); button.CanDefault = true; button.Show (); AddButton (button, response, isDefault); } private void AddButton (Gtk.Button button, Gtk.ResponseType response, bool isDefault) { AddActionWidget (button, response); if (isDefault) { Default = button; DefaultResponse = response; button.GrabDefault (); } } //run and destroy a standard dialog public static Gtk.ResponseType RunHigMessageDialog(Gtk.Window parent, Gtk.DialogFlags flags, Gtk.MessageType type, Gtk.ButtonsType buttons, string header, string msg) { HigMessageDialog hmd = new HigMessageDialog(parent, flags, type, buttons, header, msg); try { return (Gtk.ResponseType)hmd.Run(); } finally { hmd.Destroy(); } } //Run and destroy a standard confirmation dialog public static Gtk.ResponseType RunHigConfirmation(Gtk.Window parent, Gtk.DialogFlags flags, Gtk.MessageType type, string header, string msg, string ok_caption) { HigMessageDialog hmd = new HigMessageDialog(parent, flags, type, header, msg, ok_caption); try { return (Gtk.ResponseType)hmd.Run(); } finally { hmd.Destroy(); } } public Gdk.Pixbuf Image { set { image.Pixbuf = value; } get { return image.Pixbuf; } } public Gtk.Label MessageLabel { get { return message_label; } } public Gtk.VBox LabelVBox { get { return inner_vbox; } } } } hyena-0.5/Hyena.Gui/Hyena.Widgets/SmoothScrolledWindow.cs0000644000175000001440000001076711377105500023531 0ustar00gabeusers00000000000000// SmoothScrolledWindow.cs // // Copyright (c) 2008 Scott Peterson // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // using System; using Gdk; using Gtk; using Hyena.Gui.Theatrics; namespace Hyena.Widgets { public class SmoothScrolledWindow : Gtk.ScrolledWindow { private bool ignore_value_changed; private uint timeout; private double value; private double target_value; private double velocity = 0; private double Accelerate (double velocity) { return AccelerateCore (velocity); } private double Decelerate (double velocity) { return Math.Max (DecelerateCore (velocity), 0); } protected virtual double AccelerateCore (double velocity) { return velocity + 8; } protected virtual double DecelerateCore (double velocity) { return velocity - Math.Max (3, 0.2 * velocity); } private double TargetValue { get { return target_value; } set { if (value == target_value) { return; } target_value = value; if (timeout == 0) { timeout = GLib.Timeout.Add (20, OnTimeout); } } } // Smoothly get us to the target value private bool OnTimeout () { double delta = target_value - value; if (delta == 0) { velocity = 0; timeout = 0; return false; } int sign = Math.Sign (delta); delta = Math.Abs (delta); double hypothetical = delta; double v = Accelerate (velocity); while (v > 0 && hypothetical > 0) { hypothetical -= v; v = Decelerate (v); } velocity = hypothetical <= 0 ? Decelerate (velocity) : Accelerate (velocity); // Minimum speed: 2 px / 20 ms = 100px / second value = Math.Round (value + Math.Max (velocity, 2) * sign); // Don't go past the target value value = (sign == 1) ? Math.Min (value, target_value) : Math.Max (value, target_value); ignore_value_changed = true; Vadjustment.Value = Math.Round (value); ignore_value_changed = false; return true; } protected override bool OnScrollEvent (Gdk.EventScroll evnt) { switch (evnt.Direction) { case ScrollDirection.Up: TargetValue = Math.Max (TargetValue - Vadjustment.StepIncrement, 0); break; case ScrollDirection.Down: TargetValue = Math.Min (TargetValue + Vadjustment.StepIncrement, Vadjustment.Upper - Vadjustment.PageSize); break; default: return base.OnScrollEvent (evnt); } return true; } protected override void OnRealized () { base.OnRealized (); Vadjustment.ValueChanged += OnValueChanged; } protected override void OnUnrealized () { Vadjustment.ValueChanged -= OnValueChanged; base.OnUnrealized (); } private void OnValueChanged (object o, EventArgs args) { if (!ignore_value_changed) { value = target_value = Vadjustment.Value; } } } } hyena-0.5/Hyena.Gui/Hyena.Widgets/AnimatedVBox.cs0000644000175000001440000000267511377105500021720 0ustar00gabeusers00000000000000// // AnimatedVBox.cs // // Authors: // Scott Peterson // // Copyright (C) 2008 Scott Peterson // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using Gdk; using Gtk; namespace Hyena.Widgets { public class AnimatedVBox : AnimatedBox { public AnimatedVBox () : base (false) { } protected AnimatedVBox (IntPtr raw) : base (raw) { } } }hyena-0.5/Hyena.Gui/Hyena.Widgets/AnimatedHBox.cs0000644000175000001440000000267511377105500021702 0ustar00gabeusers00000000000000// // AnimatedHBox.cs // // Authors: // Scott Peterson // // Copyright (C) 2008 Scott Peterson // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using Gdk; using Gtk; namespace Hyena.Widgets { public class AnimatedHBox : AnimatedBox { public AnimatedHBox () : base (true) { } protected AnimatedHBox (IntPtr raw) : base (raw) { } } } hyena-0.5/Hyena.Gui/Hyena.Widgets/TextViewEditable.cs0000644000175000001440000001173011377105500022600 0ustar00gabeusers00000000000000// // TextViewEditable.cs // // Author: // Aaron Bockover // // Copyright (C) 2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using Gtk; namespace Hyena.Widgets { public class TextViewEditable : TextView, Editable { public TextViewEditable () { Buffer.Changed += OnBufferChanged; Buffer.InsertText += OnBufferInsertText; Buffer.DeleteRange += OnBufferDeleteRange; } public event EventHandler Changed; public event TextDeletedHandler TextDeleted; public event TextInsertedHandler TextInserted; private void OnBufferChanged (object o, EventArgs args) { EventHandler handler = Changed; if (handler != null) { handler (this, EventArgs.Empty); } } private void OnBufferInsertText (object o, InsertTextArgs args) { TextInsertedHandler handler = TextInserted; if (handler != null) { TextInsertedArgs raise_args = new TextInsertedArgs (); raise_args.Args = new object [] { args.Text, args.Length, args.Pos.Offset }; handler (this, raise_args); } } private void OnBufferDeleteRange (object o, DeleteRangeArgs args) { TextDeletedHandler handler = TextDeleted; if (handler != null) { TextDeletedArgs raise_args = new TextDeletedArgs (); raise_args.Args = new object [] { args.Start.Offset, args.End.Offset }; handler (this, raise_args); } } void Editable.PasteClipboard () { } void Editable.CutClipboard () { } void Editable.CopyClipboard () { } public void DeleteText (int start_pos, int end_pos) { start_pos--; end_pos--; TextIter start_iter = Buffer.GetIterAtOffset (start_pos); TextIter end_iter = Buffer.GetIterAtOffset (start_pos + (end_pos - start_pos)); Buffer.Delete (ref start_iter, ref end_iter); } public void InsertText (string new_text, ref int position) { TextIter iter = Buffer.GetIterAtOffset (position - 1); Buffer.Insert (ref iter, new_text); position = iter.Offset + 1; } public string GetChars (int start_pos, int end_pos) { start_pos--; end_pos--; TextIter start_iter = Buffer.GetIterAtOffset (start_pos); TextIter end_iter = Buffer.GetIterAtOffset (start_pos + (end_pos - start_pos)); return Buffer.GetText (start_iter, end_iter, true); } public void SelectRegion (int start, int end) { Buffer.SelectRange (Buffer.GetIterAtOffset (start - 1), Buffer.GetIterAtOffset (end - 1)); } public bool GetSelectionBounds (out int start, out int end) { TextIter start_iter, end_iter; start = 0; end = 0; if (Buffer.GetSelectionBounds (out start_iter, out end_iter)) { start = start_iter.Offset + 1; end = end_iter.Offset + 1; return true; } return true; } public void DeleteSelection () { TextIter start, end; if (Buffer.GetSelectionBounds (out start, out end)) { Buffer.Delete (ref start, ref end); } } public int Position { get { return Buffer.CursorPosition; } set { Buffer.PlaceCursor (Buffer.GetIterAtOffset (Position)); } } public bool IsEditable { get { return Editable; } set { Editable = value; } } } } hyena-0.5/Hyena.Gui/Hyena.Widgets/PulsingButton.cs0000644000175000001440000001012011377105500022174 0ustar00gabeusers00000000000000// // PulsingButton.cs // // Author: // Aaron Bockover // // Copyright (C) 2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using Gtk; using Hyena.Gui; using Hyena.Gui.Theatrics; namespace Hyena.Widgets { public class PulsingButton : Button { private static Stage default_stage; public static Stage DefaultStage { get { if (default_stage == null) { default_stage = new Stage (); default_stage.DefaultActorDuration = 1250; } return default_stage; } } private Pulsator pulsator = new Pulsator (); public Stage Stage { get { return pulsator.Stage; } set { pulsator.Stage = value; } } public PulsingButton () : base () { Setup (); } public PulsingButton (string stock_id) : base (stock_id) { Setup (); } public PulsingButton (Widget widget) : base (widget) { Setup (); } protected PulsingButton (IntPtr raw) : base (raw) { Setup (); } private void Setup () { Stage = DefaultStage; pulsator.Target = this; pulsator.Pulse += delegate { QueueDraw (); }; } protected override bool OnExposeEvent (Gdk.EventExpose evnt) { if (!pulsator.IsPulsing) { return base.OnExposeEvent (evnt); } Cairo.Context cr = Gdk.CairoHelper.Create (GdkWindow); double x = Allocation.X + Allocation.Width / 2; double y = Allocation.Y + Allocation.Height / 2; double r = Math.Min (Allocation.Width, Allocation.Height) / 2; double alpha = Choreographer.Compose (pulsator.Percent, Easing.Sine); Cairo.Color color = CairoExtensions.GdkColorToCairoColor (Style.Background (StateType.Selected)); Cairo.RadialGradient fill = new Cairo.RadialGradient (x, y, 0, x, y, r); color.A = alpha; fill.AddColorStop (0, color); fill.AddColorStop (0.5, color); color.A = 0; fill.AddColorStop (1, color); cr.Arc (x, y, r, 0, 2 * Math.PI); cr.Pattern = fill; cr.Fill (); fill.Destroy (); CairoExtensions.DisposeContext (cr); return base.OnExposeEvent (evnt); } public void StartPulsing () { if (IsMapped && Sensitive) { pulsator.StartPulsing (); } } public void StopPulsing () { pulsator.StopPulsing (); } protected override void OnStateChanged (StateType previous_state) { base.OnStateChanged (previous_state); if (State == StateType.Insensitive) { StopPulsing (); } } } } hyena-0.5/Hyena.Gui/Hyena.Widgets/ImageButton.cs0000644000175000001440000000461411377105500021610 0ustar00gabeusers00000000000000// // ImageButton.cs // // Authors: // Gabriel Burt // // Copyright (C) 2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using Gtk; namespace Hyena.Widgets { public class ImageButton : Button { private Image image; private Label label; private HBox hbox; public Image ImageWidget { get { return image; } } public Label LabelWidget { get { return label; } } public uint InnerPadding { get { return hbox.BorderWidth; } set { hbox.BorderWidth = value; } } public int Spacing { get { return hbox.Spacing; } set { hbox.Spacing = value; } } public ImageButton (string text, string iconName) : this (text, iconName, Gtk.IconSize.Button) { } public ImageButton (string text, string iconName, Gtk.IconSize iconSize) : base () { image = new Image (); image.IconName = iconName; image.IconSize = (int) iconSize; label = new Label (); label.MarkupWithMnemonic = text; hbox = new HBox (); hbox.Spacing = 2; hbox.PackStart (image, false, false, 0); hbox.PackStart (label, true, true, 0); Child = hbox; CanDefault = true; ShowAll (); } } } hyena-0.5/Hyena.Gui/Hyena.Widgets/ComplexMenuItem.cs0000644000175000001440000001263711377105500022451 0ustar00gabeusers00000000000000// // ComplexMenuItem.cs // // Author: // Aaron Bockover // Gabriel Burt // // Copyright (C) 2007-2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using Gtk; namespace Hyena.Widgets { public class ComplexMenuItem : MenuItem { private bool is_selected = false; public ComplexMenuItem() : base() { } protected ComplexMenuItem (IntPtr raw) : base (raw) { } // Override OnAdded and OnRemoved so we can work with Gtk.Action/Gtk.UIManager // which otherwise would try to replace our child with a Label. private bool first_add = true; protected override void OnAdded (Widget widget) { if (first_add) { first_add = false; base.OnAdded (widget); } } protected override void OnRemoved (Widget widget) { } protected void ConnectChildExpose(Widget widget) { widget.ExposeEvent += OnChildExposeEvent; } [GLib.ConnectBefore] private void OnChildExposeEvent(object o, ExposeEventArgs args) { // NOTE: This is a little insane, but it allows packing of EventBox based widgets // into a GtkMenuItem without breaking the theme (leaving an unstyled void in the item). // This method is called before the EventBox child does its drawing and the background // is filled in with the proper style. int x, y, width, height; Widget widget = (Widget)o; if(IsSelected) { x = Allocation.X - widget.Allocation.X; y = Allocation.Y - widget.Allocation.Y; width = Allocation.Width; height = Allocation.Height; ShadowType shadow_type = (ShadowType)StyleGetProperty("selected-shadow-type"); Gtk.Style.PaintBox(Style, widget.GdkWindow, StateType.Prelight, shadow_type, args.Event.Area, widget, "menuitem", x, y, width, height); } else { // Fill only the visible area in solid color, to be most efficient widget.GdkWindow.DrawRectangle(Parent.Style.BackgroundGC(StateType.Normal), true, 0, 0, widget.Allocation.Width, widget.Allocation.Height); // FIXME: The above should not be necessary, but Clearlooks-based themes apparently // don't provide any style for the menu background so we have to fill it first with // the correct theme color. Weak. // // Do a complete style paint based on the size of the entire menu to be compatible with // themes that provide a real style for "menu" x = Parent.Allocation.X - widget.Allocation.X; y = Parent.Allocation.Y - widget.Allocation.Y; width = Parent.Allocation.Width; height = Parent.Allocation.Height; Gtk.Style.PaintBox(Style, widget.GdkWindow, StateType.Normal, ShadowType.Out, args.Event.Area, widget, "menu", x, y, width, height); } } protected override void OnSelected() { base.OnSelected(); is_selected = true; } protected override void OnDeselected() { base.OnDeselected(); is_selected = false; } protected override void OnParentSet(Widget previous_parent) { if(previous_parent != null) { previous_parent.KeyPressEvent -= OnKeyPressEventProxy; } if(Parent != null) { Parent.KeyPressEvent += OnKeyPressEventProxy; } } [GLib.ConnectBefore] private void OnKeyPressEventProxy(object o, KeyPressEventArgs args) { if(!IsSelected) { return; } switch(args.Event.Key) { case Gdk.Key.Up: case Gdk.Key.Down: case Gdk.Key.Escape: return; } args.RetVal = OnKeyPressEvent(args.Event); } protected override bool OnKeyPressEvent(Gdk.EventKey evnt) { return false; } protected bool IsSelected { get { return is_selected; } } } } hyena-0.5/Hyena.Gui/Hyena.Widgets/MenuButton.cs0000644000175000001440000001332611436010340021463 0ustar00gabeusers00000000000000// // MenuButton.cs // // Author: // Scott Peterson // // Copyright (c) 2008 Scott Peterson // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // using System; using Gtk; using Gdk; namespace Hyena.Widgets { public class MenuButton : Container { private ToggleButton toggle_button = new ToggleButton (); private HBox box = new HBox (); private Alignment alignment; private Arrow arrow; private Widget button_widget; private Menu menu; private Widget size_widget; protected MenuButton (IntPtr ptr) : base (ptr) {} public MenuButton () { } public MenuButton (Widget buttonWidget, Menu menu, bool showArrow) { Construct (buttonWidget, menu, showArrow); } protected void Construct (Widget buttonWidget, Menu menu, bool showArrow) { WidgetFlags |= WidgetFlags.NoWindow; button_widget = buttonWidget; Menu = menu; toggle_button.Parent = this; toggle_button.FocusOnClick = false; toggle_button.Relief = ReliefStyle.None; toggle_button.Pressed += delegate { ShowMenu (); toggle_button.Active = true; }; toggle_button.Activated += delegate { ShowMenu (); }; box.Parent = this; if (showArrow) { box.PackStart (button_widget, true, true, 0); alignment = new Alignment (0f, 0.5f, 0f, 0f); arrow = new Arrow (ArrowType.Down, ShadowType.None); alignment.Add (arrow); box.PackStart (alignment, false, false, 5); size_widget = box; FocusChain = new Widget[] {toggle_button, box}; alignment.ShowAll (); alignment.NoShowAll = true; } else { toggle_button.Add (button_widget); size_widget = toggle_button; } ShowAll (); } public Widget ButtonWidget { get { return button_widget; } } public Menu Menu { get { return menu; } set { if (menu == value) return; if (menu != null) menu.Deactivated -= OnMenuDeactivated; menu = value; menu.Deactivated += OnMenuDeactivated; } } private void OnMenuDeactivated (object o, EventArgs args) { toggle_button.Active = false; } public ToggleButton ToggleButton { get { return toggle_button; } } public Arrow Arrow { get { return arrow; } } public bool ArrowVisible { get { return alignment.Visible; } set { alignment.Visible = value; } } protected override void OnSizeRequested (ref Requisition requisition) { requisition = size_widget.SizeRequest (); } protected override void OnSizeAllocated (Rectangle allocation) { box.SizeAllocate (allocation); toggle_button.SizeAllocate (allocation); base.OnSizeAllocated (allocation); } protected override void ForAll (bool include_internals, Callback callback) { callback (toggle_button); callback (box); } protected override void OnAdded (Widget widget) { } protected override void OnRemoved (Widget widget) { } protected void ShowMenu () { menu.Popup (null, null, PositionMenu, 1, Gtk.Global.CurrentEventTime); } private void PositionMenu (Menu menu, out int x, out int y, out bool push_in) { Gtk.Requisition menu_req = menu.SizeRequest (); int monitor_num = Screen.GetMonitorAtWindow (GdkWindow); Gdk.Rectangle monitor = Screen.GetMonitorGeometry (monitor_num < 0 ? 0 : monitor_num); GdkWindow.GetOrigin (out x, out y); y += Allocation.Y; x += Allocation.X + (Direction == TextDirection.Ltr ? Math.Max (Allocation.Width - menu_req.Width, 0) : - (menu_req.Width - Allocation.Width)); if (y + Allocation.Height + menu_req.Height <= monitor.Y + monitor.Height) { y += Allocation.Height; } else if (y - menu_req.Height >= monitor.Y) { y -= menu_req.Height; } else if (monitor.Y + monitor.Height - (y + Allocation.Height) > y) { y += Allocation.Height; } else { y -= menu_req.Height; } push_in = false; } } } hyena-0.5/Hyena.Gui/Hyena.Widgets/ScrolledWindow.cs0000644000175000001440000000725711377105500022337 0ustar00gabeusers00000000000000// // ScrolledWindow.cs // // Author: // Aaron Bockover // // Copyright (C) 2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Reflection; using Gtk; using Gdk; using Cairo; using Hyena.Gui; using Hyena.Data.Gui; namespace Hyena.Widgets { public class ScrolledWindow : Gtk.ScrolledWindow { private Widget adjustable; private RoundedFrame rounded_frame; public ScrolledWindow () { } public void AddWithFrame (Widget widget) { RoundedFrame frame = new RoundedFrame (); frame.Add (widget); frame.Show (); Add (frame); ProbeAdjustable (widget); } protected override void OnAdded (Widget widget) { if (widget is RoundedFrame) { rounded_frame = (RoundedFrame)widget; rounded_frame.Added += OnFrameWidgetAdded; rounded_frame.Removed += OnFrameWidgetRemoved; } base.OnAdded (widget); } protected override void OnRemoved (Widget widget) { if (widget == rounded_frame) { rounded_frame.Added -= OnFrameWidgetAdded; rounded_frame.Removed -= OnFrameWidgetRemoved; rounded_frame = null; } base.OnRemoved (widget); } private void OnFrameWidgetAdded (object o, AddedArgs args) { if (rounded_frame != null) { ProbeAdjustable (args.Widget); } } private void OnFrameWidgetRemoved (object o, RemovedArgs args) { if (adjustable != null && adjustable == args.Widget) { Hadjustment = null; Vadjustment = null; adjustable = null; } } private void ProbeAdjustable (Widget widget) { Type type = widget.GetType (); PropertyInfo hadj_prop = type.GetProperty ("Hadjustment"); PropertyInfo vadj_prop = type.GetProperty ("Vadjustment"); if (hadj_prop == null || vadj_prop == null) { return; } object hadj_value = hadj_prop.GetValue (widget, null); object vadj_value = vadj_prop.GetValue (widget, null); if (hadj_value == null || vadj_value == null || hadj_value.GetType () != typeof (Adjustment) || vadj_value.GetType () != typeof (Adjustment)) { return; } Hadjustment = (Adjustment)hadj_value; Vadjustment = (Adjustment)vadj_value; } } } hyena-0.5/Hyena.Gui/Hyena.Widgets/AnimatedBox.cs0000644000175000001440000004332511377105500021567 0ustar00gabeusers00000000000000// // AnimatedBox.cs // // Authors: // Scott Peterson // // Copyright (C) 2008 Scott Peterson // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Collections; using System.Collections.Generic; using Gdk; using Gtk; using Hyena.Gui.Theatrics; namespace Hyena.Widgets { public abstract class AnimatedBox : Container { private readonly Stage stage = new Stage (); private readonly LinkedList children = new LinkedList (); private readonly SingleActorStage border_stage = new Hyena.Gui.Theatrics.SingleActorStage (); private readonly bool horizontal; private uint duration = 500; private Easing easing = Easing.Linear; private Blocking blocking = Blocking.Upstage; private int start_padding; private int end_padding; private int spacing; private int start_spacing; private int end_spacing; private int active_count; private int start_border; private int end_border; private double border_bias; private Easing border_easing; private AnimationState border_state; protected AnimatedBox (bool horizontal) { WidgetFlags |= WidgetFlags.NoWindow; this.horizontal = horizontal; stage.ActorStep += OnActorStep; border_stage.Iteration += OnBorderIteration; } protected AnimatedBox (IntPtr raw) : base (raw) { } #region Private private double Percent { get { return border_stage.Actor.Percent * border_bias + (1.0 - border_bias); } } private bool OnActorStep (Actor actor) { switch (actor.Target.AnimationState) { case AnimationState.Coming: actor.Target.Percent = actor.Percent; if (actor.Expired) { actor.Target.AnimationState = AnimationState.Idle; return false; } break; case AnimationState.IntendingToGo: actor.Target.AnimationState = AnimationState.Going; actor.Target.Bias = actor.Percent; actor.Reset ((uint)(actor.Target.Duration * actor.Percent)); break; case AnimationState.Going: if (actor.Expired) { actor.Target.Unparent (); children.Remove (actor.Target.Node); return false; } else { actor.Target.Percent = 1.0 - actor.Percent; } break; } return true; } private void OnBorderIteration (object sender, EventArgs args) { if (border_stage.Actor == null) { if (border_state == AnimationState.Coming) { start_border = start_padding; end_border = end_padding; } else { start_border = end_border = 0; } border_state = AnimationState.Idle; } else { double percent = border_state == AnimationState.Coming ? Percent : 1.0 - Percent; start_border = Choreographer.PixelCompose (percent, start_padding, border_easing); end_border = Choreographer.PixelCompose (percent, end_padding, border_easing); } QueueResizeNoRedraw (); } private void OnWidgetDestroyed (object sender, EventArgs args) { RemoveCore ((AnimatedWidget)sender); } private void RecalculateSpacings () { int skip_count = 0; foreach (AnimatedWidget animated_widget in Widgets) { animated_widget.QueueResizeNoRedraw (); if (skip_count > 1) { skip_count--; continue; } AnimatedWidget widget = animated_widget; if (skip_count == 0) { widget.StartPadding = start_spacing; } else { skip_count--; } widget.EndPadding = end_spacing; if (widget.Node.Previous == null) { while (true) { widget.StartPadding = 0; if (widget.AnimationState == AnimationState.Coming || widget.AnimationState == AnimationState.Idle || widget.Node.Next == null) { break; } widget.EndPadding = spacing; widget = widget.Node.Next.Value; skip_count++; } } if (widget.Node.Next == null) { while (true) { widget.EndPadding = 0; if (widget.AnimationState == AnimationState.Coming || widget.AnimationState == AnimationState.Idle || widget.Node.Previous == null) { break; } widget.StartPadding = spacing; widget = widget.Node.Previous.Value; } } } } #endregion #region Protected Overrides protected override void OnAdded (Widget widget) { PackStart (widget, duration, easing, blocking); } protected override void OnSizeRequested (ref Requisition requisition) { int width = 0; int height = 0; if (horizontal) { width = start_border + end_border; } else { height = start_border + end_border; } foreach (AnimatedWidget widget in Widgets) { Requisition req = widget.SizeRequest (); if (horizontal) { width += req.Width; height = Math.Max (height, req.Height); } else { width = Math.Max (width, req.Width); height += req.Height; } } requisition.Width = width; requisition.Height = height; } protected override void OnSizeAllocated (Rectangle allocation) { base.OnSizeAllocated (allocation); if (horizontal) { allocation.X += start_border; allocation.Y += (int)BorderWidth; allocation.Height -= (int)BorderWidth * 2; } else { allocation.X += (int)BorderWidth; allocation.Y += start_border; allocation.Width -= (int)BorderWidth * 2; } foreach (AnimatedWidget widget in Widgets) { if (horizontal) { allocation.Width = widget.Width; widget.SizeAllocate (allocation); allocation.X += allocation.Width; } else { allocation.Height = widget.Height; widget.SizeAllocate (allocation); allocation.Y += allocation.Height; } } } protected override void ForAll (bool include_internals, Callback callback) { foreach (AnimatedWidget child in Widgets) { callback (child); } } #endregion #region Public #region Properties public uint Duration { get { return duration; } set { duration = value; } } public Easing Easing { get { return easing; } set { easing = value; } } public Blocking Blocking { get { return blocking; } set { blocking = value; } } public int Spacing { get { return spacing; } set { spacing = value; double half = (double)value / 2.0; start_spacing = (int)Math.Ceiling (half); end_spacing = (int)Math.Floor (half); } } public int StartPadding { get { return start_padding - (int)BorderWidth; } set { start_padding = value + (int)BorderWidth; } } public int EndPadding { get { return end_padding - (int)BorderWidth; } set { end_padding = value + (int)BorderWidth; } } internal IEnumerable Widgets { get { foreach (AnimatedWidget child in children) { yield return child; } } } #endregion #region Pack Methods public void PackStart (Widget widget) { PackStart (widget, duration, easing, blocking); } public void PackStart (Widget widget, uint duration) { PackStart (widget, duration, easing, blocking); } public void PackStart (Widget widget, Easing easing) { PackStart (widget, duration, easing, blocking); } public void PackStart (Widget widget, uint duration, Easing easing) { PackStart (widget, duration, easing, blocking); } public void PackStart (Widget widget, Blocking blocking) { PackStart (widget, duration, easing, blocking); } public void PackStart (Widget widget, uint duration, Blocking blocking) { PackStart (widget, duration, easing, blocking); } public void PackStart (Widget widget, Easing easing, Blocking blocking) { PackStart (widget, duration, easing, blocking); } public void PackStart (Widget widget, uint duration, Easing easing, Blocking blocking) { Pack (widget, duration, easing, blocking, false); } public void PackEnd (Widget widget) { PackEnd (widget, duration, easing, blocking); } public void PackEnd (Widget widget, uint duration) { PackEnd (widget, duration, easing, blocking); } public void PackEnd (Widget widget, Easing easing) { PackEnd (widget, duration, easing, blocking); } public void PackEnd (Widget widget, uint duration, Easing easing) { PackEnd (widget, duration, easing, blocking); } public void PackEnd (Widget widget, Blocking blocking) { PackEnd (widget, duration, easing, blocking); } public void PackEnd (Widget widget, uint duration, Blocking blocking) { PackEnd (widget, duration, easing, blocking); } public void PackEnd (Widget widget, Easing easing, Blocking blocking) { PackEnd (widget, duration, easing, blocking); } public void PackEnd (Widget widget, uint duration, Easing easing, Blocking blocking) { Pack (widget, duration, easing, blocking, true); } private void Pack (Widget widget, uint duration, Easing easing, Blocking blocking, bool end) { if (widget == null) { throw new ArgumentNullException ("widget"); } AnimatedWidget animated_widget = new AnimatedWidget (widget, duration, easing, blocking, horizontal); animated_widget.Parent = this; animated_widget.WidgetDestroyed += OnWidgetDestroyed; stage.Add (animated_widget, duration); animated_widget.Node = end ? children.AddLast (animated_widget) : children.AddFirst (animated_widget); RecalculateSpacings (); if (active_count == 0) { if (border_state == AnimationState.Going) { border_bias = Percent; } else { border_easing = easing; border_bias = 1.0; } border_state = AnimationState.Coming; border_stage.Reset ((uint)(duration * border_bias)); } active_count++; } #endregion #region Remove Methods public new void Remove (Widget widget) { RemoveCore (widget, 0, 0, 0, false, false); } public void Remove (Widget widget, uint duration) { RemoveCore (widget, duration, 0, 0, false, false); } public void Remove (Widget widget, Easing easing) { RemoveCore (widget, 0, easing, 0, true, false); } public void Remove (Widget widget, uint duration, Easing easing) { RemoveCore (widget, duration, easing, 0, true, false); } public void Remove (Widget widget, Blocking blocking) { RemoveCore (widget, 0, 0, blocking, false, true); } public void Remove (Widget widget, uint duration, Blocking blocking) { RemoveCore (widget, duration, 0, blocking, false, true); } public void Remove (Widget widget, Easing easing, Blocking blocking) { RemoveCore (widget, 0, easing, blocking, true, true); } public void Remove (Widget widget, uint duration, Easing easing, Blocking blocking) { RemoveCore (widget, duration, easing, blocking, true, true); } private void RemoveCore (Widget widget, uint duration, Easing easing, Blocking blocking, bool use_easing, bool use_blocking) { if (widget == null) { throw new ArgumentNullException ("widget"); } AnimatedWidget animated_widget = null; foreach (AnimatedWidget child in Widgets) { if (child.Widget == widget) { animated_widget = child; break; } } if (animated_widget == null) { throw new ArgumentException ("Cannot remove the specified widget because it has not been added to this container or it has already been removed.", "widget"); } RemoveCore (animated_widget, duration, easing, blocking, use_easing, use_blocking); RecalculateSpacings (); } private void RemoveCore (AnimatedWidget widget) { RemoveCore (widget, widget.Duration, 0, 0, false, false); } private void RemoveCore (AnimatedWidget widget, uint duration, Easing easing, Blocking blocking, bool use_easing, bool use_blocking) { if (duration > 0) { widget.Duration = duration; } if (use_easing) { widget.Easing = easing; } if (use_blocking) { widget.Blocking = blocking; } if (widget.AnimationState == AnimationState.Coming) { widget.AnimationState = AnimationState.IntendingToGo; } else { if (widget.Easing == Easing.QuadraticIn) { widget.Easing = Easing.QuadraticOut; } else if (widget.Easing == Easing.QuadraticOut) { widget.Easing = Easing.QuadraticIn; } else if (widget.Easing == Easing.ExponentialIn) { widget.Easing = Easing.ExponentialOut; } else if (widget.Easing == Easing.ExponentialOut) { widget.Easing = Easing.ExponentialIn; } widget.AnimationState = AnimationState.Going; stage.Add (widget, widget.Duration); } duration = widget.Duration; easing = widget.Easing; active_count--; if (active_count == 0) { if (border_state == AnimationState.Coming) { border_bias = Percent; } else { border_easing = easing; border_bias = 1.0; } border_state = AnimationState.Going; border_stage.Reset ((uint)(duration * border_bias)); } } public void RemoveAll () { foreach (AnimatedWidget child in Widgets) { if (child.AnimationState != AnimationState.Going) { RemoveCore (child); } } RecalculateSpacings (); } #endregion public bool Contains (Widget widget) { foreach (AnimatedWidget child in Widgets) { if (child.AnimationState != AnimationState.Going && child.Widget == widget) { return true; } } return false; } #endregion } }hyena-0.5/Hyena.Gui/Hyena.Widgets/GenericToolItem.cs0000644000175000001440000000302611377105500022417 0ustar00gabeusers00000000000000// // GenericToolItem.cs // // Author: // Aaron Bockover // // Copyright (C) 2006-2007 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using Gtk; namespace Hyena.Widgets { public class GenericToolItem : ToolItem where T : Widget { private T widget; public GenericToolItem (T widget) { this.widget = widget; Add (widget); } public T Widget { get { return widget; } } } } hyena-0.5/Hyena.Gui/Hyena.Widgets/WrapLabel.cs0000644000175000001440000001066611377105500021247 0ustar00gabeusers00000000000000// // WrapLabel.cs // // Author: // Aaron Bockover // // Copyright (C) 2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using Gtk; namespace Hyena.Widgets { public class WrapLabel : Widget { private string text; private bool use_markup = false; private bool wrap = true; private Pango.Layout layout; public WrapLabel () { WidgetFlags |= WidgetFlags.NoWindow; } private void CreateLayout () { if (layout != null) { layout.Dispose (); } layout = new Pango.Layout (PangoContext); layout.Wrap = Pango.WrapMode.Word; } private void UpdateLayout () { if (layout == null) { CreateLayout (); } layout.Ellipsize = wrap ? Pango.EllipsizeMode.None : Pango.EllipsizeMode.End; if (text == null) { text = ""; } if (use_markup) { layout.SetMarkup (text); } else { layout.SetText (text); } QueueResize (); } protected override void OnStyleSet (Style previous_style) { CreateLayout (); UpdateLayout (); base.OnStyleSet (previous_style); } protected override void OnRealized () { GdkWindow = Parent.GdkWindow; base.OnRealized (); } protected override void OnSizeAllocated (Gdk.Rectangle allocation) { int lw, lh; layout.Width = (int)(allocation.Width * Pango.Scale.PangoScale); layout.GetPixelSize (out lw, out lh); TooltipText = layout.IsEllipsized ? text : null; HeightRequest = lh; base.OnSizeAllocated (allocation); } protected override bool OnExposeEvent (Gdk.EventExpose evnt) { if (evnt.Window == GdkWindow) { // Center the text vertically int lw, lh; layout.GetPixelSize (out lw, out lh); int y = Allocation.Y + (Allocation.Height - lh) / 2; Gtk.Style.PaintLayout (Style, GdkWindow, State, false, evnt.Area, this, null, Allocation.X, y, layout); } return true; } public void MarkupFormat (string format, params object [] args) { if (args == null || args.Length == 0) { Markup = format; return; } for (int i = 0; i < args.Length; i++) { if (args[i] is string) { args[i] = GLib.Markup.EscapeText ((string)args[i]); } } Markup = String.Format (format, args); } public bool Wrap { get { return wrap; } set { wrap = value; UpdateLayout (); } } public string Markup { get { return text; } set { use_markup = true; text = value; UpdateLayout (); } } public string Text { get { return text; } set { use_markup = false; text = value; UpdateLayout (); } } } } hyena-0.5/Hyena.Gui/Hyena.Widgets/SegmentedBar.cs0000644000175000001440000004747511377105500021746 0ustar00gabeusers00000000000000// // SegmentedBar.cs // // Author: // Aaron Bockover // // Copyright (C) 2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Collections.Generic; using Gtk; using Cairo; using Hyena.Gui; namespace Hyena.Widgets { public class SegmentedBar : Widget { public delegate string BarValueFormatHandler (Segment segment); public class Segment { private string title; private double percent; private Cairo.Color color; private bool show_in_bar; public Segment (string title, double percent, Cairo.Color color) : this (title, percent, color, true) { } public Segment (string title, double percent, Cairo.Color color, bool showInBar) { this.title = title; this.percent = percent; this.color = color; this.show_in_bar = showInBar; } public string Title { get { return title; } set { title = value; } } public double Percent { get { return percent; } set { percent = value; } } public Cairo.Color Color { get { return color; } set { color = value; } } public bool ShowInBar { get { return show_in_bar; } set { show_in_bar = value; } } internal int LayoutWidth; internal int LayoutHeight; } // State private List segments = new List (); private int layout_width; private int layout_height; // Properties private int bar_height = 26; private int bar_label_spacing = 8; private int segment_label_spacing = 16; private int segment_box_size = 12; private int segment_box_spacing = 6; private int h_padding = 0; private bool show_labels = true; private bool reflect = true; private Color remainder_color = CairoExtensions.RgbToColor (0xeeeeee); private BarValueFormatHandler format_handler; public SegmentedBar () { WidgetFlags |= WidgetFlags.NoWindow; } protected override void OnRealized () { GdkWindow = Parent.GdkWindow; base.OnRealized (); } #region Size Calculations protected override void OnSizeRequested (ref Requisition requisition) { requisition.Width = 200; requisition.Height = 0; } protected override void OnSizeAllocated (Gdk.Rectangle allocation) { int _bar_height = reflect ? (int)Math.Ceiling (bar_height * 1.75) : bar_height; if (show_labels) { ComputeLayoutSize (); HeightRequest = Math.Max (bar_height + bar_label_spacing + layout_height, _bar_height); WidthRequest = layout_width + (2 * h_padding); } else { HeightRequest = _bar_height; WidthRequest = bar_height + (2 * h_padding); } base.OnSizeAllocated (allocation); } private void ComputeLayoutSize () { if (segments.Count == 0) { return; } Pango.Layout layout = null; layout_width = layout_height = 0; for (int i = 0, n = segments.Count; i < n; i++) { int aw, ah, bw, bh; layout = CreateAdaptLayout (layout, false, true); layout.SetText (FormatSegmentText (segments[i])); layout.GetPixelSize (out aw, out ah); layout = CreateAdaptLayout (layout, true, false); layout.SetText (FormatSegmentValue (segments[i])); layout.GetPixelSize (out bw, out bh); int w = Math.Max (aw, bw); int h = ah + bh; segments[i].LayoutWidth = w; segments[i].LayoutHeight = Math.Max (h, segment_box_size * 2); layout_width += segments[i].LayoutWidth + segment_box_size + segment_box_spacing + (i < n - 1 ? segment_label_spacing : 0); layout_height = Math.Max (layout_height, segments[i].LayoutHeight); } layout.Dispose (); } #endregion #region Public Methods public void AddSegmentRgba (string title, double percent, uint rgbaColor) { AddSegment (title, percent, CairoExtensions.RgbaToColor (rgbaColor)); } public void AddSegmentRgb (string title, double percent, uint rgbColor) { AddSegment (title, percent, CairoExtensions.RgbToColor (rgbColor)); } public void AddSegment (string title, double percent, Color color) { AddSegment (new Segment (title, percent, color, true)); } public void AddSegment (string title, double percent, Color color, bool showInBar) { AddSegment (new Segment (title, percent, color, showInBar)); } public void AddSegment (Segment segment) { lock (segments) { segments.Add (segment); QueueDraw (); } } public void UpdateSegment (int index, double percent) { segments[index].Percent = percent; QueueDraw (); } #endregion #region Public Properties public BarValueFormatHandler ValueFormatter { get { return format_handler; } set { format_handler = value; } } public Color RemainderColor { get { return remainder_color; } set { remainder_color = value; QueueDraw (); } } public int BarHeight { get { return bar_height; } set { if (bar_height != value) { bar_height = value; QueueResize (); } } } public bool ShowReflection { get { return reflect; } set { if (reflect != value) { reflect = value; QueueResize (); } } } public bool ShowLabels { get { return show_labels; } set { if (show_labels != value) { show_labels = value; QueueResize (); } } } public int SegmentLabelSpacing { get { return segment_label_spacing; } set { if (segment_label_spacing != value) { segment_label_spacing = value; QueueResize (); } } } public int SegmentBoxSize { get { return segment_box_size; } set { if (segment_box_size != value) { segment_box_size = value; QueueResize (); } } } public int SegmentBoxSpacing { get { return segment_box_spacing; } set { if (segment_box_spacing != value) { segment_box_spacing = value; QueueResize (); } } } public int BarLabelSpacing { get { return bar_label_spacing; } set { if (bar_label_spacing != value) { bar_label_spacing = value; QueueResize (); } } } public int HorizontalPadding { get { return h_padding; } set { if (h_padding != value) { h_padding = value; QueueResize (); } } } #endregion #region Rendering protected override bool OnExposeEvent (Gdk.EventExpose evnt) { if (evnt.Window != GdkWindow) { return base.OnExposeEvent (evnt); } Cairo.Context cr = Gdk.CairoHelper.Create (evnt.Window); if (reflect) { CairoExtensions.PushGroup (cr); } cr.Operator = Operator.Over; cr.Translate (Allocation.X + h_padding, Allocation.Y); cr.Rectangle (0, 0, Allocation.Width - h_padding, Math.Max (2 * bar_height, bar_height + bar_label_spacing + layout_height)); cr.Clip (); Pattern bar = RenderBar (Allocation.Width - 2 * h_padding, bar_height); cr.Save (); cr.Source = bar; cr.Paint (); cr.Restore (); if (reflect) { cr.Save (); cr.Rectangle (0, bar_height, Allocation.Width - h_padding, bar_height); cr.Clip (); Matrix matrix = new Matrix (); matrix.InitScale (1, -1); matrix.Translate (0, -(2 * bar_height) + 1); cr.Transform (matrix); cr.Pattern = bar; LinearGradient mask = new LinearGradient (0, 0, 0, bar_height); mask.AddColorStop (0.25, new Color (0, 0, 0, 0)); mask.AddColorStop (0.5, new Color (0, 0, 0, 0.125)); mask.AddColorStop (0.75, new Color (0, 0, 0, 0.4)); mask.AddColorStop (1.0, new Color (0, 0, 0, 0.7)); cr.Mask (mask); mask.Destroy (); cr.Restore (); CairoExtensions.PopGroupToSource (cr); cr.Paint (); } if (show_labels) { cr.Translate ((reflect ? Allocation.X : -h_padding) + (Allocation.Width - layout_width) / 2, (reflect ? Allocation.Y : 0) + bar_height + bar_label_spacing); RenderLabels (cr); } bar.Destroy (); CairoExtensions.DisposeContext (cr); return true; } private Pattern RenderBar (int w, int h) { ImageSurface s = new ImageSurface (Format.Argb32, w, h); Context cr = new Context (s); RenderBar (cr, w, h, h / 2); // TODO Implement the new ctor - see http://bugzilla.gnome.org/show_bug.cgi?id=561394 #pragma warning disable 0618 Pattern pattern = new Pattern (s); #pragma warning restore 0618 s.Destroy (); ((IDisposable)cr).Dispose (); return pattern; } private void RenderBar (Context cr, int w, int h, int r) { RenderBarSegments (cr, w, h, r); RenderBarStrokes (cr, w, h, r); } private void RenderBarSegments (Context cr, int w, int h, int r) { LinearGradient grad = new LinearGradient (0, 0, w, 0); double last = 0.0; foreach (Segment segment in segments) { if (segment.Percent > 0) { grad.AddColorStop (last, segment.Color); grad.AddColorStop (last += segment.Percent, segment.Color); } } CairoExtensions.RoundedRectangle (cr, 0, 0, w, h, r); cr.Pattern = grad; cr.FillPreserve (); cr.Pattern.Destroy (); grad = new LinearGradient (0, 0, 0, h); grad.AddColorStop (0.0, new Color (1, 1, 1, 0.125)); grad.AddColorStop (0.35, new Color (1, 1, 1, 0.255)); grad.AddColorStop (1, new Color (0, 0, 0, 0.4)); cr.Pattern = grad; cr.Fill (); cr.Pattern.Destroy (); } private void RenderBarStrokes (Context cr, int w, int h, int r) { LinearGradient stroke = MakeSegmentGradient (h, CairoExtensions.RgbaToColor (0x00000040)); LinearGradient seg_sep_light = MakeSegmentGradient (h, CairoExtensions.RgbaToColor (0xffffff20)); LinearGradient seg_sep_dark = MakeSegmentGradient (h, CairoExtensions.RgbaToColor (0x00000020)); cr.LineWidth = 1; double seg_w = 20; double x = seg_w > r ? seg_w : r; while (x <= w - r) { cr.MoveTo (x - 0.5, 1); cr.LineTo (x - 0.5, h - 1); cr.Pattern = seg_sep_light; cr.Stroke (); cr.MoveTo (x + 0.5, 1); cr.LineTo (x + 0.5, h - 1); cr.Pattern = seg_sep_dark; cr.Stroke (); x += seg_w; } CairoExtensions.RoundedRectangle (cr, 0.5, 0.5, w - 1, h - 1, r); cr.Pattern = stroke; cr.Stroke (); stroke.Destroy (); seg_sep_light.Destroy (); seg_sep_dark.Destroy (); } private LinearGradient MakeSegmentGradient (int h, Color color) { return MakeSegmentGradient (h, color, false); } private LinearGradient MakeSegmentGradient (int h, Color color, bool diag) { LinearGradient grad = new LinearGradient (0, 0, 0, h); grad.AddColorStop (0, CairoExtensions.ColorShade (color, 1.1)); grad.AddColorStop (0.35, CairoExtensions.ColorShade (color, 1.2)); grad.AddColorStop (1, CairoExtensions.ColorShade (color, 0.8)); return grad; } private void RenderLabels (Context cr) { if (segments.Count == 0) { return; } Pango.Layout layout = null; Color text_color = CairoExtensions.GdkColorToCairoColor (Style.Foreground (State)); Color box_stroke_color = new Color (0, 0, 0, 0.6); int x = 0; foreach (Segment segment in segments) { cr.LineWidth = 1; cr.Rectangle (x + 0.5, 2 + 0.5, segment_box_size - 1, segment_box_size - 1); LinearGradient grad = MakeSegmentGradient (segment_box_size, segment.Color, true); cr.Pattern = grad; cr.FillPreserve (); cr.Color = box_stroke_color; cr.Stroke (); grad.Destroy (); x += segment_box_size + segment_box_spacing; int lw, lh; layout = CreateAdaptLayout (layout, false, true); layout.SetText (FormatSegmentText (segment)); layout.GetPixelSize (out lw, out lh); cr.MoveTo (x, 0); text_color.A = 0.9; cr.Color = text_color; PangoCairoHelper.ShowLayout (cr, layout); cr.Fill (); layout = CreateAdaptLayout (layout, true, false); layout.SetText (FormatSegmentValue (segment)); cr.MoveTo (x, lh); text_color.A = 0.75; cr.Color = text_color; PangoCairoHelper.ShowLayout (cr, layout); cr.Fill (); x += segment.LayoutWidth + segment_label_spacing; } layout.Dispose (); } #endregion #region Utilities private int pango_size_normal; private Pango.Layout CreateAdaptLayout (Pango.Layout layout, bool small, bool bold) { if (layout == null) { Pango.Context context = CreatePangoContext (); layout = new Pango.Layout (context); layout.FontDescription = context.FontDescription; pango_size_normal = layout.FontDescription.Size; } layout.FontDescription.Size = small ? (int)(layout.FontDescription.Size * Pango.Scale.Small) : pango_size_normal; layout.FontDescription.Weight = bold ? Pango.Weight.Bold : Pango.Weight.Normal; return layout; } private string FormatSegmentText (Segment segment) { return segment.Title; } private string FormatSegmentValue (Segment segment) { return format_handler == null ? String.Format ("{0}%", segment.Percent * 100.0) : format_handler (segment); } #endregion } #region Test Module [TestModule ("Segmented Bar")] internal class SegmentedBarTestModule : Window { private SegmentedBar bar; private VBox box; public SegmentedBarTestModule () : base ("Segmented Bar") { BorderWidth = 10; AppPaintable = true; box = new VBox (); box.Spacing = 10; Add (box); int space = 55; bar = new SegmentedBar (); bar.HorizontalPadding = bar.BarHeight / 2; bar.AddSegmentRgb ("Audio", 0.00187992456702332, 0x3465a4); bar.AddSegmentRgb ("Other", 0.0788718162651326, 0xf57900); bar.AddSegmentRgb ("Video", 0.0516869922033282, 0x73d216); bar.AddSegment ("Free Space", 0.867561266964516, bar.RemainderColor, false); bar.ValueFormatter = delegate (SegmentedBar.Segment segment) { return String.Format ("{0} GB", space * segment.Percent); }; HBox controls = new HBox (); controls.Spacing = 5; Label label = new Label ("Height:"); controls.PackStart (label, false, false, 0); SpinButton height = new SpinButton (new Adjustment (bar.BarHeight, 5, 100, 1, 1, 1), 1, 0); height.Activated += delegate { bar.BarHeight = height.ValueAsInt; }; height.Changed += delegate { bar.BarHeight = height.ValueAsInt; bar.HorizontalPadding = bar.BarHeight / 2; }; controls.PackStart (height, false, false, 0); CheckButton reflect = new CheckButton ("Reflection"); reflect.Active = bar.ShowReflection; reflect.Toggled += delegate { bar.ShowReflection = reflect.Active; }; controls.PackStart (reflect, false, false, 0); CheckButton labels = new CheckButton ("Labels"); labels.Active = bar.ShowLabels; labels.Toggled += delegate { bar.ShowLabels = labels.Active; }; controls.PackStart (labels, false, false, 0); box.PackStart (controls, false, false, 0); box.PackStart (new HSeparator (), false, false, 0); box.PackStart (bar, false, false, 0); box.ShowAll (); SetSizeRequest (350, -1); Gdk.Geometry limits = new Gdk.Geometry (); limits.MinWidth = SizeRequest ().Width; limits.MaxWidth = Gdk.Screen.Default.Width; limits.MinHeight = -1; limits.MaxHeight = -1; SetGeometryHints (this, limits, Gdk.WindowHints.MaxSize | Gdk.WindowHints.MinSize); } } #endregion } hyena-0.5/Hyena.Gui/Hyena.Widgets/RatingMenuItem.cs0000644000175000001440000000770711436010340022261 0ustar00gabeusers00000000000000// // RatingMenuItem.cs // // Author: // Aaron Bockover // // Copyright (C) 2007-2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using Gtk; using Mono.Unix; using Hyena.Gui; namespace Hyena.Widgets { public class RatingMenuItem : ComplexMenuItem { private RatingEntry entry; private bool can_activate = true; private Box box; protected RatingMenuItem (RatingEntry entry) : base () { box = new HBox (); box.Spacing = 5; Label label = new Label (); label.Markup = String.Format ("{0}", GLib.Markup.EscapeText (Catalog.GetString ("Rating:"))); box.PackStart (label, false, false, 0); label.Show (); this.entry = entry; entry.HasFrame = false; entry.PreviewOnHover = true; entry.AlwaysShowEmptyStars = true; entry.Changed += OnEntryChanged; box.PackStart (entry, false, false, 0); box.ShowAll (); Add (box); } public RatingMenuItem () : this (new RatingEntry ()) { } protected RatingMenuItem (IntPtr raw) : base (raw) { } private int TransformX (double inx) { int x = (int)inx - entry.Allocation.X; if (x < 0) { x = 0; } else if (x > entry.Allocation.Width) { x = entry.Allocation.Width; } return x; } protected override bool OnButtonReleaseEvent (Gdk.EventButton evnt) { if (evnt.X == 0 && evnt.Y == 0) { return false; } entry.SetValueFromPosition (TransformX (evnt.X)); return true; } protected override bool OnMotionNotifyEvent (Gdk.EventMotion evnt) { return entry.HandleMotionNotify (evnt.State, TransformX (evnt.X)); } protected override bool OnLeaveNotifyEvent (Gdk.EventCrossing evnt) { return entry.HandleLeaveNotify (evnt); } protected override bool OnScrollEvent (Gdk.EventScroll evnt) { return entry.HandleScroll (evnt); } protected override bool OnKeyPressEvent (Gdk.EventKey evnt) { return entry.HandleKeyPress (evnt); } private void OnEntryChanged (object o, EventArgs args) { if (can_activate) { Activate (); } } public void Reset (int value) { can_activate = false; Value = value; entry.ClearHover (); can_activate = true; } public int Value { get { return entry.Value; } set { entry.Value = value; } } public RatingEntry RatingEntry { get { return entry; } } } } hyena-0.5/Hyena.Gui/Hyena.Widgets/EntryPopup.cs0000644000175000001440000001717011377105500021520 0ustar00gabeusers00000000000000// // EntryPopup.cs // // Author: // Neil Loknath // // Copyright (C) 2009 Neil Loknath // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Timers; using Gdk; using Gtk; namespace Hyena.Widgets { public class EntryPopup : Gtk.Window { private Entry text_entry; private HBox hbox; private uint timeout_id = 0; public event EventHandler Changed; public event EventHandler KeyPressed; public EntryPopup (string text) : this () { Text = text; } public EntryPopup () : base (Gtk.WindowType.Popup) { CanFocus = true; Resizable = false; TypeHint = Gdk.WindowTypeHint.Utility; Modal = true; Frame frame = new Frame (); frame.Shadow = ShadowType.EtchedIn; Add (frame); hbox = new HBox () { Spacing = 6 }; text_entry = new Entry(); hbox.PackStart (text_entry, true, true, 0); hbox.BorderWidth = 3; frame.Add (hbox); frame.ShowAll (); text_entry.Text = String.Empty; text_entry.CanFocus = true; //TODO figure out why this event does not get raised text_entry.FocusOutEvent += (o, a) => { if (hide_when_focus_lost) { HidePopup (); } }; text_entry.KeyReleaseEvent += delegate (object o, KeyReleaseEventArgs args) { if (args.Event.Key == Gdk.Key.Escape || args.Event.Key == Gdk.Key.Return || args.Event.Key == Gdk.Key.Tab) { HidePopup (); } InitializeDelayedHide (); }; text_entry.KeyPressEvent += (o, a) => OnKeyPressed (a); text_entry.Changed += (o, a) => { if (GdkWindow.IsVisible) { OnChanged (a); } }; } public new bool HasFocus { get { return text_entry.HasFocus; } set { text_entry.HasFocus = value; } } public string Text { get { return text_entry.Text; } set { text_entry.Text = value; } } public Entry Entry { get { return text_entry; } } public HBox Box { get { return hbox; } } private bool hide_after_timeout = true; public bool HideAfterTimeout { get { return hide_after_timeout; } set { hide_after_timeout = value; } } private uint timeout = 5000; public uint Timeout { get { return timeout; } set { timeout = value; } } private bool hide_when_focus_lost = true; public bool HideOnFocusOut { get { return hide_when_focus_lost; } set { hide_when_focus_lost = value; } } private bool reset_when_hiding = true; public bool ResetOnHide { get { return reset_when_hiding; } set { reset_when_hiding = value; } } public override void Dispose () { text_entry.Dispose (); base.Dispose (); } public new void GrabFocus () { text_entry.GrabFocus (); } public void Position (Gdk.Window eventWindow) { int x, y; int widget_x, widget_y; int widget_height, widget_width; Realize (); Gdk.Window widget_window = eventWindow; Gdk.Screen widget_screen = widget_window.Screen; Gtk.Requisition popup_req; widget_window.GetOrigin (out widget_x, out widget_y); widget_window.GetSize (out widget_width, out widget_height); popup_req = Requisition; if (widget_x + widget_width > widget_screen.Width) { x = widget_screen.Width - popup_req.Width; } else if (widget_x + widget_width - popup_req.Width < 0) { x = 0; } else { x = widget_x + widget_width - popup_req.Width; } if (widget_y + widget_height + popup_req.Height > widget_screen.Height) { y = widget_screen.Height - popup_req.Height; } else if (widget_y + widget_height < 0) { y = 0; } else { y = widget_y + widget_height; } Move (x, y); } private void ResetDelayedHide () { if (timeout_id > 0) { GLib.Source.Remove (timeout_id); timeout_id = 0; } } private void InitializeDelayedHide () { ResetDelayedHide (); timeout_id = GLib.Timeout.Add (timeout, delegate { HidePopup (); return false; }); } private void HidePopup () { ResetDelayedHide (); Hide (); if (reset_when_hiding) { text_entry.Text = String.Empty; } } protected virtual void OnChanged (EventArgs args) { var handler = Changed; if (handler != null) { handler (this, EventArgs.Empty); } } protected virtual void OnKeyPressed (KeyPressEventArgs args) { var handler = KeyPressed; if (handler != null) { handler (this, args); } } //TODO figure out why this event does not get raised protected override bool OnFocusOutEvent (Gdk.EventFocus evnt) { if (hide_when_focus_lost) { HidePopup (); return true; } return base.OnFocusOutEvent (evnt); } protected override bool OnExposeEvent (Gdk.EventExpose evnt) { InitializeDelayedHide (); return base.OnExposeEvent (evnt); } protected override bool OnButtonReleaseEvent (Gdk.EventButton evnt) { if (!text_entry.HasFocus && hide_when_focus_lost) { HidePopup (); return true; } return base.OnButtonReleaseEvent (evnt); } protected override bool OnButtonPressEvent (Gdk.EventButton evnt) { if (!text_entry.HasFocus && hide_when_focus_lost) { HidePopup (); return true; } return base.OnButtonPressEvent (evnt); } } } hyena-0.5/Hyena.Gui/Hyena.Widgets/AnimatedWidget.cs0000644000175000001440000001453011377105500022256 0ustar00gabeusers00000000000000// // AnimatedVboxActor.cs // // Authors: // Scott Peterson // // Copyright (C) 2008 Scott Peterson // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Collections.Generic; using Gdk; using Gtk; using Hyena.Gui.Theatrics; namespace Hyena.Widgets { internal enum AnimationState { Coming, Idle, IntendingToGo, Going } internal class AnimatedWidget : Container { public event EventHandler WidgetDestroyed; public Widget Widget; public Easing Easing; public Blocking Blocking; public AnimationState AnimationState; public uint Duration; public double Bias = 1.0; public int Width; public int Height; public int StartPadding; public int EndPadding; public LinkedListNode Node; private readonly bool horizontal; private double percent; private Rectangle widget_alloc; private Pixmap canvas; public AnimatedWidget (Widget widget, uint duration, Easing easing, Blocking blocking, bool horizontal) { this.horizontal = horizontal; Widget = widget; Duration = duration; Easing = easing; Blocking = blocking; AnimationState = AnimationState.Coming; Widget.Parent = this; Widget.Destroyed += OnWidgetDestroyed; ShowAll (); } protected AnimatedWidget (IntPtr raw) : base (raw) { } public double Percent { get { return percent; } set { percent = value * Bias; QueueResizeNoRedraw (); } } private void OnWidgetDestroyed (object sender, EventArgs args) { if (!IsRealized) { return; } canvas = new Pixmap (GdkWindow, widget_alloc.Width, widget_alloc.Height); canvas.DrawDrawable (Style.BackgroundGC (State), GdkWindow, widget_alloc.X, widget_alloc.Y, 0, 0, widget_alloc.Width, widget_alloc.Height); if (AnimationState != AnimationState.Going) { WidgetDestroyed (this, args); } } #region Overrides protected override void OnRemoved (Widget widget) { if (widget == Widget) { widget.Unparent (); Widget = null; } } protected override void OnRealized () { WidgetFlags |= WidgetFlags.Realized; Gdk.WindowAttr attributes = new Gdk.WindowAttr (); attributes.WindowType = Gdk.WindowType.Child; attributes.Wclass = Gdk.WindowClass.InputOutput; attributes.EventMask = (int)Gdk.EventMask.ExposureMask; GdkWindow = new Gdk.Window (Parent.GdkWindow, attributes, 0); GdkWindow.UserData = Handle; GdkWindow.Background = Style.Background (State); Style.Attach (GdkWindow); } protected override void OnSizeRequested (ref Requisition requisition) { if (Widget != null) { Requisition req = Widget.SizeRequest (); widget_alloc.Width = req.Width; widget_alloc.Height = req.Height; } if (horizontal) { Width = Choreographer.PixelCompose (percent, widget_alloc.Width + StartPadding + EndPadding, Easing); Height = widget_alloc.Height; } else { Width = widget_alloc.Width; Height = Choreographer.PixelCompose (percent, widget_alloc.Height + StartPadding + EndPadding, Easing); } requisition.Width = Width; requisition.Height = Height; } protected override void OnSizeAllocated (Rectangle allocation) { base.OnSizeAllocated (allocation); if (Widget != null) { if (horizontal) { widget_alloc.Height = allocation.Height; widget_alloc.X = StartPadding; if (Blocking == Blocking.Downstage) { widget_alloc.X += allocation.Width - widget_alloc.Width; } } else { widget_alloc.Width = allocation.Width; widget_alloc.Y = StartPadding; if (Blocking == Blocking.Downstage) { widget_alloc.Y = allocation.Height - widget_alloc.Height; } } if (widget_alloc.Height > 0 && widget_alloc.Width > 0) { Widget.SizeAllocate (widget_alloc); } } } protected override bool OnExposeEvent (EventExpose evnt) { if (canvas != null) { GdkWindow.DrawDrawable (Style.BackgroundGC (State), canvas, 0, 0, widget_alloc.X, widget_alloc.Y, widget_alloc.Width, widget_alloc.Height); return true; } else { return base.OnExposeEvent (evnt); } } protected override void ForAll (bool include_internals, Callback callback) { if (Widget != null) { callback (Widget); } } #endregion } } hyena-0.5/Hyena.Gui/Hyena.Widgets/RoundedFrame.cs0000644000175000001440000001446411377105500021751 0ustar00gabeusers00000000000000// // RoundedFrame.cs // // Authors: // Aaron Bockover // Gabriel Burt // // Copyright (C) 2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using Gtk; using Cairo; using Hyena.Gui; using Hyena.Gui.Theming; namespace Hyena.Widgets { public class RoundedFrame : Bin { private Theme theme; protected Theme Theme { get { return theme; } } private Widget child; private Gdk.Rectangle child_allocation; private bool fill_color_set; private Cairo.Color fill_color; private bool draw_border = true; private Pattern fill_pattern; private int frame_width; // Ugh, this is to avoid the GLib.MissingIntPtrCtorException seen by some; BGO #552169 protected RoundedFrame (IntPtr ptr) : base (ptr) { } public RoundedFrame () { } public void SetFillColor (Cairo.Color color) { fill_color = color; fill_color_set = true; QueueDraw (); } public void UnsetFillColor () { fill_color_set = false; QueueDraw (); } public Pattern FillPattern { get { return fill_pattern; } set { fill_pattern = value; QueueDraw (); } } public bool DrawBorder { get { return draw_border; } set { draw_border = value; QueueDraw (); } } #region Gtk.Widget Overrides protected override void OnStyleSet (Style previous_style) { base.OnStyleSet (previous_style); theme = Hyena.Gui.Theming.ThemeEngine.CreateTheme (this); frame_width = (int)theme.Context.Radius + 1; } protected override void OnSizeRequested (ref Requisition requisition) { if (child != null && child.Visible) { // Add the child's width/height Requisition child_requisition = child.SizeRequest (); requisition.Width = Math.Max (0, child_requisition.Width); requisition.Height = child_requisition.Height; } else { requisition.Width = 0; requisition.Height = 0; } // Add the frame border requisition.Width += ((int)BorderWidth + frame_width) * 2; requisition.Height += ((int)BorderWidth + frame_width) * 2; } protected override void OnSizeAllocated (Gdk.Rectangle allocation) { base.OnSizeAllocated (allocation); child_allocation = new Gdk.Rectangle (); if (child == null || !child.Visible) { return; } child_allocation.X = (int)BorderWidth + frame_width; child_allocation.Y = (int)BorderWidth + frame_width; child_allocation.Width = (int)Math.Max (1, Allocation.Width - child_allocation.X * 2); child_allocation.Height = (int)Math.Max (1, Allocation.Height - child_allocation.Y - (int)BorderWidth - frame_width); child_allocation.X += Allocation.X; child_allocation.Y += Allocation.Y; child.SizeAllocate (child_allocation); } protected override void OnSetScrollAdjustments (Adjustment hadj, Adjustment vadj) { // This is to satisfy the gtk_widget_set_scroll_adjustments // inside of GtkScrolledWindow so it doesn't complain about // its child not being scrollable. } protected override bool OnExposeEvent (Gdk.EventExpose evnt) { if (!IsDrawable) { return false; } Cairo.Context cr = Gdk.CairoHelper.Create (evnt.Window); try { DrawFrame (cr, evnt.Area); if (child != null) { PropagateExpose (child, evnt); } return false; } finally { CairoExtensions.DisposeContext (cr); } } private void DrawFrame (Cairo.Context cr, Gdk.Rectangle clip) { int x = child_allocation.X - frame_width; int y = child_allocation.Y - frame_width; int width = child_allocation.Width + 2 * frame_width; int height = child_allocation.Height + 2 * frame_width; Gdk.Rectangle rect = new Gdk.Rectangle (x, y, width, height); theme.Context.ShowStroke = draw_border; if (fill_color_set) { theme.DrawFrameBackground (cr, rect, fill_color); } else if (fill_pattern != null) { theme.DrawFrameBackground (cr, rect, fill_pattern); } else { theme.DrawFrameBackground (cr, rect, true); theme.DrawFrameBorder (cr, rect); } } #endregion #region Gtk.Container Overrides protected override void OnAdded (Widget widget) { child = widget; base.OnAdded (widget); } protected override void OnRemoved (Widget widget) { if (child == widget) { child = null; } base.OnRemoved (widget); } #endregion } } hyena-0.5/Hyena.Gui/Hyena.Widgets/AnimatedImage.cs0000644000175000001440000001317111377105500022055 0ustar00gabeusers00000000000000// // AnimatedImage.cs // // Author: // Aaron Bockover // // Copyright (C) 2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using Gtk; using Hyena.Gui; using Hyena.Gui.Theatrics; namespace Hyena.Widgets { public class AnimatedImage : Image { private Gdk.Pixbuf pixbuf; private Gdk.Pixbuf inactive_pixbuf; private Gdk.Pixbuf [] frames; private int frame_width; private int frame_height; private int max_frames; private bool active_frozen; private SingleActorStage stage = new SingleActorStage (); public AnimatedImage () { stage.Iteration += OnIteration; stage.Reset (); stage.Actor.CanExpire = false; } protected override void OnShown () { base.OnShown (); if (active_frozen && !stage.Playing) { stage.Play (); } } protected override void OnHidden () { base.OnHidden (); active_frozen = Active; if (stage.Playing) { stage.Pause (); } } protected override void OnSizeAllocated (Gdk.Rectangle allocation) { if (allocation != Allocation) { base.OnSizeAllocated (allocation); } } public void Load () { ExtractFrames (); base.Pixbuf = frames[0]; } private void OnIteration (object o, EventArgs args) { if (!Visible) { return; } if (frames == null || frames.Length == 0) { return; } else if (frames.Length == 1) { base.Pixbuf = frames[0]; return; } // The first frame is the idle frame, so skip it when animating int index = (int)Math.Round ((double)(frames.Length - 2) * stage.Actor.Percent) + 1; if (base.Pixbuf != frames[index]) { base.Pixbuf = frames[index]; } } private void ExtractFrames () { if (pixbuf == null) { throw new ApplicationException ("No source pixbuf specified"); } else if (pixbuf.Width % frame_width != 0 || pixbuf.Height % frame_height != 0) { throw new ApplicationException ("Invalid frame dimensions"); } int rows = pixbuf.Height / frame_height; int cols = pixbuf.Width / frame_width; int frame_count = rows * cols; frames = new Gdk.Pixbuf[max_frames > 0 ? max_frames : frame_count]; for (int y = 0, n = 0; y < rows; y++) { for (int x = 0; x < cols; x++, n++) { frames[n] = new Gdk.Pixbuf (pixbuf, x * frame_width, y * frame_height, frame_width, frame_height); if (max_frames > 0 && n >= max_frames - 1) { return; } } } } public bool Active { get { return !Visible ? active_frozen : stage.Playing; } set { if (value) { active_frozen = true; if (Visible) { stage.Play (); } } else { active_frozen = false; if (stage.Playing) { stage.Pause (); } if (inactive_pixbuf != null) { base.Pixbuf = inactive_pixbuf; } else if (frames != null && frames.Length > 1) { base.Pixbuf = frames[0]; } else { base.Pixbuf = null; } } } } public int FrameWidth { get { return frame_width; } set { frame_width = value; } } public int FrameHeight { get { return frame_height; } set { frame_height = value; } } public int MaxFrames { get { return max_frames; } set { max_frames = value; } } public new Gdk.Pixbuf Pixbuf { get { return pixbuf; } set { pixbuf = value; } } public Gdk.Pixbuf InactivePixbuf { get { return inactive_pixbuf; } set { inactive_pixbuf = value; if (!Active) { base.Pixbuf = value; } } } } } hyena-0.5/Hyena.Gui/Hyena.Widgets/SimpleTable.cs0000644000175000001440000000660111377105500021571 0ustar00gabeusers00000000000000// // SimpleTable.cs // // Author: // Gabriel Burt // // Copyright (C) 2009 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Collections.Generic; using Gtk; namespace Hyena.Widgets { public class SimpleTable : Table { private bool added_any; private List items = new List (); private Dictionary item_widgets = new Dictionary (); public SimpleTable () : base (1, 2, false) { ColumnSpacing = 5; RowSpacing = 5; } public void AddRow (T item, params Widget [] cols) { InsertRow (item, (uint)items.Count, cols); } public void InsertRow (T item, uint row, params Widget [] cols) { if (!added_any) { added_any = true; } else if (NColumns != cols.Length) { throw new ArgumentException ("cols", String.Format ("Expected {0} column widgets, same as previous calls to Add", NColumns)); } Resize ((uint) items.Count + 1, (uint) cols.Length); for (int y = items.Count - 1; y >= row; y--) { for (uint x = 0; x < NColumns; x++) { var widget = item_widgets[items[y]][x]; Remove (widget); Attach (widget, x, x + 1, (uint) y + 1, (uint) y + 2); } } items.Insert ((int)row, item); item_widgets[item] = cols; for (uint x = 0; x < NColumns; x++) { Attach (cols[x], x, x + 1, row, row + 1); } } public void RemoveRow (T item) { FreezeChildNotify (); foreach (var widget in item_widgets[item]) { Remove (widget); } int index = items.IndexOf (item); for (int y = index + 1; y < items.Count; y++) { for (uint x = 0; x < NColumns; x++) { var widget = item_widgets[items[y]][x]; Remove (widget); Attach (widget, x, x + 1, (uint) y - 1, (uint) y); } } Resize ((uint) Math.Max (1, items.Count - 1), NColumns); ThawChildNotify (); items.Remove (item); item_widgets.Remove (item); } } } hyena-0.5/Hyena.Gui/Makefile.in0000644000175000001440000004264011453150777016453 0ustar00gabeusers00000000000000# Makefile.in generated by automake 1.10.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(top_srcdir)/build/build.environment.mk \ $(top_srcdir)/build/build.mk \ $(top_srcdir)/build/build.rules.mk @ENABLE_TESTS_TRUE@am__append_1 = " $(NUNIT_LIBS)" subdir = Hyena.Gui ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/build/m4/shamrock/expansions.m4 \ $(top_srcdir)/build/m4/shamrock/mono.m4 \ $(top_srcdir)/build/m4/shamrock/programs.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = am__installdirs = "$(DESTDIR)$(moduledir)" moduleSCRIPT_INSTALL = $(INSTALL_SCRIPT) SCRIPTS = $(module_SCRIPTS) DIST_SOURCES = DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ GLIBSHARP_CFLAGS = @GLIBSHARP_CFLAGS@ GLIBSHARP_LIBS = @GLIBSHARP_LIBS@ GTKSHARP_A11Y_CFLAGS = @GTKSHARP_A11Y_CFLAGS@ GTKSHARP_A11Y_LIBS = @GTKSHARP_A11Y_LIBS@ GTKSHARP_CFLAGS = @GTKSHARP_CFLAGS@ GTKSHARP_LIBS = @GTKSHARP_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MCS = @MCS@ MKDIR_P = @MKDIR_P@ MONO = @MONO@ MONO_MODULE_CFLAGS = @MONO_MODULE_CFLAGS@ MONO_MODULE_LIBS = @MONO_MODULE_LIBS@ NUNIT_CFLAGS = @NUNIT_CFLAGS@ NUNIT_LIBS = @NUNIT_LIBS@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ am__leading_dot = @am__leading_dot@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ expanded_bindir = @expanded_bindir@ expanded_datadir = @expanded_datadir@ expanded_libdir = @expanded_libdir@ host_alias = @host_alias@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ ASSEMBLY = Hyena.Gui ASSEMBLY_BUILD_FLAGS = -unsafe TARGET = library LINK = -r:ICSharpCode.SharpZipLib -r:Mono.Posix -r:System \ -r:System.Core -r:Mono.Cairo $(GTKSHARP_LIBS) \ $(GLIBSHARP_LIBS) -r:$(DIR_BIN)/Hyena.dll $(am__append_1) SOURCES = \ Hyena.Data.Gui/Accessibility/ColumnCellAccessible.cs \ Hyena.Data.Gui/Accessibility/ColumnCellTextAccessible.cs \ Hyena.Data.Gui/Accessibility/ColumnHeaderCellTextAccessible.cs \ Hyena.Data.Gui/Accessibility/ICellAccessibleParent.cs \ Hyena.Data.Gui/Accessibility/ListViewAccessible.cs \ Hyena.Data.Gui/Accessibility/ListViewAccessible_Selection.cs \ Hyena.Data.Gui/Accessibility/ListViewAccessible_Table.cs \ Hyena.Data.Gui/CellContext.cs \ Hyena.Data.Gui/Column.cs \ Hyena.Data.Gui/ColumnCell.cs \ Hyena.Data.Gui/ColumnCellCheckBox.cs \ Hyena.Data.Gui/ColumnCellRating.cs \ Hyena.Data.Gui/ColumnCellText.cs \ Hyena.Data.Gui/ColumnController.cs \ Hyena.Data.Gui/ColumnHeaderCellText.cs \ Hyena.Data.Gui/DataViewChild.cs \ Hyena.Data.Gui/DataViewLayout.cs \ Hyena.Data.Gui/DataViewLayoutGrid.cs \ Hyena.Data.Gui/IHeaderCell.cs \ Hyena.Data.Gui/IInteractiveCell.cs \ Hyena.Data.Gui/IListView.cs \ Hyena.Data.Gui/ISizeRequestCell.cs \ Hyena.Data.Gui/ITextCell.cs \ Hyena.Data.Gui/ITooltipCell.cs \ Hyena.Data.Gui/ListView/ListView.cs \ Hyena.Data.Gui/ListView/ListView_Accessible.cs \ Hyena.Data.Gui/ListView/ListView_DragAndDrop.cs \ Hyena.Data.Gui/ListView/ListView_Header.cs \ Hyena.Data.Gui/ListView/ListView_Interaction.cs \ Hyena.Data.Gui/ListView/ListView_Model.cs \ Hyena.Data.Gui/ListView/ListView_Rendering.cs \ Hyena.Data.Gui/ListView/ListView_Windowing.cs \ Hyena.Data.Gui/ListView/ListViewBase.cs \ Hyena.Data.Gui/ListViewTestModule.cs \ Hyena.Data.Gui/ObjectListView.cs \ Hyena.Data.Gui/RowActivatedHandler.cs \ Hyena.Data.Gui/SortableColumn.cs \ Hyena.Gui.Canvas/Point.cs \ Hyena.Gui.Canvas/Rect.cs \ Hyena.Gui.Canvas/Size.cs \ Hyena.Gui.Canvas/Thickness.cs \ Hyena.Gui.Dialogs/ExceptionDialog.cs \ Hyena.Gui.Dialogs/VersionInformationDialog.cs \ Hyena.Gui.Theatrics/Actor.cs \ Hyena.Gui.Theatrics/Choreographer.cs \ Hyena.Gui.Theatrics/Pulsator.cs \ Hyena.Gui.Theatrics/SingleActorStage.cs \ Hyena.Gui.Theatrics/Stage.cs \ Hyena.Gui.Theatrics/Tests/ChoreographerTests.cs \ Hyena.Gui.Theming/GtkColors.cs \ Hyena.Gui.Theming/GtkTheme.cs \ Hyena.Gui.Theming/Theme.cs \ Hyena.Gui.Theming/ThemeContext.cs \ Hyena.Gui.Theming/ThemeEngine.cs \ Hyena.Gui.Theming/ThemeTestModule.cs \ Hyena.Gui/ActionManager.cs \ Hyena.Gui/BaseWidgetAccessible.cs \ Hyena.Gui/CairoDamageDebugger.cs \ Hyena.Gui/CairoExtensions.cs \ Hyena.Gui/CleanRoomStartup.cs \ Hyena.Gui/CompositeUtils.cs \ Hyena.Gui/Contrast.cs \ Hyena.Gui/DragDropList.cs \ Hyena.Gui/EditableEraseAction.cs \ Hyena.Gui/EditableInsertAction.cs \ Hyena.Gui/EditableUndoAdapter.cs \ Hyena.Gui/GtkUtilities.cs \ Hyena.Gui/GtkWorkarounds.cs \ Hyena.Gui/HyenaActionGroup.cs \ Hyena.Gui/PangoCairoHelper.cs \ Hyena.Gui/PangoExtensions.cs \ Hyena.Gui/PixbufImageSurface.cs \ Hyena.Gui/RatingRenderer.cs \ Hyena.Gui/ShadingTestWindow.cs \ Hyena.Gui/TestModuleAttribute.cs \ Hyena.Gui/TestModuleRunner.cs \ Hyena.Gui/TooltipSetter.cs \ Hyena.Query.Gui/DateQueryValueEntry.cs \ Hyena.Query.Gui/FileSizeQueryValueEntry.cs \ Hyena.Query.Gui/IntegerQueryValueEntry.cs \ Hyena.Query.Gui/NullQueryValueEntry.cs \ Hyena.Query.Gui/QueryBox.cs \ Hyena.Query.Gui/QueryDebugger.cs \ Hyena.Query.Gui/QueryLimitBox.cs \ Hyena.Query.Gui/QueryTermBox.cs \ Hyena.Query.Gui/QueryTermsBox.cs \ Hyena.Query.Gui/QueryValueEntry.cs \ Hyena.Query.Gui/RelativeTimeSpanQueryValueEntry.cs \ Hyena.Query.Gui/StringQueryValueEntry.cs \ Hyena.Query.Gui/TimeSpanQueryValueEntry.cs \ Hyena.Widgets/AnimatedBox.cs \ Hyena.Widgets/AnimatedHBox.cs \ Hyena.Widgets/AnimatedImage.cs \ Hyena.Widgets/AnimatedVBox.cs \ Hyena.Widgets/AnimatedWidget.cs \ Hyena.Widgets/ComplexMenuItem.cs \ Hyena.Widgets/EntryPopup.cs \ Hyena.Widgets/GenericToolItem.cs \ Hyena.Widgets/HigMessageDialog.cs \ Hyena.Widgets/ImageButton.cs \ Hyena.Widgets/MenuButton.cs \ Hyena.Widgets/MessageBar.cs \ Hyena.Widgets/PulsingButton.cs \ Hyena.Widgets/RatingEntry.cs \ Hyena.Widgets/RatingMenuItem.cs \ Hyena.Widgets/RoundedFrame.cs \ Hyena.Widgets/ScrolledWindow.cs \ Hyena.Widgets/SegmentedBar.cs \ Hyena.Widgets/SimpleTable.cs \ Hyena.Widgets/SmoothScrolledWindow.cs \ Hyena.Widgets/TextViewEditable.cs \ Hyena.Widgets/WrapLabel.cs # Initializers MONO_BASE_PATH = MONO_ADDINS_PATH = # Install Paths DEFAULT_INSTALL_DIR = $(pkglibdir) DIR_BIN = $(top_builddir)/bin # Cute hack to replace a space with something colon := : empty := space := $(empty) $(empty) UNIQUE_FILTER_PIPE = tr [:space:] \\n | sort | uniq BUILD_DATA_DIR = $(top_builddir)/bin/share/$(PACKAGE) SOURCES_BUILD = $(addprefix $(srcdir)/, $(SOURCES)) RESOURCES_EXPANDED = $(addprefix $(srcdir)/, $(RESOURCES)) RESOURCES_BUILD = $(foreach resource, $(RESOURCES_EXPANDED), \ -resource:$(resource),$(notdir $(resource))) INSTALL_ICONS = $(top_srcdir)/build/private-icon-theme-installer "$(mkinstalldirs)" "$(INSTALL_DATA)" THEME_ICONS_SOURCE = $(wildcard $(srcdir)/ThemeIcons/*/*/*.png) $(wildcard $(srcdir)/ThemeIcons/scalable/*/*.svg) THEME_ICONS_RELATIVE = $(subst $(srcdir)/ThemeIcons/, , $(THEME_ICONS_SOURCE)) ASSEMBLY_EXTENSION = $(strip $(patsubst library, dll, $(TARGET))) ASSEMBLY_FILE = $(top_builddir)/bin/$(ASSEMBLY).$(ASSEMBLY_EXTENSION) INSTALL_DIR_RESOLVED = $(firstword $(subst , $(DEFAULT_INSTALL_DIR), $(INSTALL_DIR))) @ENABLE_TESTS_TRUE@ENABLE_TESTS_FLAG = "-define:ENABLE_TESTS" @ENABLE_ATK_TRUE@ENABLE_ATK_FLAG = "-define:ENABLE_ATK" FILTERED_LINK = $(shell echo "$(LINK)" | $(UNIQUE_FILTER_PIPE)) DEP_LINK = $(shell echo "$(LINK)" | $(UNIQUE_FILTER_PIPE) | sed s,-r:,,g | grep '$(top_builddir)/bin/') OUTPUT_FILES = \ $(ASSEMBLY_FILE) \ $(ASSEMBLY_FILE).mdb moduledir = $(INSTALL_DIR_RESOLVED) module_SCRIPTS = $(OUTPUT_FILES) Hyena.Gui.dll.config EXTRA_DIST = $(SOURCES_BUILD) $(RESOURCES_EXPANDED) \ $(THEME_ICONS_SOURCE) Hyena.Gui.dll.config CLEANFILES = $(OUTPUT_FILES) DISTCLEANFILES = *.pidb MAINTAINERCLEANFILES = Makefile.in all: all-am .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/build/build.mk $(top_srcdir)/build/build.environment.mk $(top_srcdir)/build/build.rules.mk $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Hyena.Gui/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --foreign Hyena.Gui/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh install-moduleSCRIPTS: $(module_SCRIPTS) @$(NORMAL_INSTALL) test -z "$(moduledir)" || $(MKDIR_P) "$(DESTDIR)$(moduledir)" @list='$(module_SCRIPTS)'; for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ if test -f $$d$$p; then \ f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \ echo " $(moduleSCRIPT_INSTALL) '$$d$$p' '$(DESTDIR)$(moduledir)/$$f'"; \ $(moduleSCRIPT_INSTALL) "$$d$$p" "$(DESTDIR)$(moduledir)/$$f"; \ else :; fi; \ done uninstall-moduleSCRIPTS: @$(NORMAL_UNINSTALL) @list='$(module_SCRIPTS)'; for p in $$list; do \ f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \ echo " rm -f '$(DESTDIR)$(moduledir)/$$f'"; \ rm -f "$(DESTDIR)$(moduledir)/$$f"; \ done tags: TAGS TAGS: ctags: CTAGS CTAGS: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(SCRIPTS) installdirs: for dir in "$(DESTDIR)$(moduledir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) clean: clean-am clean-am: clean-generic mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am info: info-am info-am: install-data-am: install-data-local install-moduleSCRIPTS install-dvi: install-dvi-am install-exec-am: install-html: install-html-am install-info: install-info-am install-man: install-pdf: install-pdf-am install-ps: install-ps-am installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-local uninstall-moduleSCRIPTS .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic distclean \ distclean-generic distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am \ install-data-local install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-moduleSCRIPTS install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ pdf-am ps ps-am uninstall uninstall-am uninstall-local \ uninstall-moduleSCRIPTS dnl SOURCES_BUILD += $(top_srcdir)/src/AssemblyInfo.cs all: $(ASSEMBLY_FILE) theme-icons run: @pushd $(top_builddir); \ make run; \ popd; test: @pushd $(top_builddir)/tests; \ make $(ASSEMBLY); \ popd; build-debug: @echo $(DEP_LINK) $(ASSEMBLY_FILE).mdb: $(ASSEMBLY_FILE) $(ASSEMBLY_FILE): $(SOURCES_BUILD) $(RESOURCES_EXPANDED) $(DEP_LINK) @mkdir -p $(top_builddir)/bin @if [ ! "x$(ENABLE_RELEASE)" = "xyes" ]; then \ $(top_srcdir)/build/dll-map-makefile-verifier $(srcdir)/Makefile.am $(srcdir)/$(notdir $@.config) && \ $(MONO) $(top_builddir)/build/dll-map-verifier.exe $(srcdir)/$(notdir $@.config) -iwinmm -ilibbanshee -ilibbnpx11 -ilibc -ilibc.so.6 -iintl -ilibmtp.dll -ilibigemacintegration.dylib -iCFRelease $(SOURCES_BUILD); \ fi; $(MCS) \ $(GMCS_FLAGS) \ $(ASSEMBLY_BUILD_FLAGS) \ -nowarn:0278 -nowarn:0078 $$warn \ -define:HAVE_GTK_2_10 -define:NET_2_0 \ -debug -target:$(TARGET) -out:$@ \ $(BUILD_DEFINES) $(ENABLE_TESTS_FLAG) $(ENABLE_ATK_FLAG) \ $(FILTERED_LINK) $(RESOURCES_BUILD) $(SOURCES_BUILD) @if [ -e $(srcdir)/$(notdir $@.config) ]; then \ cp $(srcdir)/$(notdir $@.config) $(top_builddir)/bin; \ fi; @if [ ! -z "$(EXTRA_BUNDLE)" ]; then \ cp $(EXTRA_BUNDLE) $(top_builddir)/bin; \ fi; theme-icons: $(THEME_ICONS_SOURCE) @$(INSTALL_ICONS) -il "$(BUILD_DATA_DIR)" "$(srcdir)" $(THEME_ICONS_RELATIVE) install-data-local: $(THEME_ICONS_SOURCE) @$(INSTALL_ICONS) -i "$(DESTDIR)$(pkgdatadir)" "$(srcdir)" $(THEME_ICONS_RELATIVE) uninstall-local: $(THEME_ICONS_SOURCE) @$(INSTALL_ICONS) -u "$(DESTDIR)$(pkgdatadir)" "$(srcdir)" $(THEME_ICONS_RELATIVE) # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: hyena-0.5/Hyena.Gui/Hyena.Data.Gui/0000777000175000001440000000000011453151003017022 5ustar00gabeusers00000000000000hyena-0.5/Hyena.Gui/Hyena.Data.Gui/ISizeRequestCell.cs0000644000175000001440000000262211377105500022551 0ustar00gabeusers00000000000000// // ISizeRequestCell.cs // // Author: // Aaron Bockover // // Copyright (C) 2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; namespace Hyena.Data.Gui { public interface ISizeRequestCell { bool RestrictSize { get; set; } void GetWidthRange (Pango.Layout layout, out int min_width, out int max_width); } } hyena-0.5/Hyena.Gui/Hyena.Data.Gui/ListViewTestModule.cs0000644000175000001440000001572611377105500023142 0ustar00gabeusers00000000000000// // ListViewTestModule.cs // // Author: // Aaron Bockover // // Copyright (C) 2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Collections.Generic; using Gtk; using Hyena.Data; using Hyena.Collections; using Hyena.Gui; using Selection = Hyena.Collections.Selection; namespace Hyena.Data.Gui { [TestModule ("List View")] public class ListViewTestModule : Window { private View view; private Model model; public ListViewTestModule () : base ("ListView") { WindowPosition = WindowPosition.Center; SetDefaultSize (800, 600); ScrolledWindow scroll = new ScrolledWindow (); scroll.HscrollbarPolicy = PolicyType.Automatic; scroll.VscrollbarPolicy = PolicyType.Automatic; view = new View (); model = new Model (); scroll.Add (view); Add (scroll); ShowAll (); view.SetModel (model); } private class View : ListView { public View () { ColumnController = new ColumnController (); ColumnController.AddRange ( new Column (String.Empty, new ColumnCellCheckBox ("F", true), 1), new Column ("Apples", new ColumnCellText ("B", true), 1), new Column ("Pears", new ColumnCellText ("C", true), 1), new Column ("How Hot", new ColumnCellRating ("G", true), 1), new Column ("Peaches", new ColumnCellText ("D", true), 1), new Column ("Doodle", new ColumnCellDoodle ("E", true), 1), new Column ("GUIDs!OMG", new ColumnCellText ("A", true), 1) ); } } private class Model : IListModel { private List store = new List (); private Selection selection = new Selection (); public event EventHandler Cleared; public event EventHandler Reloaded; public Model () { Random random = new Random (0); for (int i = 0; i < 1000; i++) { store.Add (new ModelItem (i, random)); } } public void Clear () { } public void Reload () { } public object GetItem (int index) { return this[index]; } public int Count { get { return store.Count; } } public bool CanReorder { get { return false; } } public ModelItem this[int index] { get { return store[index]; } } public Selection Selection { get { return selection; } } } private class ModelItem { public ModelItem (int i, Random rand) { a = Guid.NewGuid ().ToString (); b = rand.Next (0, 255); c = rand.NextDouble (); d = String.Format ("Item {0}", i); e = new List (); f = rand.Next (0, 1) == 1; g = rand.Next (0, 5); } string a; public string A { get { return a; } } int b; public int B { get { return b; } } double c; public double C { get { return c; } } string d; public string D { get { return d; } } List e; public List E { get { return e; } } bool f; public bool F { get { return f; } set { f = value; } } int g; public int G { get { return g; } set { g = value; } } } private class ColumnCellDoodle : ColumnCell, IInteractiveCell { private Random random = new Random (); private bool red = false; public ColumnCellDoodle (string property, bool expand) : base (property, expand) { } public override void Render (CellContext context, StateType state, double cellWidth, double cellHeight) { red = !red; Cairo.Context cr = context.Context; cr.Rectangle (0, 0, cellWidth, cellHeight); cr.Color = CairoExtensions.RgbaToColor (red ? 0xff000099 : 0x00000099); cr.Fill (); List points = Points; for (int i = 0, n = points.Count; i < n; i++) { if (i == 0) { cr.MoveTo (points[i].X, points[i].Y); } else { cr.LineTo (points[i].X, points[i].Y); } } cr.Color = CairoExtensions.RgbToColor ((uint)random.Next (0xffffff)); cr.LineWidth = 1; cr.Stroke (); } private object last_pressed_bound; public bool ButtonEvent (int x, int y, bool pressed, Gdk.EventButton evnt) { if (!pressed) { last_pressed_bound = null; return false; } last_pressed_bound = BoundObject; Points.Add (new Gdk.Point (x, y)); return true; } public bool MotionEvent (int x, int y, Gdk.EventMotion evnt) { if (last_pressed_bound == BoundObject) { Points.Add (new Gdk.Point (x, y)); return true; } return false; } public bool PointerLeaveEvent () { last_pressed_bound = null; return true; } private List Points { get { return (List)BoundObject; } } } } } hyena-0.5/Hyena.Gui/Hyena.Data.Gui/ListView/0000777000175000001440000000000011453151003020570 5ustar00gabeusers00000000000000hyena-0.5/Hyena.Gui/Hyena.Data.Gui/ListView/ListView_Model.cs0000644000175000001440000001643711377105500024022 0ustar00gabeusers00000000000000// // ListView_Model.cs // // Author: // Aaron Bockover // // Copyright (C) 2007-2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Reflection; using Gtk; namespace Hyena.Data.Gui { public partial class ListView : ListViewBase { #pragma warning disable 0067 public event EventHandler ModelChanged; public event EventHandler ModelReloaded; #pragma warning restore 0067 public void SetModel (IListModel model) { SetModel (model, 0.0); } public virtual void SetModel (IListModel value, double vpos) { if (model == value) { return; } if (model != null) { model.Cleared -= OnModelClearedHandler; model.Reloaded -= OnModelReloadedHandler; } model = value; if (model != null) { model.Cleared += OnModelClearedHandler; model.Reloaded += OnModelReloadedHandler; selection_proxy.Selection = model.Selection; IsEverReorderable = model.CanReorder; } ISortable sortable = model as ISortable; if (sortable != null) { ISortableColumn sort_column = ColumnController.SortColumn ?? ColumnController.DefaultSortColumn; if (sort_column != null) { sortable.Sort (sort_column); RecalculateColumnSizes (); RegenerateColumnCache (); InvalidateHeader (); IsReorderable = sortable.SortColumn == null || sortable.SortColumn.SortType == SortType.None; } } if (ViewLayout != null) { ViewLayout.Model = Model; } RefreshViewForModel (vpos); var handler = ModelChanged; if (handler != null) { handler (this, EventArgs.Empty); } } private void RefreshViewForModel (double? vpos) { if (Model == null) { UpdateAdjustments (); QueueDraw (); return; } if (ViewLayout != null) { ViewLayout.ModelUpdated (); } UpdateAdjustments (); if (vpos != null) { ScrollToY ((double) vpos); } else if (Model.Count <= ItemsInView) { // If our view fits all rows at once, make sure we're scrolled to the top ScrollToY (0.0); } else if (vadjustment != null) { ScrollToY (vadjustment.Value); } if (Parent is ScrolledWindow) { Parent.QueueDraw (); } } private void OnModelClearedHandler (object o, EventArgs args) { OnModelCleared (); } private void OnModelReloadedHandler (object o, EventArgs args) { OnModelReloaded (); var handler = ModelReloaded; if (handler != null) { handler (this, EventArgs.Empty); } } private void OnColumnControllerUpdatedHandler (object o, EventArgs args) { OnColumnControllerUpdated (); } protected virtual void OnModelCleared () { RefreshViewForModel (null); } protected virtual void OnModelReloaded () { RefreshViewForModel (null); } private IListModel model; public virtual IListModel Model { get { return model; } } private string row_opaque_property_name = "Sensitive"; private PropertyInfo row_opaque_property_info; bool row_opaque_property_invalid = false; public string RowOpaquePropertyName { get { return row_opaque_property_name; } set { if (value == row_opaque_property_name) { return; } row_opaque_property_name = value; row_opaque_property_info = null; row_opaque_property_invalid = false; InvalidateList (); } } private bool IsRowOpaque (object item) { if (item == null || row_opaque_property_invalid) { return true; } if (row_opaque_property_info == null || row_opaque_property_info.ReflectedType != item.GetType ()) { row_opaque_property_info = item.GetType ().GetProperty (row_opaque_property_name); if (row_opaque_property_info == null || row_opaque_property_info.PropertyType != typeof (bool)) { row_opaque_property_info = null; row_opaque_property_invalid = true; return true; } } return (bool)row_opaque_property_info.GetValue (item, null); } private string row_bold_property_name = "IsBold"; private PropertyInfo row_bold_property_info; bool row_bold_property_invalid = false; public string RowBoldPropertyName { get { return row_bold_property_name; } set { if (value == row_bold_property_name) { return; } row_bold_property_name = value; row_bold_property_info = null; row_bold_property_invalid = false; InvalidateList (); } } private bool IsRowBold (object item) { if (item == null || row_bold_property_invalid) { return false; } if (row_bold_property_info == null || row_bold_property_info.ReflectedType != item.GetType ()) { row_bold_property_info = item.GetType ().GetProperty (row_bold_property_name); if (row_bold_property_info == null || row_bold_property_info.PropertyType != typeof (bool)) { row_bold_property_info = null; row_bold_property_invalid = true; return false; } } return (bool)row_bold_property_info.GetValue (item, null); } } } hyena-0.5/Hyena.Gui/Hyena.Data.Gui/ListView/ListView_Windowing.cs0000644000175000001440000001625211377105500024722 0ustar00gabeusers00000000000000// // ListView_Windowing.cs // // Author: // Aaron Bockover // // Copyright (C) 2007-2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using Gdk; using Gtk; using Hyena.Gui.Theming; namespace Hyena.Data.Gui { public partial class ListView : ListViewBase { private Rectangle list_rendering_alloc; private Rectangle header_rendering_alloc; private Rectangle list_interaction_alloc; private Rectangle header_interaction_alloc; private Gdk.Window event_window; protected Rectangle ListAllocation { get { return list_rendering_alloc; } } protected Gdk.Window EventWindow { get { return event_window; } } protected override void OnRealized () { WidgetFlags |= WidgetFlags.Realized | WidgetFlags.NoWindow; GdkWindow = Parent.GdkWindow; cell_context.Drawable = GdkWindow; WindowAttr attributes = new WindowAttr (); attributes.WindowType = Gdk.WindowType.Child; attributes.X = Allocation.X; attributes.Y = Allocation.Y; attributes.Width = Allocation.Width; attributes.Height = Allocation.Height; attributes.Wclass = WindowClass.InputOnly; attributes.EventMask = (int)( EventMask.PointerMotionMask | EventMask.KeyPressMask | EventMask.KeyReleaseMask | EventMask.ButtonPressMask | EventMask.ButtonReleaseMask | EventMask.LeaveNotifyMask | EventMask.ExposureMask); WindowAttributesType attributes_mask = WindowAttributesType.X | WindowAttributesType.Y | WindowAttributesType.Wmclass; event_window = new Gdk.Window (GdkWindow, attributes, attributes_mask); event_window.UserData = Handle; OnDragSourceSet (); MoveResize (Allocation); base.OnRealized (); } protected override void OnUnrealized () { WidgetFlags &= ~WidgetFlags.Realized; event_window.UserData = IntPtr.Zero; Hyena.Gui.GtkWorkarounds.WindowDestroy (event_window); event_window = null; base.OnUnrealized (); } protected override void OnMapped () { WidgetFlags |= WidgetFlags.Mapped; event_window.Show (); } protected override void OnUnmapped () { WidgetFlags &= ~WidgetFlags.Mapped; event_window.Hide (); } protected int TranslateToListY (int y) { return y - list_interaction_alloc.Y; } private void MoveResize (Rectangle allocation) { if (Theme == null) { return; } header_rendering_alloc = allocation; header_rendering_alloc.Height = HeaderHeight; list_rendering_alloc.X = header_rendering_alloc.X + Theme.TotalBorderWidth; list_rendering_alloc.Y = header_rendering_alloc.Bottom + Theme.TotalBorderWidth; list_rendering_alloc.Width = allocation.Width - Theme.TotalBorderWidth * 2; list_rendering_alloc.Height = allocation.Height - (list_rendering_alloc.Y - allocation.Y) - Theme.TotalBorderWidth; header_interaction_alloc = header_rendering_alloc; header_interaction_alloc.X = list_rendering_alloc.X; header_interaction_alloc.Width = list_rendering_alloc.Width; header_interaction_alloc.Height += Theme.BorderWidth; header_interaction_alloc.Offset (-allocation.X, -allocation.Y); list_interaction_alloc = list_rendering_alloc; list_interaction_alloc.Offset (-allocation.X, -allocation.Y); header_width = header_interaction_alloc.Width; } protected override void OnSizeRequested (ref Requisition requisition) { // TODO give the minimum height of the header if (Theme == null) { return; } requisition.Width = Theme.TotalBorderWidth * 2; requisition.Height = HeaderHeight + Theme.TotalBorderWidth * 2; } protected override void OnSizeAllocated (Rectangle allocation) { base.OnSizeAllocated (allocation); if (IsRealized) { event_window.MoveResize (allocation); } MoveResize (allocation); RecalculateColumnSizes (); RegenerateColumnCache (); if (ViewLayout != null) { ViewLayout.Allocate ((Hyena.Gui.Canvas.Rect)list_rendering_alloc); } if (vadjustment != null) { hadjustment.PageSize = header_interaction_alloc.Width; hadjustment.PageIncrement = header_interaction_alloc.Width; vadjustment.PageSize = list_rendering_alloc.Height; vadjustment.PageIncrement = list_rendering_alloc.Height; UpdateAdjustments (); } ICareAboutView model = Model as ICareAboutView; if (model != null) { model.RowsInView = RowsInView; } OnInvalidateMeasure (); InvalidateList (); } protected int ItemsInView { get { // FIXME hardcoded grid int columns = ViewLayout == null ? 1 : (ViewLayout as DataViewLayoutGrid).Columns; return RowsInView * columns; } } // FIXME: obsolete protected int RowsInView { get { if (ChildSize.Height <= 0) { return 0; } return (int)Math.Ceiling ((list_rendering_alloc.Height + ChildSize.Height) / (double)ChildSize.Height); } } private DataViewLayout view_layout; protected DataViewLayout ViewLayout { get { return view_layout; } set { view_layout = value; QueueResize (); } } } } hyena-0.5/Hyena.Gui/Hyena.Data.Gui/ListView/ListView_Accessible.cs0000644000175000001440000001370511377105500025012 0ustar00gabeusers00000000000000// // ListView_Accessible.cs // // Authors: // Gabriel Burt // Eitan Isaacson // // Copyright (C) 2009 Novell, Inc. // Copyright (C) 2009 Eitan Isaacson // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Linq; using System.Collections.Generic; using Gtk; using Hyena.Data.Gui.Accessibility; namespace Hyena.Data.Gui { public partial class ListView : ListViewBase { static ListView () { #if ENABLE_ATK ListViewAccessibleFactory.Init (); #endif } public Gdk.Rectangle GetColumnCellExtents (int row, int column) { return GetColumnCellExtents (row, column, true); } public Gdk.Rectangle GetColumnCellExtents (int row, int column, bool clip) { return GetColumnCellExtents (row, column, clip, Atk.CoordType.Window); } public Gdk.Rectangle GetColumnCellExtents (int row, int column, bool clip, Atk.CoordType coord_type) { int width = GetColumnWidth (column); int height = ChildSize.Height; int y = (int)GetViewPointForModelRow (row).Y - VadjustmentValue + ListAllocation.Y; int x = ListAllocation.X - HadjustmentValue; for (int index=0;index c.Visible).ElementAtOrDefault (column); OnColumnRightClicked (col, rectangle.X + rectangle.Width/2, rectangle.Y + rectangle.Height/2); } public void ClickColumnHeader (int column) { Column col = ColumnController.Where (c => c.Visible).ElementAtOrDefault (column); OnColumnLeftClicked (col); } private void AccessibleCellRedrawn (int column, int row) { var accessible = Accessible as ICellAccessibleParent; if (accessible != null) { accessible.CellRedrawn (column, row); } } } #if ENABLE_ATK internal class ListViewAccessibleFactory : Atk.ObjectFactory { public static void Init () { new ListViewAccessibleFactory (); Atk.Global.DefaultRegistry.SetFactoryType ((GLib.GType)typeof (ListView), (GLib.GType)typeof (ListViewAccessibleFactory)); } protected override Atk.Object OnCreateAccessible (GLib.Object obj) { return new ListViewAccessible (obj); } protected override GLib.GType OnGetAccessibleType () { return ListViewAccessible.GType; } } #endif } hyena-0.5/Hyena.Gui/Hyena.Data.Gui/ListView/ListViewBase.cs0000644000175000001440000000413711377105500023467 0ustar00gabeusers00000000000000// // ListViewBase.cs // // Author: // Aaron Bockover // // Copyright (C) 2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using Gtk; namespace Hyena.Data.Gui { public class ListViewBase : Widget { protected ListViewBase (IntPtr ptr) : base (ptr) { } public ListViewBase () { } public void QueueDirtyRegion (Gdk.Rectangle region) { region.Intersect (Allocation); QueueDrawArea (region.X, region.Y, region.Width, region.Height); } public void QueueDirtyRegion (Hyena.Gui.Canvas.Rect region) { QueueDirtyRegion ((Gdk.Rectangle)region); } public void QueueDirtyRegion (Cairo.Rectangle region) { QueueDirtyRegion (new Gdk.Rectangle () { X = (int)Math.Floor (region.X), Y = (int)Math.Floor (region.Y), Width = (int)Math.Ceiling (region.Width), Height = (int)Math.Ceiling (region.Height) }); } } } hyena-0.5/Hyena.Gui/Hyena.Data.Gui/ListView/ListView_Header.cs0000644000175000001440000005433111377105500024145 0ustar00gabeusers00000000000000// // ListView_Header.cs // // Author: // Aaron Bockover // // Copyright (C) 2007-2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Collections.Generic; using Mono.Unix; using Gtk; namespace Hyena.Data.Gui { public partial class ListView : ListViewBase { internal struct CachedColumn { public static readonly CachedColumn Zero; public Column Column; public int X1; public int X2; public int Width; public int MinWidth; public int MaxWidth; public int ResizeX1; public int ResizeX2; public int Index; public double ElasticWidth; public double ElasticPercent; } private static Gdk.Cursor resize_x_cursor = new Gdk.Cursor (Gdk.CursorType.SbHDoubleArrow); private static Gdk.Cursor drag_cursor = new Gdk.Cursor (Gdk.CursorType.Fleur); private bool resizable; private int header_width; private double list_width, max_width; private int sort_column_index = -1; private int resizing_column_index = -1; private int pressed_column_index = -1; private int pressed_column_x = -1; private int pressed_column_x_start = -1; private int pressed_column_x_offset = -1; private int pressed_column_x_drag = -1; private int pressed_column_x_start_hadjustment = -1; private bool pressed_column_is_dragging = false; private bool pressed_column_drag_started = false; private Pango.Layout column_layout; private CachedColumn [] column_cache; private List elastic_columns; public int Width { get { return (int)list_width; } } public int MaxWidth { get { return (int)max_width + Theme.TotalBorderWidth*2; } } #region Columns private void InvalidateColumnCache () { column_cache = null; } private void GenerateColumnCache () { column_cache = new CachedColumn[column_controller.Count]; int i = 0; double total = 0.0; foreach (Column column in column_controller) { if (!column.Visible) { continue; } // If we don't already have a MinWidth set, use the width of our Title text column.CalculateWidths (column_layout, HeaderVisible, HeaderHeight); column_cache[i] = new CachedColumn (); column_cache[i].Column = column; column_cache[i].Index = i; total += column.Width; i++; } Array.Resize (ref column_cache, i); double scale_factor = 1.0 / total; for (i = 0; i < column_cache.Length; i++) { column_cache[i].Column.Width *= scale_factor; if (column_cache[i].Column.Width <= 0) { Hyena.Log.Warning ("Overriding 0-computed column cache width"); column_cache[i].Column.Width = 0.01; } } RecalculateColumnSizes (); } private void RegenerateColumnCache () { if (column_controller == null) { return; } if (column_cache == null) { GenerateColumnCache (); } for (int i = 0; i < column_cache.Length; i++) { // Calculate this column's proportional share of the width, and set positions (X1/X2) column_cache[i].Width = (int)Math.Round (((double)header_width * column_cache[i].Column.Width)); column_cache[i].X1 = i == 0 ? 0 : column_cache[i - 1].X2; column_cache[i].X2 = column_cache[i].X1 + column_cache[i].Width; column_cache[i].ResizeX1 = column_cache[i].X2; column_cache[i].ResizeX2 = column_cache[i].ResizeX1 + 2; } // TODO handle max width int index = column_cache.Length - 1; if (index >= 0) { column_cache[index].X2 = header_width; column_cache[index].Width = column_cache[index].X2 - column_cache[index].X1; } } private void RecalculateColumnSizes () { if (column_cache == null) { return; } ISortable sortable = Model as ISortable; sort_column_index = -1; int min_header_width = 0; for (int i = 0; i < column_cache.Length; i++) { if (sortable != null) { ColumnHeaderCellText column_cell = column_cache[i].Column.HeaderCell as ColumnHeaderCellText; if (column_cell != null) { ISortableColumn sort_column = column_cache[i].Column as ISortableColumn; column_cell.HasSort = sort_column != null && sortable.SortColumn == sort_column; if (column_cell.HasSort) { sort_column_index = i; } } } column_cache[i].Column.CalculateWidths (column_layout, HeaderVisible, HeaderHeight); column_cache[i].MaxWidth = column_cache[i].Column.MaxWidth; column_cache[i].MinWidth = column_cache[i].Column.MinWidth; min_header_width += column_cache[i].MinWidth; } if (column_cache.Length == 1) { column_cache[0].Column.Width = 1.0; } else if (min_header_width >= header_interaction_alloc.Width) { header_width = min_header_width; resizable = false; for (int i = 0; i < column_cache.Length; i++) { column_cache[i].Column.Width = (double)column_cache[i].MinWidth / (double)header_width; } } else { header_width = header_interaction_alloc.Width; resizable = true; if (elastic_columns == null) { elastic_columns = new List (column_cache.Length); } elastic_columns.Clear (); for (int i = 0; i < column_cache.Length; i++) { elastic_columns.Add (i); column_cache[i].ElasticWidth = 0.0; column_cache[i].ElasticPercent = column_cache[i].Column.Width * header_width; } double remaining_width = RecalculateColumnSizes (header_width, header_width); while (Math.Round (remaining_width) != 0.0 && elastic_columns.Count > 0) { double total_elastic_width = 0.0; foreach (int i in elastic_columns) { total_elastic_width += column_cache[i].ElasticWidth; } remaining_width = RecalculateColumnSizes (remaining_width, total_elastic_width); } for (int i = 0; i < column_cache.Length; i++) { column_cache[i].Column.Width = column_cache[i].ElasticWidth / (double)header_width; } } double tmp_width = 0.0; double tmp_max = 0.0; foreach (var col in column_cache) { tmp_width += col.ElasticWidth; tmp_max += col.MaxWidth == Int32.MaxValue ? col.MinWidth : col.MaxWidth; } list_width = tmp_width; max_width = tmp_max; } private double RecalculateColumnSizes (double total_width, double total_elastic_width) { double remaining_width = total_width; for (int index = 0; index < elastic_columns.Count; index++) { int i = elastic_columns[index]; double percent = column_cache[i].ElasticPercent / total_elastic_width; double delta = total_width * percent; // TODO handle max widths double width = column_cache[i].ElasticWidth + delta; if (width < column_cache[i].MinWidth) { delta = column_cache[i].MinWidth - column_cache[i].ElasticWidth; elastic_columns.RemoveAt (index); index--; } else if (width > column_cache[i].MaxWidth) { delta = column_cache[i].MaxWidth - column_cache[i].ElasticWidth; elastic_columns.RemoveAt (index); index--; } remaining_width -= delta; column_cache[i].ElasticWidth += delta; } if (Math.Abs (total_width - remaining_width) < 1.0 || remaining_width == Double.NaN) { Hyena.Log.Warning ("Forcefully breaking out of RCS loop b/c change in total_width less than 1.0"); return 0; } return Math.Round (remaining_width); } protected virtual void OnColumnControllerUpdated () { InvalidateColumnCache (); RegenerateColumnCache (); UpdateAdjustments (); QueueDirtyRegion (); } protected virtual void OnColumnLeftClicked (Column clickedColumn) { if (Model is ISortable && clickedColumn is ISortableColumn) { ISortableColumn sort_column = clickedColumn as ISortableColumn; ISortable sortable = Model as ISortable; // Change the sort-type with every click if (sort_column == ColumnController.SortColumn) { switch (sort_column.SortType) { case SortType.Ascending: sort_column.SortType = SortType.Descending; break; case SortType.Descending: sort_column.SortType = SortType.None; break; case SortType.None: sort_column.SortType = SortType.Ascending; break; } } // If we're switching from a different column, or we aren't reorderable, make sure sort type isn't None if ((sort_column != ColumnController.SortColumn || !IsEverReorderable) && sort_column.SortType == SortType.None) { sort_column.SortType = SortType.Ascending; } sortable.Sort (sort_column); ColumnController.SortColumn = sort_column; IsReorderable = sortable.SortColumn == null || sortable.SortColumn.SortType == SortType.None; Model.Reload (); CenterOnSelection (); RecalculateColumnSizes (); RegenerateColumnCache (); InvalidateHeader (); } } protected virtual void OnColumnRightClicked (Column clickedColumn, int x, int y) { Column [] columns = ColumnController.ToArray (); Array.Sort (columns, delegate (Column a, Column b) { // Fully qualified type name to avoid Mono 1.2.4 bug return System.String.Compare (a.Title, b.Title); }); uint items = 0; for (int i = 0; i < columns.Length; i++) { if (columns[i].Id != null) { items++; } } uint max_items_per_column = 15; if (items >= max_items_per_column * 2) { max_items_per_column = (uint)Math.Ceiling (items / 3.0); } else if (items >= max_items_per_column) { max_items_per_column = (uint)Math.Ceiling (items / 2.0); } uint column_count = (uint)Math.Ceiling (items / (double)max_items_per_column); Menu menu = new Menu (); uint row_offset = 2; if (clickedColumn.Id != null) { // FIXME: Also restrict if the column vis can't be changed menu.Attach (new ColumnHideMenuItem (clickedColumn), 0, column_count, 0, 1); menu.Attach (new SeparatorMenuItem (), 0, column_count, 1, 2); } items = 0; for (uint i = 0, n = (uint)columns.Length, column = 0, row = 0; i < n; i++) { if (columns[i].Id == null) { continue; } row = items++ % max_items_per_column; menu.Attach (new ColumnToggleMenuItem (columns[i]), column, column + 1, row + row_offset, row + 1 + row_offset); if (row == max_items_per_column - 1) { column++; } } menu.ShowAll (); menu.Popup (null, null, delegate (Menu popup, out int pos_x, out int pos_y, out bool push_in) { int win_x, win_y; GdkWindow.GetOrigin (out win_x, out win_y); pos_x = win_x + x; pos_y = win_y + y; push_in = true; }, 3, Gtk.Global.CurrentEventTime); } private void ResizeColumn (double x) { CachedColumn resizing_column = column_cache[resizing_column_index]; double resize_delta = x - resizing_column.ResizeX2; // If this column cannot be resized, check the columns to the left. int real_resizing_column_index = resizing_column_index; while (resizing_column.MinWidth == resizing_column.MaxWidth) { if (real_resizing_column_index == 0) { return; } resizing_column = column_cache[--real_resizing_column_index]; } // Make sure the resize_delta won't make us smaller than the min if (resizing_column.Width + resize_delta < resizing_column.MinWidth) { resize_delta = resizing_column.MinWidth - resizing_column.Width; } // Make sure the resize_delta won't make us bigger than the max if (resizing_column.Width + resize_delta > resizing_column.MaxWidth) { resize_delta = resizing_column.MaxWidth - resizing_column.Width; } if (resize_delta == 0) { return; } int sign = Math.Sign (resize_delta); resize_delta = Math.Abs (resize_delta); double total_elastic_width = 0.0; for (int i = real_resizing_column_index + 1; i < column_cache.Length; i++) { total_elastic_width += column_cache[i].ElasticWidth = sign == 1 ? column_cache[i].Width - column_cache[i].MinWidth : column_cache[i].MaxWidth - column_cache[i].Width; } if (total_elastic_width == 0) { return; } if (resize_delta > total_elastic_width) { resize_delta = total_elastic_width; } // Convert to a proprotional width resize_delta = sign * resize_delta / (double)header_width; for (int i = real_resizing_column_index + 1; i < column_cache.Length; i++) { column_cache[i].Column.Width += -resize_delta * (column_cache[i].ElasticWidth / total_elastic_width); } resizing_column.Column.Width += resize_delta; RegenerateColumnCache (); QueueDraw (); } private Column GetColumnForResizeHandle (int x) { if (column_cache == null || !resizable) { return null; } x += HadjustmentValue; for (int i = 0; i < column_cache.Length - 1; i++) { if (x < column_cache[i].ResizeX1 - 2) { // No point in checking other columns since their ResizeX1 are even larger break; } else if (x <= column_cache[i].ResizeX2 + 2 && CanResizeColumn (i)) { return column_cache[i].Column; } } return null; } protected int GetColumnWidth (int column_index) { CachedColumn cached_column = column_cache[column_index]; return cached_column.Width; } private bool CanResizeColumn (int column_index) { // At least one column to the left (including the one being resized) should be resizable. bool found = false; for (int i = column_index; i >= 0 ; i--) { if (column_cache[i].Column.MaxWidth != column_cache[i].Column.MinWidth) { found = true; break; } } if (!found) { return false; } // At least one column to the right should be resizable as well. for (int i = column_index + 1; i < column_cache.Length; i++) { if (column_cache[i].Column.MaxWidth != column_cache[i].Column.MinWidth) { return true; } } return false; } private Column GetColumnAt (int x) { if (column_cache == null) { return null; } x += HadjustmentValue; foreach (CachedColumn column in column_cache) { if (x >= column.X1 && x <= column.X2) { return column.Column; } } return null; } private CachedColumn GetCachedColumnForColumn (Column col) { foreach (CachedColumn ca_col in column_cache) { if (ca_col.Column == col) { return ca_col; } } return CachedColumn.Zero; } private ColumnController column_controller; public ColumnController ColumnController { get { return column_controller; } set { if (column_controller == value) { return; } if (column_controller != null) { column_controller.Updated -= OnColumnControllerUpdatedHandler; } column_controller = value; OnColumnControllerUpdated (); if (column_controller != null) { column_controller.Updated += OnColumnControllerUpdatedHandler; } } } #endregion #region Header private int header_height = 0; private int HeaderHeight { get { // FIXME: ViewLayout should have the header info and never be null if (!header_visible || ViewLayout != null) { return 0; } if (header_height == 0) { int w; int h; column_layout.SetText ("W"); column_layout.GetPixelSize (out w, out h); header_height = h; header_height += 10; } return header_height; } } private bool header_visible = true; public bool HeaderVisible { get { return header_visible; } set { header_visible = value; MoveResize (Allocation); } } #endregion #region Gtk.MenuItem Wrappers for the column context menu private class ColumnToggleMenuItem : CheckMenuItem { private Column column; private bool ready = false; private Label label; public ColumnToggleMenuItem (Column column) : base () { this.column = column; Active = column.Visible; ready = true; label = new Label (); label.Xalign = 0.0f; label.Text = column.LongTitle ?? String.Empty; label.Show (); Add (label); } protected override void OnStyleSet (Style previousStyle) { base.OnStyleSet (previousStyle); label.ModifyFg (StateType.Prelight, Style.Foreground (StateType.Selected)); } protected override void OnActivated () { base.OnActivated (); if (!ready) { return; } column.Visible = Active; } } private class ColumnHideMenuItem : ImageMenuItem { private Column column; private Label label; public ColumnHideMenuItem (Column column) : base () { this.column = column; this.Image = new Image (Stock.Remove, IconSize.Menu); label = new Label (); label.Xalign = 0.0f; label.Markup = String.Format (Catalog.GetString ("Hide {0}"), GLib.Markup.EscapeText (column.LongTitle)); label.Show (); Add (label); } protected override void OnStyleSet (Style previousStyle) { base.OnStyleSet (previousStyle); label.ModifyFg (StateType.Prelight, Style.Foreground (StateType.Selected)); } protected override void OnActivated () { column.Visible = false; } } #endregion } } hyena-0.5/Hyena.Gui/Hyena.Data.Gui/ListView/ListView_Interaction.cs0000644000175000001440000010766311377105500025243 0ustar00gabeusers00000000000000// // ListView_Interaction.cs // // Authors: // Aaron Bockover // Gabriel Burt // Eitan Isaacson // // Copyright (C) 2007-2009 Novell, Inc. // Copyright (C) 2009 Eitan Isaacson // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using Gtk; using Hyena.Collections; using Hyena.Gui.Canvas; using Selection = Hyena.Collections.Selection; namespace Hyena.Data.Gui { public partial class ListView : ListViewBase { private bool header_focused = false; public bool HeaderFocused { get { return header_focused; } set { header_focused = value; InvalidateHeader (); InvalidateList (); } } #pragma warning disable 0067 public event EventHandler ActiveColumnChanged; #pragma warning restore 0067 private int active_column = 0; public int ActiveColumn { get { return active_column; } set { active_column = value; var handler = ActiveColumnChanged; if (handler != null) { handler (this, EventArgs.Empty); } } } private Adjustment vadjustment; public Adjustment Vadjustment { get { return vadjustment; } } private Adjustment hadjustment; public Adjustment Hadjustment { get { return hadjustment; } } private SelectionProxy selection_proxy = new SelectionProxy (); public SelectionProxy SelectionProxy { get { return selection_proxy; } } public Selection Selection { get { return model == null ? null : model.Selection; } } private int HadjustmentValue { get { return hadjustment == null ? 0 : (int)hadjustment.Value; } } private int VadjustmentValue { get { return vadjustment == null ? 0 : (int)vadjustment.Value; } } public event RowActivatedHandler RowActivated; #region Row/Selection, Keyboard/Mouse Interaction private bool KeyboardScroll (Gdk.ModifierType modifier, int relative_row, bool align_y) { if (Model == null) { return true; } int row_limit; if (relative_row < 0) { if (Selection.FocusedIndex == -1) { return false; } row_limit = 0; } else { row_limit = Model.Count - 1; } if (Selection.FocusedIndex == row_limit) { return true; } int row_index = Math.Min (Model.Count - 1, Math.Max (0, Selection.FocusedIndex + relative_row)); if (Selection != null) { if ((modifier & Gdk.ModifierType.ControlMask) != 0) { // Don't change the selection } else if ((modifier & Gdk.ModifierType.ShiftMask) != 0) { // Behave like nautilus: if and arrow key + shift is pressed and the currently focused item // is not selected, select it and don't move the focus or vadjustment. // Otherwise, select the new row and scroll etc as necessary. if (relative_row * relative_row != 1) { Selection.SelectFromFirst (row_index, true); } else if (Selection.Contains (Selection.FocusedIndex)) { Selection.SelectFromFirst (row_index, true); } else { Selection.Select (Selection.FocusedIndex); return true; } } else { Selection.Clear (false); Selection.Select (row_index); } } // Scroll if needed double y_at_row = GetViewPointForModelRow (row_index).Y; if (align_y) { if (y_at_row < VadjustmentValue) { ScrollToY (y_at_row); } else if (vadjustment != null) { var bottom_of_item = y_at_row + ChildSize.Height; var bottom_of_view = vadjustment.Value + vadjustment.PageSize; if (bottom_of_item > bottom_of_view) { // Scroll down just enough to put the item fully into view ScrollToY (bottom_of_item - (vadjustment.PageSize)); } } } else if (vadjustment != null) { ScrollToY (vadjustment.Value + y_at_row - GetViewPointForModelRow (Selection.FocusedIndex).Y); } Selection.FocusedIndex = row_index; InvalidateList (); return true; } protected override bool OnKeyPressEvent (Gdk.EventKey press) { bool handled = false; // FIXME: hard-coded grid logic here... bool grid = ViewLayout != null; int items_per_row = grid ? (ViewLayout as DataViewLayoutGrid).Columns : 1; switch (press.Key) { case Gdk.Key.a: if ((press.State & Gdk.ModifierType.ControlMask) != 0 && Model.Count > 0) { SelectionProxy.Selection.SelectAll (); handled = true; } break; case Gdk.Key.A: if ((press.State & Gdk.ModifierType.ControlMask) != 0 && Selection.Count > 0) { SelectionProxy.Selection.Clear (); handled = true; } break; case Gdk.Key.k: case Gdk.Key.K: case Gdk.Key.Up: case Gdk.Key.KP_Up: if (!HeaderFocused) { handled = KeyboardScroll (press.State, -items_per_row, true); } break; case Gdk.Key.j: case Gdk.Key.J: case Gdk.Key.Down: case Gdk.Key.KP_Down: if (!HeaderFocused) { handled = KeyboardScroll (press.State, items_per_row, true); } else { handled = true; HeaderFocused = false; } break; case Gdk.Key.Right: case Gdk.Key.KP_Right: handled = true; if (grid && !HeaderFocused) { handled = KeyboardScroll (press.State, 1, true); } else if (ActiveColumn + 1 < column_cache.Length) { ActiveColumn++; InvalidateHeader (); } break; case Gdk.Key.Left: case Gdk.Key.KP_Left: handled = true; if (grid && !HeaderFocused) { handled = KeyboardScroll (press.State, -1, true); } else if (ActiveColumn - 1 >= 0) { ActiveColumn--; InvalidateHeader (); } break; case Gdk.Key.Page_Up: case Gdk.Key.KP_Page_Up: if (!HeaderFocused) handled = vadjustment != null && KeyboardScroll (press.State, (int)(-vadjustment.PageIncrement / (double)ChildSize.Height) * items_per_row, false); break; case Gdk.Key.Page_Down: case Gdk.Key.KP_Page_Down: if (!HeaderFocused) handled = vadjustment != null && KeyboardScroll (press.State, (int)(vadjustment.PageIncrement / (double)ChildSize.Height) * items_per_row, false); break; case Gdk.Key.Home: case Gdk.Key.KP_Home: if (!HeaderFocused) handled = KeyboardScroll (press.State, -10000000, true); break; case Gdk.Key.End: case Gdk.Key.KP_End: if (!HeaderFocused) handled = KeyboardScroll (press.State, 10000000, true); break; case Gdk.Key.Return: case Gdk.Key.KP_Enter: if (!HeaderFocused) { handled = ActivateSelection (); } else if (HeaderFocused && ActiveColumn >= 0) { OnColumnLeftClicked ( column_cache[ActiveColumn].Column); handled = true; } break; case Gdk.Key.Escape: handled = CancelColumnDrag (); break; case Gdk.Key.space: if (Selection != null && Selection.FocusedIndex != 1 && !HeaderFocused) { Selection.ToggleSelect (Selection.FocusedIndex); handled = true; } break; case Gdk.Key.F10: if ((press.State & Gdk.ModifierType.ShiftMask) != 0) goto case Gdk.Key.Menu; break; case Gdk.Key.Menu: // OnPopupMenu() is reserved for list items in derived classes. if (HeaderFocused) { InvokeColumnHeaderMenu (ActiveColumn); handled = true; } break; } if (handled) { return true; } return base.OnKeyPressEvent (press); } protected bool ActivateSelection () { if (Selection != null && Selection.FocusedIndex != -1) { Selection.Clear (false); Selection.Select (Selection.FocusedIndex); OnRowActivated (); return true; } return false; } #region DataViewLayout Interaction Events private DataViewChild last_layout_child; private bool LayoutChildHandlesEvent (Gdk.Event evnt, bool press) { if (ViewLayout == null) { return false; } var point = new Point (0, 0); bool handled = false; var evnt_button = evnt as Gdk.EventButton; var evnt_motion = evnt as Gdk.EventMotion; if (evnt_motion != null) { point = new Point (evnt_motion.X, evnt_motion.Y); } else if (evnt_button != null) { point = new Point (evnt_button.X, evnt_button.Y); } else if (evnt is Gdk.EventCrossing && last_layout_child != null) { last_layout_child.CursorLeaveEvent (); last_layout_child = null; return false; } var child = GetLayoutChildAt (point); if (child == null) { return false; } point.Offset (-child.VirtualAllocation.X, -child.VirtualAllocation.Y); if (evnt_motion != null) { if (last_layout_child != child) { if (last_layout_child != null) { last_layout_child.CursorLeaveEvent (); } last_layout_child = child; child.CursorEnterEvent (); } handled = child.CursorMotionEvent (point); } else if (evnt_button != null) { handled = child.ButtonEvent (point, press, evnt_button.Button); } return handled; } private DataViewChild GetLayoutChildAt (Point point) { point.Offset (-list_interaction_alloc.X, -list_interaction_alloc.Y); return ViewLayout.FindChildAtPoint (point); } #endregion #region Cell Event Proxy (FIXME: THIS ENTIRE SECTION IS OBSOLETE YAY YAY YAY!) private IInteractiveCell last_icell; private Gdk.Rectangle last_icell_area = Gdk.Rectangle.Zero; private void InvalidateLastIcell () { if (last_icell != null && last_icell.PointerLeaveEvent ()) { QueueDirtyRegion (last_icell_area); last_icell = null; last_icell_area = Gdk.Rectangle.Zero; } } private void ProxyEventToCell (Gdk.Event evnt, bool press) { IInteractiveCell icell; Gdk.Rectangle icell_area; bool redraw = ProxyEventToCell (evnt, press, out icell, out icell_area); int xoffset = HadjustmentValue; int yoffset = VadjustmentValue; if (last_icell_area != icell_area) { if (last_icell != null && last_icell.PointerLeaveEvent ()) { QueueDirtyRegion (new Gdk.Rectangle () { X = last_icell_area.X - xoffset, Y = last_icell_area.Y - yoffset, Width = last_icell_area.Width, Height = last_icell_area.Height }); } last_icell = icell; last_icell_area = icell_area; } if (redraw) { QueueDirtyRegion (new Gdk.Rectangle () { X = icell_area.X - xoffset, Y = icell_area.Y - yoffset, Width = icell_area.Width, Height = icell_area.Height }); } } private bool ProxyEventToCell (Gdk.Event evnt, bool press, out IInteractiveCell icell, out Gdk.Rectangle icell_area) { icell = null; icell_area = Gdk.Rectangle.Zero; int evnt_x, evnt_y; int x, y, row_index; x = y = row_index = 0; var evnt_button = evnt as Gdk.EventButton; var evnt_motion = evnt as Gdk.EventMotion; if (evnt_motion != null) { evnt_x = (int)evnt_motion.X; evnt_y = (int)evnt_motion.Y; } else if (evnt_button != null) { evnt_x = (int)evnt_button.X; evnt_y = (int)evnt_button.Y; } else { // Possibly EventCrossing, for the leave event icell = last_icell; return false; } Column column; if (!GetEventCell (evnt_x, evnt_y, out icell, out column, out row_index)) { return false; } x = evnt_x - list_interaction_alloc.X; y = evnt_y - list_interaction_alloc.Y; // Turn the view-absolute coordinates into cell-relative coordinates CachedColumn cached_column = GetCachedColumnForColumn (column); x -= cached_column.X1 - HadjustmentValue; int page_offset = VadjustmentValue % ChildSize.Height; y = (y + page_offset) % ChildSize.Height; var view_point = GetViewPointForModelRow (row_index); icell_area.Y = (int)view_point.Y + list_interaction_alloc.Y + Allocation.Y; icell_area.X = cached_column.X1 + Allocation.X; icell_area.Width = cached_column.Width; icell_area.Height = ChildSize.Height; // Send the cell a synthesized input event if (evnt_motion != null) { return icell.MotionEvent (x, y, evnt_motion); } else { return icell.ButtonEvent (x, y, press, evnt_button); } } #pragma warning disable 0169 private bool GetEventCell (int x, int y, out G icell, out Column column, out int row_index) where G : class { icell = null; column = null; row_index = 0; if (Model == null) { return false; } x -= list_interaction_alloc.X; y -= list_interaction_alloc.Y; row_index = GetModelRowAt (x, y); if (row_index < 0 || row_index >= Model.Count) { return false; } column = GetColumnAt (x); if (column == null) { return false; } ColumnCell cell = column.GetCell (0); icell = cell as G; if (icell == null) { return false; } // Bind the row to the cell cell.BindListItem (model[row_index]); return true; } #pragma warning restore 0169 #endregion #region OnButtonPress protected override bool OnButtonPressEvent (Gdk.EventButton evnt) { HasFocus = true; if (header_visible && header_interaction_alloc.Contains ((int)evnt.X, (int)evnt.Y)) { HeaderFocused = true; return OnHeaderButtonPressEvent (evnt); } else if (list_interaction_alloc.Contains ((int)evnt.X, (int)evnt.Y) && model != null) { HeaderFocused = false; return OnListButtonPressEvent (evnt); } return true; } private bool OnHeaderButtonPressEvent (Gdk.EventButton evnt) { int x = (int)evnt.X - header_interaction_alloc.X; int y = (int)evnt.Y - header_interaction_alloc.Y; if (evnt.Button == 3 && ColumnController.EnableColumnMenu) { Column menu_column = GetColumnAt (x); if (menu_column != null) { OnColumnRightClicked (menu_column, x + Allocation.X, y + Allocation.Y); } return true; } else if (evnt.Button != 1) { return true; } Gtk.Drag.SourceUnset (this); Column column = GetColumnForResizeHandle (x); if (column != null) { resizing_column_index = GetCachedColumnForColumn (column).Index; } else { column = GetColumnAt (x); if (column != null) { CachedColumn column_c = GetCachedColumnForColumn (column); pressed_column_index = column_c.Index; pressed_column_x_start = x; pressed_column_x_offset = pressed_column_x_start - column_c.X1; pressed_column_x_start_hadjustment = HadjustmentValue; } } return true; } private bool OnListButtonPressEvent (Gdk.EventButton evnt) { if (Model == null) { return true; } int x = (int)evnt.X - list_interaction_alloc.X; int y = (int)evnt.Y - list_interaction_alloc.Y; GrabFocus (); int row_index = GetModelRowAt (x, y); if (row_index < 0 || row_index >= Model.Count) { Gtk.Drag.SourceUnset (this); return true; } if (LayoutChildHandlesEvent (evnt, true)) { return true; } ProxyEventToCell (evnt, true); object item = model[row_index]; if (item == null) { return true; } if (evnt.Button == 1 && evnt.Type == Gdk.EventType.TwoButtonPress) { // Double clicked OnRowActivated (); } else if (Selection != null) { if ((evnt.State & Gdk.ModifierType.ControlMask) != 0) { if (evnt.Button == 3) { // Right clicked with ctrl pressed, so make sure row selected if (!Selection.Contains (row_index)) { Selection.Select (row_index); } } else { // Normal ctrl-click, so toggle Selection.ToggleSelect (row_index); } } else if ((evnt.State & Gdk.ModifierType.ShiftMask) != 0) { // Shift-click, so select from first-row-selected (if any) to the current row Selection.SelectFromFirst (row_index, true); } else { if (evnt.Button == 3) { // Normal right-click, make sure row is only row selected if (!Selection.Contains (row_index)) { Selection.Clear (false); Selection.Select (row_index); } } else { // Normal click, if row not already selected, select only it right now, // but if it's already selected, wait until the Release to unselect any others so that // drag and drop of 2+ items works. if (!Selection.Contains (row_index)) { Selection.Clear (false); Selection.Select (row_index); } } } FocusModelRow (row_index); // Now that we've worked out the selections, open the context menu if (evnt.Button == 3) { OnPopupMenu (); } } InvalidateList (); return true; } #endregion #region OnButtonRelease protected override bool OnButtonReleaseEvent (Gdk.EventButton evnt) { OnDragSourceSet (); StopDragScroll (); if (resizing_column_index >= 0) { pressed_column_index = -1; resizing_column_index = -1; GdkWindow.Cursor = null; return true; } if (pressed_column_drag_started) { CancelColumnDrag (); pressed_column_drag_started = false; return true; } if (header_visible && header_interaction_alloc.Contains ((int)evnt.X, (int)evnt.Y)) { return OnHeaderButtonRelease (evnt); } else if (list_interaction_alloc.Contains ((int)evnt.X, (int)evnt.Y) && model != null && (evnt.State & (Gdk.ModifierType.ShiftMask | Gdk.ModifierType.ControlMask)) == 0) { if (LayoutChildHandlesEvent (evnt, false)) { return true; } ProxyEventToCell (evnt, false); return OnListButtonRelease (evnt); } return true; } private bool OnHeaderButtonRelease (Gdk.EventButton evnt) { if (pressed_column_index >= 0 && pressed_column_index < column_cache.Length) { Column column = column_cache[pressed_column_index].Column; ActiveColumn = pressed_column_index; if (column != null) OnColumnLeftClicked (column); pressed_column_index = -1; return true; } else { return false; } } private bool OnListButtonRelease (Gdk.EventButton evnt) { if (Model == null) { return true; } int x = (int)evnt.X - list_interaction_alloc.X; int y = (int)evnt.Y - list_interaction_alloc.Y; GrabFocus (); int row_index = GetModelRowAt (x, y); if (row_index >= Model.Count) { return true; } object item = model[row_index]; if (item == null) { return true; } //if (Selection != null && Selection.Contains (row_index) && Selection.Count > 1) { if (Selection != null && evnt.Button == 1 && Hyena.Gui.GtkUtilities.NoImportantModifiersAreSet ()) { if (Selection.Count > 1) { Selection.Clear (false); Selection.Select (row_index); FocusModelRow (row_index); InvalidateList (); } } return true; } #endregion protected override bool OnMotionNotifyEvent (Gdk.EventMotion evnt) { int x = (int)evnt.X - header_interaction_alloc.X; if (pressed_column_index >= 0 && !pressed_column_is_dragging && Gtk.Drag.CheckThreshold (this, pressed_column_x_start, 0, x, 0)) { pressed_column_is_dragging = true; pressed_column_drag_started = true; InvalidateHeader (); InvalidateList (); } pressed_column_x = x; if (OnMotionNotifyEvent (x)) { return true; } GdkWindow.Cursor = header_interaction_alloc.Contains ((int)evnt.X, (int)evnt.Y) && (resizing_column_index >= 0 || GetColumnForResizeHandle (x) != null) ? resize_x_cursor : null; if (resizing_column_index >= 0) { ResizeColumn (x); } if (LayoutChildHandlesEvent (evnt, false)) { return true; } ProxyEventToCell (evnt, false); return true; } private bool OnMotionNotifyEvent (int x) { if (!pressed_column_is_dragging) { return false; } OnDragScroll (OnDragHScrollTimeout, header_interaction_alloc.Width * 0.1, header_interaction_alloc.Width, x); GdkWindow.Cursor = drag_cursor; Column swap_column = GetColumnAt (x); if (swap_column != null) { CachedColumn swap_column_c = GetCachedColumnForColumn (swap_column); bool reorder = false; if (swap_column_c.Index < pressed_column_index) { // Moving from right to left reorder = pressed_column_x_drag <= swap_column_c.X1 + swap_column_c.Width / 2; } else if (swap_column_c.Index > pressed_column_index) { if (column_cache.Length > pressed_column_index && pressed_column_index >= 0) { // Moving from left to right reorder = pressed_column_x_drag + column_cache[pressed_column_index].Width >= swap_column_c.X1 + swap_column_c.Width / 2; } } if (reorder) { int actual_pressed_index = ColumnController.IndexOf (column_cache[pressed_column_index].Column); int actual_swap_index = ColumnController.IndexOf (swap_column_c.Column); ColumnController.Reorder (actual_pressed_index, actual_swap_index); pressed_column_index = swap_column_c.Index; RegenerateColumnCache (); } } pressed_column_x_drag = x - pressed_column_x_offset - (pressed_column_x_start_hadjustment - HadjustmentValue); QueueDraw (); return true; } private bool OnDragHScrollTimeout () { ScrollToY (hadjustment, HadjustmentValue + (drag_scroll_velocity * drag_scroll_velocity_max)); OnMotionNotifyEvent (pressed_column_x); return true; } protected override bool OnLeaveNotifyEvent (Gdk.EventCrossing evnt) { if (evnt.Mode == Gdk.CrossingMode.Normal) { GdkWindow.Cursor = null; if (LayoutChildHandlesEvent (evnt, false)) { return true; } ProxyEventToCell (evnt, false); } return base.OnLeaveNotifyEvent (evnt); } protected override bool OnFocused (Gtk.DirectionType directionType) { if (!HeaderVisible) return base.OnFocused (directionType); if (HasFocus) { if (directionType == DirectionType.TabForward && HeaderFocused) HeaderFocused = false; else if (directionType == DirectionType.TabBackward && !HeaderFocused) HeaderFocused = true; else return base.OnFocused (directionType); return true; } else { if (directionType == DirectionType.TabForward ) HeaderFocused = true; else if (directionType == DirectionType.TabBackward) HeaderFocused = false; return base.OnFocused (directionType); } } protected virtual void OnRowActivated () { if (Selection.FocusedIndex != -1) { RowActivatedHandler handler = RowActivated; if (handler != null) { handler (this, new RowActivatedArgs (Selection.FocusedIndex, model[Selection.FocusedIndex])); } } } private bool CancelColumnDrag () { if (pressed_column_index >= 0 && pressed_column_is_dragging) { pressed_column_is_dragging = false; pressed_column_index = -1; GdkWindow.Cursor = null; QueueDirtyRegion (); return true; } return false; } // FIXME: replace all invocations with direct call to ViewLayout protected int GetModelRowAt (int x, int y) { if (ViewLayout != null) { var child = ViewLayout.FindChildAtPoint (new Point (x, y)); return child == null ? -1 : child.ModelRowIndex; } else { if (y < 0 || ChildSize.Height <= 0) { return -1; } int v_page_offset = VadjustmentValue % ChildSize.Height; int first_row = VadjustmentValue / ChildSize.Height; int row_offset = (y + v_page_offset) / ChildSize.Height; return first_row + row_offset; } } protected Gdk.Point GetViewPointForModelRow (int row) { // FIXME: hard-coded grid logic if (ViewLayout != null) { int cols = ((DataViewLayoutGrid)ViewLayout).Columns; if (cols == 0 || row == 0) { return new Gdk.Point (0, 0); } else { return new Gdk.Point ((row % cols) * ChildSize.Width, (int)(Math.Floor ((double)row / (double)cols) * ChildSize.Height)); } } else { return new Gdk.Point (0, ChildSize.Height * row); } } private void FocusModelRow (int index) { Selection.FocusedIndex = index; } #endregion #region Adjustments & Scrolling private void UpdateAdjustments () { UpdateAdjustments (null, null); } private void UpdateAdjustments (Adjustment hadj, Adjustment vadj) { if (hadj != null) { hadjustment = hadj; } if (vadj != null) { vadjustment = vadj; } // FIXME: with ViewLayout, hadj and vadj should be unified // since the layout will take the header into account... if (hadjustment != null) { hadjustment.Upper = header_width; hadjustment.StepIncrement = 10.0; if (hadjustment.Value + hadjustment.PageSize > hadjustment.Upper) { hadjustment.Value = hadjustment.Upper - hadjustment.PageSize; } } if (vadjustment != null && model != null) { // FIXME: hard-coded grid logic if (ViewLayout != null) { vadjustment.Upper = ViewLayout.VirtualSize.Height; vadjustment.StepIncrement = ViewLayout.ChildSize.Height; } else { vadjustment.Upper = ChildSize.Height * model.Count; vadjustment.StepIncrement = ChildSize.Height; } if (vadjustment.Value + vadjustment.PageSize > vadjustment.Upper) { vadjustment.Value = vadjustment.Upper - vadjustment.PageSize; } } else if (vadjustment != null) { // model is null vadjustment.Upper = 0; vadjustment.Lower = 0; } if (hadjustment != null) { hadjustment.Change (); } if (vadjustment != null) { vadjustment.Change (); } } private void OnHadjustmentChanged (object o, EventArgs args) { InvalidateLastIcell (); InvalidateHeader (); InvalidateList (); if (ViewLayout != null) { ViewLayout.UpdatePosition (HadjustmentValue, VadjustmentValue); } } private void OnVadjustmentChanged (object o, EventArgs args) { InvalidateLastIcell (); InvalidateList (); if (ViewLayout != null) { ViewLayout.UpdatePosition (HadjustmentValue, VadjustmentValue); } } public void ScrollToY (double val) { ScrollToY (vadjustment, val); } private void ScrollToY (Adjustment adjustment, double val) { if (adjustment != null) { adjustment.Value = Math.Max (0.0, Math.Min (val, adjustment.Upper - adjustment.PageSize)); } } public void ScrollTo (int index) { ScrollToY (GetViewPointForModelRow (index).Y); } public void CenterOn (int index) { ScrollTo (index - ItemsInView / 2 + 1); } public bool IsRowVisible (int index) { double y = GetViewPointForModelRow (index).Y; return vadjustment.Value <= y && y < vadjustment.Value + vadjustment.PageSize; } protected void CenterOnSelection () { if (Selection != null && Selection.Count > 0 && !Selection.AllSelected) { bool selection_in_view = false; int first_row = GetModelRowAt (0, 0); for (int i = 0; i < ItemsInView; i++) { if (Selection.Contains (first_row + i)) { selection_in_view = true; break; } } if (!selection_in_view) { CenterOn (Selection.Ranges[0].Start); } } } protected override void OnSetScrollAdjustments (Adjustment hadj, Adjustment vadj) { if (hadj == null || vadj == null) { return; } hadj.ValueChanged += OnHadjustmentChanged; vadj.ValueChanged += OnVadjustmentChanged; UpdateAdjustments (hadj, vadj); } #endregion } } hyena-0.5/Hyena.Gui/Hyena.Data.Gui/ListView/ListView_DragAndDrop.cs0000644000175000001440000001526411377105500025104 0ustar00gabeusers00000000000000// // ListView_DragAndDrop.cs // // Author: // Aaron Bockover // // Copyright (C) 2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using Gtk; namespace Hyena.Data.Gui { public static class ListViewDragDropTarget { public enum TargetType { ModelSelection } public static readonly TargetEntry ModelSelection = new TargetEntry ("application/x-hyena-data-model-selection", TargetFlags.App, (uint)TargetType.ModelSelection); } public partial class ListView : ListViewBase { private static TargetEntry [] drag_drop_dest_entries = new TargetEntry [] { ListViewDragDropTarget.ModelSelection }; protected virtual TargetEntry [] DragDropDestEntries { get { return drag_drop_dest_entries; } } protected virtual TargetEntry [] DragDropSourceEntries { get { return drag_drop_dest_entries; } } private bool is_reorderable = false; public bool IsReorderable { get { return is_reorderable && IsEverReorderable; } set { is_reorderable = value; OnDragSourceSet (); OnDragDestSet (); } } private bool is_ever_reorderable = false; public bool IsEverReorderable { get { return is_ever_reorderable; } set { is_ever_reorderable = value; OnDragSourceSet (); OnDragDestSet (); } } private bool force_drag_source_set = false; protected bool ForceDragSourceSet { get { return force_drag_source_set; } set { force_drag_source_set = true; OnDragSourceSet (); } } private bool force_drag_dest_set = false; protected bool ForceDragDestSet { get { return force_drag_dest_set; } set { force_drag_dest_set = true; OnDragDestSet (); } } protected virtual void OnDragDestSet () { if (ForceDragDestSet || IsReorderable) { Gtk.Drag.DestSet (this, DestDefaults.All, DragDropDestEntries, Gdk.DragAction.Move); } else { Gtk.Drag.DestUnset (this); } } protected virtual void OnDragSourceSet () { if (ForceDragSourceSet || IsReorderable) { Gtk.Drag.SourceSet (this, Gdk.ModifierType.Button1Mask | Gdk.ModifierType.Button3Mask, DragDropSourceEntries, Gdk.DragAction.Copy | Gdk.DragAction.Move); } else { Gtk.Drag.SourceUnset (this); } } private uint drag_scroll_timeout_id; private uint drag_scroll_timeout_duration = 50; private double drag_scroll_velocity; private double drag_scroll_velocity_max = 100.0; private int drag_reorder_row_index = -1; private int drag_reorder_motion_y = -1; private void StopDragScroll () { drag_scroll_velocity = 0.0; if (drag_scroll_timeout_id > 0) { GLib.Source.Remove (drag_scroll_timeout_id); drag_scroll_timeout_id = 0; } } private void OnDragScroll (GLib.TimeoutHandler handler, double threshold, int total, int position) { if (position < threshold) { drag_scroll_velocity = -1.0 + (position / threshold); } else if (position > total - threshold) { drag_scroll_velocity = 1.0 - ((total - position) / threshold); } else { StopDragScroll (); return; } if (drag_scroll_timeout_id == 0) { drag_scroll_timeout_id = GLib.Timeout.Add (drag_scroll_timeout_duration, handler); } } protected override bool OnDragMotion (Gdk.DragContext context, int x, int y, uint time) { if (!IsReorderable) { StopDragScroll (); drag_reorder_row_index = -1; drag_reorder_motion_y = -1; InvalidateList (); return false; } drag_reorder_motion_y = y; DragReorderUpdateRow (); OnDragScroll (OnDragVScrollTimeout, Allocation.Height * 0.3, Allocation.Height, y); return true; } protected override void OnDragLeave (Gdk.DragContext context, uint time) { StopDragScroll (); } protected override void OnDragEnd (Gdk.DragContext context) { StopDragScroll (); drag_reorder_row_index = -1; drag_reorder_motion_y = -1; InvalidateList (); } private bool OnDragVScrollTimeout () { ScrollToY (VadjustmentValue + (drag_scroll_velocity * drag_scroll_velocity_max)); DragReorderUpdateRow (); return true; } private void DragReorderUpdateRow () { int row = GetDragRow (drag_reorder_motion_y); if (row != drag_reorder_row_index) { drag_reorder_row_index = row; InvalidateList (); } } protected int GetDragRow (int y) { y = TranslateToListY (y); int row = GetModelRowAt (0, y); if (row == -1) { return -1; } if (row != GetModelRowAt (0, y + ChildSize.Height / 2)) { row++; } return row; } } } hyena-0.5/Hyena.Gui/Hyena.Data.Gui/ListView/ListView_Rendering.cs0000644000175000001440000005430311377105500024671 0ustar00gabeusers00000000000000// // ListView_Rendering.cs // // Author: // Aaron Bockover // // Copyright (C) 2007-2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Collections.Generic; using Gtk; using Gdk; using Hyena.Gui; using Hyena.Gui.Theming; using Hyena.Gui.Canvas; using GtkColorClass=Hyena.Gui.Theming.GtkColorClass; namespace Hyena.Data.Gui { public delegate int ListViewRowHeightHandler (Widget widget); public partial class ListView : ListViewBase { private Cairo.Context cairo_context; private CellContext cell_context; private Pango.Layout pango_layout; private List selected_rows = new List (); private Theme theme; protected Theme Theme { get { return theme; } } // Using an auto-property here makes the build fail with mono 1.9.1 (bnc#396633) private bool do_not_render_null_model; public bool DoNotRenderNullModel { get { return do_not_render_null_model; } set { do_not_render_null_model = value; } } private bool changing_style = false; protected override void OnStyleSet (Style old_style) { if (changing_style) { return; } changing_style = true; GtkUtilities.AdaptGtkRcStyle (this, typeof (TreeView)); changing_style = false; base.OnStyleSet (old_style); // FIXME: legacy list foo if (ViewLayout == null) { OnInvalidateMeasure (); } theme = Hyena.Gui.Theming.ThemeEngine.CreateTheme (this); // Save the drawable so we can reuse it Gdk.Drawable drawable = cell_context != null ? cell_context.Drawable : null; if (pango_layout != null) { pango_layout.FontDescription.Dispose (); pango_layout.Dispose (); pango_layout = null; } cell_context = new CellContext (); cell_context.Theme = theme; cell_context.Widget = this; cell_context.Drawable = drawable; } protected override bool OnExposeEvent (EventExpose evnt) { if (DoNotRenderNullModel && Model == null) { return true; } var damage = new Rectangle (); foreach (Rectangle rect in evnt.Region.GetRectangles ()) { damage = damage.Union (rect); } cairo_context = CairoHelper.Create (evnt.Window); if (pango_layout == null) { pango_layout = CairoExtensions.CreateLayout (this, cairo_context); } cell_context.Context = cairo_context; cell_context.Layout = pango_layout; // FIXME: legacy list foo if (ViewLayout == null) { OnMeasure (); } Theme.DrawFrameBackground (cairo_context, Allocation, true); // FIXME: ViewLayout will never be null in the future but we'll need // to deterministically render a header somehow... if (header_visible && ViewLayout == null && column_controller != null) { PaintHeader (damage); } if (Model != null) { // FIXME: ViewLayout will never be null in // the future, PaintList will go away if (ViewLayout == null) { PaintList (damage); } else { PaintView ((Rect)damage); } } Theme.DrawFrameBorder (cairo_context, Allocation); PaintDraggingColumn (damage); CairoExtensions.DisposeContext (cairo_context); return true; } #region Header Rendering private void PaintHeader (Rectangle clip) { Rectangle rect = header_rendering_alloc; rect.Height += Theme.BorderWidth; clip.Intersect (rect); cairo_context.Rectangle (clip.X, clip.Y, clip.Width, clip.Height); cairo_context.Clip (); Theme.DrawHeaderBackground (cairo_context, header_rendering_alloc); Rectangle cell_area = new Rectangle (); cell_area.Y = header_rendering_alloc.Y; cell_area.Height = header_rendering_alloc.Height; cell_context.Clip = clip; cell_context.Opaque = true; cell_context.TextAsForeground = true; bool have_drawn_separator = false; for (int ci = 0; ci < column_cache.Length; ci++) { if (pressed_column_is_dragging && pressed_column_index == ci) { continue; } cell_area.X = column_cache[ci].X1 + Theme.TotalBorderWidth + header_rendering_alloc.X - HadjustmentValue; cell_area.Width = column_cache[ci].Width; PaintHeaderCell (cell_area, ci, false, ref have_drawn_separator); } if (pressed_column_is_dragging && pressed_column_index >= 0) { cell_area.X = pressed_column_x_drag + Allocation.X - HadjustmentValue; cell_area.Width = column_cache[pressed_column_index].Width; PaintHeaderCell (cell_area, pressed_column_index, true, ref have_drawn_separator); } cairo_context.ResetClip (); } private void PaintHeaderCell (Rectangle area, int ci, bool dragging, ref bool have_drawn_separator) { if (ci < 0 || column_cache.Length <= ci) return; if (ci == ActiveColumn && HasFocus && HeaderFocused) { Theme.DrawColumnHeaderFocus (cairo_context, area); } if (dragging) { Theme.DrawColumnHighlight (cairo_context, area, CairoExtensions.ColorShade (Theme.Colors.GetWidgetColor (GtkColorClass.Dark, StateType.Normal), 0.9)); Cairo.Color stroke_color = CairoExtensions.ColorShade (Theme.Colors.GetWidgetColor ( GtkColorClass.Base, StateType.Normal), 0.0); stroke_color.A = 0.3; cairo_context.Color = stroke_color; cairo_context.MoveTo (area.X + 0.5, area.Y + 1.0); cairo_context.LineTo (area.X + 0.5, area.Bottom); cairo_context.MoveTo (area.Right - 0.5, area.Y + 1.0); cairo_context.LineTo (area.Right - 0.5, area.Bottom); cairo_context.Stroke (); } ColumnCell cell = column_cache[ci].Column.HeaderCell; if (cell != null) { cairo_context.Save (); cairo_context.Translate (area.X, area.Y); cell_context.Area = area; cell.Render (cell_context, StateType.Normal, area.Width, area.Height); cairo_context.Restore (); } if (!dragging && ci < column_cache.Length - 1 && (have_drawn_separator || column_cache[ci].MaxWidth != column_cache[ci].MinWidth)) { have_drawn_separator = true; Theme.DrawHeaderSeparator (cairo_context, area, area.Right); } } #endregion #region List Rendering private void PaintList (Rectangle clip) { if (ChildSize.Height <= 0) { return; } // TODO factor this out? // Render the sort effect to the GdkWindow. if (sort_column_index != -1 && (!pressed_column_is_dragging || pressed_column_index != sort_column_index)) { CachedColumn col = column_cache[sort_column_index]; Theme.DrawRowRule (cairo_context, list_rendering_alloc.X + col.X1 - HadjustmentValue, header_rendering_alloc.Bottom + Theme.BorderWidth, col.Width, list_rendering_alloc.Height + Theme.InnerBorderWidth * 2); } clip.Intersect (list_rendering_alloc); cairo_context.Rectangle (clip.X, clip.Y, clip.Width, clip.Height); cairo_context.Clip (); cell_context.Clip = clip; cell_context.TextAsForeground = false; int vadjustment_value = VadjustmentValue; int first_row = vadjustment_value / ChildSize.Height; int last_row = Math.Min (model.Count, first_row + RowsInView); int offset = list_rendering_alloc.Y - vadjustment_value % ChildSize.Height; Rectangle selected_focus_alloc = Rectangle.Zero; Rectangle single_list_alloc = new Rectangle (); single_list_alloc.X = list_rendering_alloc.X - HadjustmentValue; single_list_alloc.Y = offset; single_list_alloc.Width = list_rendering_alloc.Width + HadjustmentValue; single_list_alloc.Height = ChildSize.Height; int selection_height = 0; int selection_y = 0; selected_rows.Clear (); for (int ri = first_row; ri < last_row; ri++) { if (Selection != null && Selection.Contains (ri)) { if (selection_height == 0) { selection_y = single_list_alloc.Y; } selection_height += single_list_alloc.Height; selected_rows.Add (ri); if (Selection.FocusedIndex == ri) { selected_focus_alloc = single_list_alloc; } } else { if (rules_hint && ri % 2 != 0) { Theme.DrawRowRule (cairo_context, single_list_alloc.X, single_list_alloc.Y, single_list_alloc.Width, single_list_alloc.Height); } PaintReorderLine (ri, single_list_alloc); if (Selection != null && Selection.FocusedIndex == ri && !Selection.Contains (ri) && HasFocus) { CairoCorners corners = CairoCorners.All; if (Selection.Contains (ri - 1)) { corners &= ~(CairoCorners.TopLeft | CairoCorners.TopRight); } if (Selection.Contains (ri + 1)) { corners &= ~(CairoCorners.BottomLeft | CairoCorners.BottomRight); } if (HasFocus && !HeaderFocused) // Cursor out of selection. Theme.DrawRowCursor (cairo_context, single_list_alloc.X, single_list_alloc.Y, single_list_alloc.Width, single_list_alloc.Height, CairoExtensions.ColorShade (Theme.Colors.GetWidgetColor (GtkColorClass.Background, StateType.Selected), 0.85)); } if (selection_height > 0) { Cairo.Color selection_color = Theme.Colors.GetWidgetColor (GtkColorClass.Background, StateType.Selected); if (!HasFocus || HeaderFocused) selection_color = CairoExtensions.ColorShade (selection_color, 1.1); Theme.DrawRowSelection (cairo_context, list_rendering_alloc.X, selection_y, list_rendering_alloc.Width, selection_height, true, true, selection_color, CairoCorners.All); selection_height = 0; } PaintRow (ri, single_list_alloc, StateType.Normal); } single_list_alloc.Y += single_list_alloc.Height; } // In case the user is dragging to the end of the list PaintReorderLine (last_row, single_list_alloc); if (selection_height > 0) { Theme.DrawRowSelection (cairo_context, list_rendering_alloc.X, selection_y, list_rendering_alloc.Width, selection_height); } if (Selection != null && Selection.Count > 1 && !selected_focus_alloc.Equals (Rectangle.Zero) && HasFocus && !HeaderFocused) { // Cursor inside selection. Theme.DrawRowCursor (cairo_context, selected_focus_alloc.X, selected_focus_alloc.Y, selected_focus_alloc.Width, selected_focus_alloc.Height, Theme.Colors.GetWidgetColor (GtkColorClass.Text, StateType.Selected)); } foreach (int ri in selected_rows) { single_list_alloc.Y = offset + ((ri - first_row) * single_list_alloc.Height); PaintRow (ri, single_list_alloc, StateType.Selected); } cairo_context.ResetClip (); } private void PaintReorderLine (int row_index, Rectangle single_list_alloc) { if (row_index == drag_reorder_row_index && IsReorderable) { cairo_context.Save (); cairo_context.LineWidth = 1.0; cairo_context.Antialias = Cairo.Antialias.None; cairo_context.MoveTo (single_list_alloc.Left, single_list_alloc.Top); cairo_context.LineTo (single_list_alloc.Right, single_list_alloc.Top); cairo_context.Color = Theme.Colors.GetWidgetColor (GtkColorClass.Text, StateType.Normal); cairo_context.Stroke (); cairo_context.Restore (); } } private void PaintRow (int row_index, Rectangle area, StateType state) { if (column_cache == null) { return; } object item = model[row_index]; bool opaque = IsRowOpaque (item); bool bold = IsRowBold (item); Rectangle cell_area = new Rectangle (); cell_area.Height = ChildSize.Height; cell_area.Y = area.Y; cell_context.ViewRowIndex = cell_context.ModelRowIndex = row_index; for (int ci = 0; ci < column_cache.Length; ci++) { cell_context.ViewColumnIndex = ci; if (pressed_column_is_dragging && pressed_column_index == ci) { continue; } cell_area.Width = column_cache[ci].Width; cell_area.X = column_cache[ci].X1 + area.X; PaintCell (item, ci, row_index, cell_area, opaque, bold, state, false); } if (pressed_column_is_dragging && pressed_column_index >= 0) { cell_area.Width = column_cache[pressed_column_index].Width; cell_area.X = pressed_column_x_drag + list_rendering_alloc.X - list_interaction_alloc.X - HadjustmentValue; PaintCell (item, pressed_column_index, row_index, cell_area, opaque, bold, state, true); } } private void PaintCell (object item, int column_index, int row_index, Rectangle area, bool opaque, bool bold, StateType state, bool dragging) { ColumnCell cell = column_cache[column_index].Column.GetCell (0); cell.BindListItem (item); ColumnCellDataProvider (cell, item); ITextCell text_cell = cell as ITextCell; if (text_cell != null) { text_cell.FontWeight = bold ? Pango.Weight.Bold : Pango.Weight.Normal; } if (dragging) { Cairo.Color fill_color = Theme.Colors.GetWidgetColor (GtkColorClass.Base, StateType.Normal); fill_color.A = 0.5; cairo_context.Color = fill_color; cairo_context.Rectangle (area.X, area.Y, area.Width, area.Height); cairo_context.Fill (); } cairo_context.Save (); cairo_context.Translate (area.X, area.Y); cell_context.Area = area; cell_context.Opaque = opaque; cell.Render (cell_context, dragging ? StateType.Normal : state, area.Width, area.Height); cairo_context.Restore (); AccessibleCellRedrawn (column_index, row_index); } private void PaintDraggingColumn (Rectangle clip) { if (!pressed_column_is_dragging || pressed_column_index < 0) { return; } CachedColumn column = column_cache[pressed_column_index]; int x = pressed_column_x_drag + Allocation.X + 1 - HadjustmentValue; Cairo.Color fill_color = Theme.Colors.GetWidgetColor (GtkColorClass.Base, StateType.Normal); fill_color.A = 0.45; Cairo.Color stroke_color = CairoExtensions.ColorShade (Theme.Colors.GetWidgetColor ( GtkColorClass.Base, StateType.Normal), 0.0); stroke_color.A = 0.3; cairo_context.Rectangle (x, header_rendering_alloc.Bottom + 1, column.Width - 2, list_rendering_alloc.Bottom - header_rendering_alloc.Bottom - 1); cairo_context.Color = fill_color; cairo_context.Fill (); cairo_context.MoveTo (x - 0.5, header_rendering_alloc.Bottom + 0.5); cairo_context.LineTo (x - 0.5, list_rendering_alloc.Bottom + 0.5); cairo_context.LineTo (x + column.Width - 1.5, list_rendering_alloc.Bottom + 0.5); cairo_context.LineTo (x + column.Width - 1.5, header_rendering_alloc.Bottom + 0.5); cairo_context.Color = stroke_color; cairo_context.LineWidth = 1.0; cairo_context.Stroke (); } #endregion #region View Layout Rendering private void PaintView (Rect clip) { clip.Intersect ((Rect)list_rendering_alloc); cairo_context.Rectangle ((Cairo.Rectangle)clip); cairo_context.Clip (); cell_context.Clip = (Gdk.Rectangle)clip; cell_context.TextAsForeground = false; selected_rows.Clear (); for (int layout_index = 0; layout_index < ViewLayout.ChildCount; layout_index++) { var layout_child = ViewLayout[layout_index]; var child_allocation = layout_child.Allocation; if (!child_allocation.IntersectsWith (clip) || layout_child.ModelRowIndex >= Model.Count) { continue; } if (Selection != null && Selection.Contains (layout_child.ModelRowIndex)) { selected_rows.Add (layout_child.ModelRowIndex); var selection_color = Theme.Colors.GetWidgetColor (GtkColorClass.Background, StateType.Selected); if (!HasFocus || HeaderFocused) { selection_color = CairoExtensions.ColorShade (selection_color, 1.1); } Theme.DrawRowSelection (cairo_context, (int)child_allocation.X, (int)child_allocation.Y, (int)child_allocation.Width, (int)child_allocation.Height, true, true, selection_color, CairoCorners.All); cell_context.State = StateType.Selected; } else { cell_context.State = StateType.Normal; } cairo_context.Save (); cairo_context.Translate (child_allocation.X, child_allocation.Y); layout_child.Render (cell_context); cairo_context.Restore (); } cairo_context.ResetClip (); } #endregion protected void InvalidateList () { if (IsRealized) { QueueDirtyRegion (list_rendering_alloc); } } private void InvalidateHeader () { if (IsRealized) { QueueDirtyRegion (header_rendering_alloc); } } protected void QueueDirtyRegion () { QueueDirtyRegion (list_rendering_alloc); } protected virtual void ColumnCellDataProvider (ColumnCell cell, object boundItem) { } private bool rules_hint = false; public bool RulesHint { get { return rules_hint; } set { rules_hint = value; InvalidateList (); } } // FIXME: Obsolete all this measure stuff on the view since it's in the layout #region Measuring private Gdk.Size child_size = Gdk.Size.Empty; public Gdk.Size ChildSize { get { return ViewLayout != null ? new Gdk.Size ((int)ViewLayout.ChildSize.Width, (int)ViewLayout.ChildSize.Height) : child_size; } } private bool measure_pending; protected virtual void OnInvalidateMeasure () { measure_pending = true; if (IsMapped && IsRealized) { QueueDirtyRegion (); } } protected virtual Gdk.Size OnMeasureChild () { return ViewLayout != null ? new Gdk.Size ((int)ViewLayout.ChildSize.Width, (int)ViewLayout.ChildSize.Height) : new Gdk.Size (0, ColumnCellText.ComputeRowHeight (this)); } private void OnMeasure () { if (!measure_pending) { return; } measure_pending = false; header_height = 0; child_size = OnMeasureChild (); UpdateAdjustments (); } #endregion } } hyena-0.5/Hyena.Gui/Hyena.Data.Gui/ListView/ListView.cs0000644000175000001440000000710011377105500022665 0ustar00gabeusers00000000000000// // ListView.cs // // Author: // Aaron Bockover // // Copyright (C) 2007-2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; namespace Hyena.Data.Gui { public partial class ListView : ListViewBase, IListView { protected ListView (IntPtr ptr) : base (ptr) { } public ListView () { column_layout = new Pango.Layout (PangoContext); CanFocus = true; selection_proxy.Changed += delegate { InvalidateList (); }; HasTooltip = true; QueryTooltip += OnQueryTooltip; } private void OnQueryTooltip (object o, Gtk.QueryTooltipArgs args) { if (cell_context != null && cell_context.Layout != null && !args.KeyboardTooltip) { ITooltipCell cell; Column column; int row_index; if (GetEventCell (args.X, args.Y, out cell, out column, out row_index)) { CachedColumn cached_column = GetCachedColumnForColumn (column); string markup = cell.GetTooltipMarkup (cell_context, cached_column.Width); if (!String.IsNullOrEmpty (markup)) { Gdk.Rectangle rect = new Gdk.Rectangle (); rect.X = list_interaction_alloc.X + cached_column.X1; // get the y of the event in list coords rect.Y = args.Y - list_interaction_alloc.Y; // get the top of the cell pointed to by list_y rect.Y -= VadjustmentValue % ChildSize.Height; rect.Y -= rect.Y % ChildSize.Height; // convert back to widget coords rect.Y += list_interaction_alloc.Y; // TODO is this right even if the list is wide enough to scroll horizontally? rect.Width = cached_column.Width; // TODO not right - could be smaller if at the top/bottom and only partially showing rect.Height = ChildSize.Height; args.Tooltip.Markup = markup; args.Tooltip.TipArea = rect; args.RetVal = true; } } } // Work around ref counting SIGSEGV, see http://bugzilla.gnome.org/show_bug.cgi?id=478519#c9 if (args.Tooltip != null) { args.Tooltip.Dispose (); } } } } hyena-0.5/Hyena.Gui/Hyena.Data.Gui/ITooltipCell.cs0000644000175000001440000000253511377105500021723 0ustar00gabeusers00000000000000// // ITooltipCell.cs // // Author: // Gabriel Burt // // Copyright (C) 2009 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using Gdk; namespace Hyena.Data.Gui { public interface ITooltipCell { string GetTooltipMarkup (CellContext cellContext, double columnWidth); } } hyena-0.5/Hyena.Gui/Hyena.Data.Gui/Accessibility/0000777000175000001440000000000011453151003021611 5ustar00gabeusers00000000000000hyena-0.5/Hyena.Gui/Hyena.Data.Gui/Accessibility/ListViewAccessible.cs0000644000175000001440000002112711436010340025662 0ustar00gabeusers00000000000000// // ListViewAccessible.cs // // Authors: // Eitan Isaacson // Gabriel Burt // // Copyright (C) 2009 Novell, Inc. // Copyright (C) 2009 Eitan Isaacson // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Linq; using System.Collections.Generic; using Hyena.Data.Gui; namespace Hyena.Data.Gui.Accessibility { #if ENABLE_ATK public partial class ListViewAccessible : Hyena.Gui.BaseWidgetAccessible, ICellAccessibleParent { private ListView list_view; private Dictionary cell_cache; public ListViewAccessible (GLib.Object widget) : base (widget as Gtk.Widget) { list_view = widget as ListView; // TODO replace with list_view.Name? Name = "ListView"; Description = "ListView"; Role = Atk.Role.Table; Parent = list_view.Parent.RefAccessible (); cell_cache = new Dictionary (); list_view.ModelChanged += OnModelChanged; list_view.ModelReloaded += OnModelChanged; OnModelChanged (null, null); list_view.SelectionProxy.FocusChanged += OnSelectionFocusChanged; list_view.ActiveColumnChanged += OnSelectionFocusChanged; ListViewAccessible_Selection (); ListViewAccessible_Table (); } protected override Atk.StateSet OnRefStateSet () { Atk.StateSet states = base.OnRefStateSet (); states.AddState (Atk.StateType.ManagesDescendants); return states; } protected override int OnGetIndexInParent () { for (int i=0; i < Parent.NAccessibleChildren; i++) { if (Parent.RefAccessibleChild (i) == this) { return i; } } return -1; } protected override int OnGetNChildren () { return n_columns * n_rows + n_columns; } protected override Atk.Object OnRefChild (int index) { ColumnCellAccessible child; if (cell_cache.ContainsKey (index)) { return cell_cache[index]; } // FIXME workaround to prevent crashing on Grid ListViews if (list_view.ColumnController == null) return null; var columns = list_view.ColumnController.Where (c => c.Visible); if (index - n_columns < 0) { child = columns.ElementAtOrDefault (index) .HeaderCell .GetAccessible (this) as ColumnCellAccessible; } else { int column = (index - n_columns) % n_columns; int row = (index - n_columns) / n_columns; var cell = columns.ElementAtOrDefault (column).GetCell (0); cell.BindListItem (list_view.Model[row]); child = (ColumnCellAccessible) cell.GetAccessible (this); } cell_cache.Add (index, child); return child; } public override Atk.Object RefAccessibleAtPoint (int x, int y, Atk.CoordType coordType) { int row, col; list_view.GetCellAtPoint (x, y, coordType, out row, out col); return RefAt (row, col); } private void OnModelChanged (object o, EventArgs a) { ThreadAssist.ProxyToMain (EmitModelChanged); } private void EmitModelChanged () { GLib.Signal.Emit (this, "model_changed"); cell_cache.Clear (); /*var handler = ModelChanged; if (handler != null) { handler (this, EventArgs.Empty); }*/ } private void OnSelectionFocusChanged (object o, EventArgs a) { ThreadAssist.ProxyToMain (EmitDescendantChanged); } private void EmitDescendantChanged () { var cell = ActiveCell; if (cell != null) { GLib.Signal.Emit (this, "active-descendant-changed", cell.Handle); } } private Atk.Object ActiveCell { get { if (list_view.HeaderFocused) { return OnRefChild (list_view.ActiveColumn); } else { if (list_view.Selection != null) { return RefAt (list_view.Selection.FocusedIndex, list_view.ActiveColumn); } else { return null; } } } } private int n_columns { get { return list_view.ColumnController != null ? list_view.ColumnController.Count (c => c.Visible) : 1; } } private int n_rows { get { return list_view.Model.Count; } } #region ICellAccessibleParent public int GetCellIndex (ColumnCellAccessible cell) { foreach (KeyValuePair kv in cell_cache) { if ((ColumnCellAccessible)kv.Value == cell) return (int)kv.Key; } return -1; } public Gdk.Rectangle GetCellExtents (ColumnCellAccessible cell, Atk.CoordType coord_type) { int cache_index = GetCellIndex (cell); int minval = Int32.MinValue; if (cache_index == -1) return new Gdk.Rectangle (minval, minval, minval, minval); if (cache_index - n_columns >= 0) { int column = (cache_index - NColumns)%NColumns; int row = (cache_index - NColumns)/NColumns; return list_view.GetColumnCellExtents (row, column, true, coord_type); } else { return list_view.GetColumnHeaderCellExtents (cache_index, true, coord_type); } } public bool IsCellShowing (ColumnCellAccessible cell) { Gdk.Rectangle cell_extents = GetCellExtents (cell, Atk.CoordType.Window); if (cell_extents.X == Int32.MinValue && cell_extents.Y == Int32.MinValue) return false; return true; } public bool IsCellFocused (ColumnCellAccessible cell) { int cell_index = GetCellIndex (cell); if (cell_index % NColumns != 0) return false; // Only 0 column cells get focus now. int row = cell_index / NColumns; return row == list_view.Selection.FocusedIndex; } public bool IsCellSelected (ColumnCellAccessible cell) { return IsChildSelected (GetCellIndex (cell)); } public bool IsCellActive (ColumnCellAccessible cell) { return (ActiveCell == (Atk.Object)cell); } public void InvokeColumnHeaderMenu (ColumnCellAccessible cell) { list_view.InvokeColumnHeaderMenu (GetCellIndex (cell)); } public void ClickColumnHeader (ColumnCellAccessible cell) { list_view.ClickColumnHeader (GetCellIndex (cell)); } public void CellRedrawn (int column, int row) { int index; if (row >= 0) index = row * n_columns + column + n_columns; else index = column; if (cell_cache.ContainsKey (index)) { cell_cache[index].Redrawn (); } } #endregion } #endif } hyena-0.5/Hyena.Gui/Hyena.Data.Gui/Accessibility/ColumnCellTextAccessible.cs0000644000175000001440000000305511377105500027025 0ustar00gabeusers00000000000000// // ColumnCellTextAccessible.cs // // Author: // Eitan Isaacson // // Copyright (C) 2009 Eitan Isaacson. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; namespace Hyena.Data.Gui.Accessibility { class ColumnCellTextAccessible : ColumnCellAccessible { public ColumnCellTextAccessible (object bound_object, ColumnCellText cell, ICellAccessibleParent parent): base (bound_object, cell as ColumnCell, parent) { Name = cell.GetTextAlternative (bound_object); } } } hyena-0.5/Hyena.Gui/Hyena.Data.Gui/Accessibility/ListViewAccessible_Selection.cs0000644000175000001440000000546311377105500027703 0ustar00gabeusers00000000000000// // ListViewAccessible_Selection.cs // // Authors: // Eitan Isaacson // Gabriel Burt // // Copyright (C) 2009 Novell, Inc. // Copyright (C) 2009 Eitan Isaacson // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Linq; using System.Collections.Generic; using Hyena.Data.Gui; namespace Hyena.Data.Gui.Accessibility { #if ENABLE_ATK public partial class ListViewAccessible : Atk.SelectionImplementor { public void ListViewAccessible_Selection () { list_view.SelectionProxy.Changed += OnSelectionChanged; } public bool AddSelection (int index) { return AddRowSelection (GetRowAtIndex (index)); } public bool ClearSelection () { list_view.Selection.Clear (); return true; } public bool IsChildSelected (int index) { return IsRowSelected (GetRowAtIndex (index)); } public bool RemoveSelection (int index) { int row = list_view.Selection.RangeCollection [index / n_columns]; return RemoveRowSelection (row); } public Atk.Object RefSelection (int index) { int row = list_view.Selection.RangeCollection [index / n_columns]; int column = index % n_columns; return RefAt (row, column); } public int SelectionCount { get { return list_view.Selection.Count * n_columns; } } public bool SelectAllSelection () { list_view.Selection.SelectAll (); return true; } private void OnSelectionChanged (object o, EventArgs a) { GLib.Signal.Emit (this, "selection_changed"); } } #endif } hyena-0.5/Hyena.Gui/Hyena.Data.Gui/Accessibility/ColumnHeaderCellTextAccessible.cs0000644000175000001440000000720211377105500030134 0ustar00gabeusers00000000000000// // ColumnHeaderCellTextAccessible.cs // // Author: // Eitan Isaacson // // Copyright (C) 2009 Eitan Isaacson. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using Mono.Unix; namespace Hyena.Data.Gui.Accessibility { class ColumnHeaderCellTextAccessible: ColumnCellTextAccessible, Atk.ActionImplementor { private static string [] action_descriptions = new string[] {"", Catalog.GetString ("open context menu")}; private static string [] action_names_localized = new string[] {Catalog.GetString ("click"), Catalog.GetString ("menu")}; private enum Actions { Click, Menu, Last }; public ColumnHeaderCellTextAccessible (object bound_object, ColumnHeaderCellText cell, ICellAccessibleParent parent) : base (bound_object, cell as ColumnCellText, parent) { Role = Atk.Role.TableColumnHeader; } #if ENABLE_ATK protected override Atk.StateSet OnRefStateSet () { Atk.StateSet states = base.OnRefStateSet (); states.RemoveState (Atk.StateType.Selectable); states.RemoveState (Atk.StateType.Transient); return states; } #endif public string GetLocalizedName (int action) { if (action >= action_names_localized.Length) return ""; return action_names_localized[action]; } public string GetName (int action) { if (action >= (int)Actions.Last) return ""; return ((Actions)action).ToString ().ToLower (); } public string GetDescription (int action) { if (action >= action_descriptions.Length) return ""; return action_descriptions[action]; } public string GetKeybinding (int action) { return ""; } public int NActions { get { return (int)Actions.Last; } } public bool DoAction (int action) { ICellAccessibleParent parent = (ICellAccessibleParent)Parent; switch ((Actions)action) { case Actions.Menu: parent.InvokeColumnHeaderMenu (this); break; case Actions.Click: parent.ClickColumnHeader (this); break; } if (action == (int)Actions.Menu) { ((ICellAccessibleParent)Parent).InvokeColumnHeaderMenu (this); } return true; } public bool SetDescription (int action, string description) { return false; } } } hyena-0.5/Hyena.Gui/Hyena.Data.Gui/Accessibility/ICellAccessibleParent.cs0000644000175000001440000000351511377105500026266 0ustar00gabeusers00000000000000// // ICellAccessibleParent.cs // // Author: // Eitan Isaacson // // Copyright (C) 2009 Eitan Isaacson. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; namespace Hyena.Data.Gui.Accessibility { public interface ICellAccessibleParent { Gdk.Rectangle GetCellExtents (ColumnCellAccessible cell, Atk.CoordType coord_type); int GetCellIndex (ColumnCellAccessible cell); bool IsCellShowing (ColumnCellAccessible cell); bool IsCellFocused (ColumnCellAccessible cell); bool IsCellSelected (ColumnCellAccessible cell); bool IsCellActive (ColumnCellAccessible cell); void InvokeColumnHeaderMenu (ColumnCellAccessible column); void ClickColumnHeader (ColumnCellAccessible column); void CellRedrawn (int column, int row); } } hyena-0.5/Hyena.Gui/Hyena.Data.Gui/Accessibility/ColumnCellAccessible.cs0000644000175000001440000001100311377105500026150 0ustar00gabeusers00000000000000// // ColumnCellAccessible.cs // // Author: // Eitan Isaacson // // Copyright (C) 2009 Eitan Isaacson. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; namespace Hyena.Data.Gui.Accessibility { public class ColumnCellAccessible: Atk.Object, Atk.ComponentImplementor { protected ColumnCell cell; protected object bound_object; private ICellAccessibleParent cell_parent; public ColumnCellAccessible (object bound_object, ColumnCell cell, ICellAccessibleParent parent) { Role = Atk.Role.TableCell; this.bound_object = bound_object; this.cell = cell; cell_parent = parent; Parent = (Atk.Object) parent; } #if ENABLE_ATK protected override Atk.StateSet OnRefStateSet () { Atk.StateSet states = base.OnRefStateSet (); states.AddState (Atk.StateType.Transient); states.AddState (Atk.StateType.Focusable); states.AddState (Atk.StateType.Enabled); states.AddState (Atk.StateType.Sensitive); states.AddState (Atk.StateType.Visible); if (cell_parent.IsCellShowing (this)) states.AddState (Atk.StateType.Showing); if (cell_parent.IsCellFocused (this)) states.AddState (Atk.StateType.Focused); if (cell_parent.IsCellSelected (this)) states.AddState (Atk.StateType.Selected); if (cell_parent.IsCellActive (this)) states.AddState (Atk.StateType.Active); return states; } protected override int OnGetIndexInParent () { return cell_parent.GetCellIndex (this); } #endif public double Alpha { get { return 1.0; } } public bool SetSize (int w, int h) { return false; } public bool SetPosition (int x, int y, Atk.CoordType coordType) { return false; } public bool SetExtents (int x, int y, int w, int h, Atk.CoordType coordType) { return false; } public void RemoveFocusHandler (uint handlerId) { } public bool GrabFocus () { return false; } public void GetSize (out int w, out int h) { Gdk.Rectangle rectangle = cell_parent.GetCellExtents(this, Atk.CoordType.Screen); w = rectangle.Width; h = rectangle.Height; } public void GetPosition (out int x, out int y, Atk.CoordType coordType) { Gdk.Rectangle rectangle = cell_parent.GetCellExtents(this, coordType); x = rectangle.X; y = rectangle.Y; } public void GetExtents (out int x, out int y, out int w, out int h, Atk.CoordType coordType) { Gdk.Rectangle rectangle = cell_parent.GetCellExtents(this, coordType); x = rectangle.X; y = rectangle.Y; w = rectangle.Width; h = rectangle.Height; } public virtual Atk.Object RefAccessibleAtPoint (int x, int y, Atk.CoordType coordType) { return null; } public bool Contains (int x, int y, Atk.CoordType coordType) { return false; } public uint AddFocusHandler (Atk.FocusHandler handler) { return 0; } public virtual void Redrawn () { } } } hyena-0.5/Hyena.Gui/Hyena.Data.Gui/Accessibility/ListViewAccessible_Table.cs0000644000175000001440000001215111377105500026775 0ustar00gabeusers00000000000000// // ListViewAccessible_Table.cs // // Authors: // Eitan Isaacson // Gabriel Burt // // Copyright (C) 2009 Novell, Inc. // Copyright (C) 2009 Eitan Isaacson // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Linq; using System.Collections.Generic; using Hyena.Data.Gui; namespace Hyena.Data.Gui.Accessibility { #if ENABLE_ATK public partial class ListViewAccessible : Atk.TableImplementor { public void ListViewAccessible_Table () { } public Atk.Object Caption { get { return new Atk.NoOpObject (list_view); } set {} } public int NColumns { get { return n_columns; } set {} } public int NRows { get { return n_rows; } set {} } public Atk.Object Summary { get { return new Atk.NoOpObject (list_view); } set {} } public bool AddColumnSelection (int column) { return false; } public bool AddRowSelection (int row) { list_view.Selection.Select (row); return true; } public int GetColumnAtIndex (int index) { return NColumns == 0 ? -1 : (index - NColumns) % NColumns; } public string GetColumnDescription (int column) { var col = list_view.ColumnController.Where (c => c.Visible).ElementAtOrDefault (column); return col == null ? null : col.LongTitle; } public int GetColumnExtentAt (int row, int column) { return 1; } public Atk.Object GetColumnHeader (int column) { if (column >= NColumns) return new Atk.NoOpObject (list_view); else return OnRefChild (column); } public int GetIndexAt (int row, int column) { return row * NColumns + column + NColumns; } public int GetRowAtIndex (int index) { if (NColumns == 0) return -1; return (index - NColumns) / NColumns; } public string GetRowDescription (int row) { return ""; } public int GetRowExtentAt (int row, int column) { return 1; } public Atk.Object GetRowHeader (int row) { return new Atk.NoOpObject (list_view); } // Ensure https://bugzilla.novell.com/show_bug.cgi?id=512477 is fixed #if ENABLE_ATK private static readonly int [] empty_int_array = new int[0]; public int [] SelectedColumns { get { return empty_int_array; } } public int [] SelectedRows { get { return list_view.Selection.ToArray (); } } #else public int GetSelectedRows (out int row) { row = 0; return 0; } public int GetSelectedColumns (out int cols) { cols = 0; return 0; } #endif public bool IsColumnSelected (int column) { return false; } public bool IsRowSelected (int row) { return list_view.Selection.Contains (row); } public bool IsSelected (int row, int column) { return list_view.Selection.Contains (row); } public Atk.Object RefAt (int row, int column) { int index = NColumns * row + column + NColumns; return OnRefChild (index); } public bool RemoveColumnSelection (int column) { return false; } public bool RemoveRowSelection (int row) { list_view.Selection.Unselect (row); return true; } public void SetColumnDescription (int column, string description) { } public void SetColumnHeader (int column, Atk.Object header) { } public void SetRowDescription (int row, string description) { } public void SetRowHeader (int row, Atk.Object header) { } } #endif } hyena-0.5/Hyena.Gui/Hyena.Data.Gui/DataViewLayoutGrid.cs0000644000175000001440000001336411377105500023072 0ustar00gabeusers00000000000000// // DataViewLayoutGrid.cs // // Author: // Aaron Bockover // // Copyright 2010 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Collections.Generic; using Hyena.Gui.Canvas; namespace Hyena.Data.Gui { public class DataViewLayoutGrid : DataViewLayout { public int Rows { get; private set; } public int Columns { get; private set; } public Func ChildAllocator { get; set; } public event EventHandler> ChildCountChanged; protected override void InvalidateChildSize () { if (Children.Count <= 0) { Children.Add (CreateChild ()); } ChildSize = Children[0].Measure (Size.Empty); } protected override void InvalidateVirtualSize () { double model_rows = Model == null ? 0 : Model.Count; VirtualSize = new Size ( ChildSize.Width * Math.Max (Columns, 1), ChildSize.Height * Math.Ceiling (model_rows / Math.Max (Columns, 1))); } protected override void InvalidateChildCollection () { Rows = ChildSize.Height > 0 ? (int)Math.Ceiling ((ActualAllocation.Height + ChildSize.Height) / (double)ChildSize.Height) : 0; Columns = ChildSize.Width > 0 ? (int)Math.Max (ActualAllocation.Width / ChildSize.Width, 1) : 0; ResizeChildCollection (Rows * Columns); var handler = ChildCountChanged; if (handler != null) { handler (this, new EventArgs (Rows * Columns)); } } protected override void InvalidateChildLayout () { if (ChildSize.Width <= 0 || ChildSize.Height <= 0) { // FIXME: empty/reset all child slots here? return; } // Compute where we should start and end in the model double offset = ActualAllocation.Y - YPosition % ChildSize.Height; int first_model_row = (int)Math.Floor (YPosition / ChildSize.Height) * Columns; int last_model_row = first_model_row + Rows * Columns; // Setup for the layout iteration int model_row_index = first_model_row; int layout_child_index = 0; int view_row_index = 0; int view_column_index = 0; // Allocation of the first child in the layout, this // will change as we iterate the layout children var child_allocation = new Rect () { X = ActualAllocation.X, Y = offset, Width = ChildSize.Width, Height = ChildSize.Height }; // Iterate the layout children and configure them for the current // view state to be consumed by interaction and rendering phases for (; model_row_index < last_model_row; model_row_index++, layout_child_index++) { var child = Children[layout_child_index]; child.Allocation = child_allocation; child.VirtualAllocation = GetChildVirtualAllocation (child_allocation); child.ModelRowIndex = model_row_index; if (Model != null) { child.BindDataItem (Model.GetItem (model_row_index)); } child.Measure (ChildSize); // FIXME: Should not do this here... child.Arrange (); // Update the allocation for the next child if (++view_column_index % Columns == 0) { view_row_index++; view_column_index = 0; child_allocation.Y += ChildSize.Height; child_allocation.X = ActualAllocation.X; } else { child_allocation.X += ChildSize.Width; } // FIXME: clear any layout children that go beyond the model } } protected virtual DataViewChild CreateChild () { if (ChildAllocator == null) { throw new InvalidOperationException ("ChildAllocator is unset"); } var child = ChildAllocator (); child.ParentLayout = this; return child; } private void ResizeChildCollection (int newChildCount) { int difference = Children.Count - newChildCount; if (difference > 0) { Children.RemoveRange (newChildCount, difference); } else { for (int i=0; i>difference; i--) { Children.Add (CreateChild ()); } } } } } hyena-0.5/Hyena.Gui/Hyena.Data.Gui/IListView.cs0000644000175000001440000000321611377105500021234 0ustar00gabeusers00000000000000// // IListView.cs // // Authors: // Gabriel Burt // // Copyright (C) 2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // namespace Hyena.Data.Gui { public interface IListView { Hyena.Collections.SelectionProxy SelectionProxy { get; } Hyena.Collections.Selection Selection { get; } void ScrollTo (int index); void CenterOn (int index); void GrabFocus (); ColumnController ColumnController { get; set; } } public interface IListView : IListView { void SetModel (IListModel model); IListModel Model { get; } } } hyena-0.5/Hyena.Gui/Hyena.Data.Gui/Column.cs0000644000175000001440000001502011377105500020606 0ustar00gabeusers00000000000000// // Column.cs // // Author: // Aaron Bockover // // Copyright (C) 2007 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Collections; using System.Collections.Generic; using Gtk; using Hyena; using Hyena.Data; namespace Hyena.Data.Gui { public class Column : ColumnDescription, IEnumerable { private ColumnCell header_cell; private List cells = new List (); private int min_width = 0; private int max_width = Int32.MaxValue; public Column (ColumnDescription description) : this (description, new ColumnCellText (description.Property, true)) { } public Column (ColumnDescription description, ColumnCell cell) : this (description.Title, cell, description.Width, description.Visible) { } public Column (string title, ColumnCell cell, double width) : this (title, cell, width, true) { } public Column (string title, ColumnCell cell, double width, bool visible) : this (null, title, cell, width, visible) { } public Column (ColumnCell headerCell, string title, ColumnCell cell, double width) : this (headerCell, title, cell, width, true) { } public Column (ColumnCell headerCell, string title, ColumnCell cell, double width, bool visible) : this (headerCell, title, cell, width, visible, 0, Int32.MaxValue) { } public Column (ColumnCell headerCell, string title, ColumnCell cell, double width, bool visible, int minWidth, int maxWidth) : base (cell.Property, title, width, visible) { min_width = minWidth; max_width = maxWidth; header_cell = headerCell ?? new ColumnHeaderCellText (HeaderCellDataHandler); ColumnCellText header_text = header_cell as ColumnCellText; ColumnCellText cell_text = cell as ColumnCellText; if (header_text != null && cell_text != null) { header_text.Alignment = cell_text.Alignment; } PackStart (cell); } private Column HeaderCellDataHandler () { return this; } public void PackStart (ColumnCell cell) { cells.Insert (0, cell); } public void PackEnd (ColumnCell cell) { cells.Add (cell); } public ColumnCell GetCell (int index) { return cells[index]; } public void RemoveCell (int index) { cells.RemoveAt (index); } public void ClearCells () { cells.Clear (); } IEnumerator IEnumerable.GetEnumerator () { return cells.GetEnumerator (); } IEnumerator IEnumerable.GetEnumerator () { return cells.GetEnumerator (); } public ColumnCell HeaderCell { get { return header_cell; } set { header_cell = value; } } public void CalculateWidths (Pango.Layout layout, bool headerVisible, int headerHeight) { bool min_was_zero = MinWidth == 0; bool was_size_req = false; ISizeRequestCell sr_cell = cells[0] as ISizeRequestCell; if (sr_cell != null && sr_cell.RestrictSize) { int min_w, max_w; sr_cell.GetWidthRange (layout, out min_w, out max_w); MinWidth = min_w == -1 ? MinWidth : min_w; MaxWidth = max_w == -1 ? MaxWidth : max_w; was_size_req = true; } if (headerVisible && (min_was_zero || was_size_req) && !String.IsNullOrEmpty (Title)) { int w, h; layout.SetText (Title); //column_layout.SetText ("\u2026"); // ellipsis char layout.GetPixelSize (out w, out h); // Pretty sure the 3* is needed here only b/c of the " - 8" in ColumnCellText; // See TODO there w += 3 * ColumnHeaderCellText.Spacing; if (this is ISortableColumn) { w += ColumnHeaderCellText.GetArrowWidth (headerHeight); } MinWidth = Math.Max (MinWidth, w); // If the min/max are sufficiently close (arbitrarily choosen as < 8px) then // make them equal, so that the column doesn't appear resizable but in reality is on barely. if (MaxWidth - MinWidth < 8) { MinWidth = MaxWidth; } } } public int MinWidth { get { return min_width; } set { min_width = value; if (value > max_width) { max_width = value; } } } public int MaxWidth { get { return max_width; } set { max_width = value; if (value < min_width) { min_width = value; } } } private string id; public string Id { get { if (id == null) { id = GetCell (0).SubProperty ?? GetCell (0).Property; id = StringUtil.CamelCaseToUnderCase (id); } return id; } set { id = value; } } } } hyena-0.5/Hyena.Gui/Hyena.Data.Gui/ColumnCell.cs0000644000175000001440000001155411377105500021416 0ustar00gabeusers00000000000000// // ColumnCell.cs // // Author: // Aaron Bockover // // Copyright (C) 2007 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Reflection; using Gtk; using Cairo; using Hyena.Data.Gui.Accessibility; namespace Hyena.Data.Gui { public abstract class ColumnCell { private bool expand; private string property, sub_property; private PropertyInfo property_info, sub_property_info; private object bound_object; private object bound_object_parent; public virtual Atk.Object GetAccessible (ICellAccessibleParent parent) { return new ColumnCellAccessible (BoundObject, this, parent); } public virtual string GetTextAlternative (object obj) { return ""; } public ColumnCell (string property, bool expand) { Property = property; Expand = expand; } public void BindListItem (object item) { if (item == null) { bound_object_parent = null; bound_object = null; return; } bound_object_parent = item; if (property != null) { EnsurePropertyInfo (); bound_object = property_info.GetValue (bound_object_parent, null); if (sub_property != null) { EnsurePropertyInfo (sub_property, ref sub_property_info, bound_object); bound_object = sub_property_info.GetValue (bound_object, null); } } else { bound_object = bound_object_parent; } } private void EnsurePropertyInfo () { EnsurePropertyInfo (property, ref property_info, bound_object_parent); } private void EnsurePropertyInfo (string name, ref PropertyInfo prop, object obj) { if (prop == null || prop.ReflectedType != obj.GetType ()) { prop = obj.GetType ().GetProperty (name); if (prop == null) { throw new Exception (String.Format ( "In {0}, type {1} does not have property {2}", this, obj.GetType (), name )); } } } public virtual void NotifyThemeChange () { } protected Type BoundType { get { return bound_object.GetType (); } } protected object BoundObject { get { return bound_object; } set { if (property != null) { EnsurePropertyInfo (); property_info.SetValue (bound_object_parent, value, null); } } } protected object BoundObjectParent { get { return bound_object_parent; } } public abstract void Render (CellContext context, StateType state, double cellWidth, double cellHeight); public virtual Gdk.Size Measure (Gtk.Widget widget) { return Gdk.Size.Empty; } public bool Expand { get { return expand; } set { expand = value; } } public DataViewLayout ViewLayout { get; set; } public string Property { get { return property; } set { property = value; if (value != null) { int i = value.IndexOf ("."); if (i != -1) { property = value.Substring (0, i); SubProperty = value.Substring (i + 1, value.Length - i - 1); } } } } public string SubProperty { get { return sub_property; } set { sub_property = value; } } } } hyena-0.5/Hyena.Gui/Hyena.Data.Gui/ColumnCellRating.cs0000644000175000001440000001200211377105500022550 0ustar00gabeusers00000000000000// // ColumnCellRating.cs // // Author: // Aaron Bockover // // Copyright (C) 2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using Gtk; using Hyena.Gui; using Hyena.Gui.Theming; namespace Hyena.Data.Gui { public class ColumnCellRating : ColumnCell, IInteractiveCell, ISizeRequestCell { private object last_pressed_bound; private object hover_bound; private int hover_value; private Gdk.Rectangle actual_area_hack; private RatingRenderer renderer = new RatingRenderer (); public ColumnCellRating (string property, bool expand) : base (property, expand) { Xpad = 0; } public override void Render (CellContext context, StateType state, double cellWidth, double cellHeight) { Gdk.Rectangle area = new Gdk.Rectangle (0, 0, context.Area.Width, context.Area.Height); // FIXME: Compute font height and set to renderer.Size renderer.Value = Value; bool is_hovering = hover_bound == BoundObjectParent && hover_bound != null; renderer.Render (context.Context, area, context.Theme.Colors.GetWidgetColor (GtkColorClass.Text, state), is_hovering, is_hovering, hover_value, 0.8, 0.45, 0.35); // FIXME: Something is hosed in the view when computing cell dimensions // The cell width request is always smaller than the actual cell, so // this value is preserved once we compute it from rendering so the // input stuff can do its necessary calculations actual_area_hack = area; } public bool ButtonEvent (int x, int y, bool pressed, Gdk.EventButton evnt) { if (ReadOnly) { return false; } if (pressed) { last_pressed_bound = BoundObjectParent; return false; } if (last_pressed_bound == BoundObjectParent) { Value = RatingFromPosition (x); last_pressed_bound = null; } return true; } public bool MotionEvent (int x, int y, Gdk.EventMotion evnt) { if (ReadOnly) { return false; } int value = RatingFromPosition (x); if (hover_bound == BoundObjectParent && value == hover_value) { return false; } hover_bound = BoundObjectParent; hover_value = value; return true; } public bool PointerLeaveEvent () { hover_bound = null; hover_value = MinRating - 1; return true; } public void GetWidthRange (Pango.Layout layout, out int min, out int max) { min = max = renderer.Width; } private int RatingFromPosition (double x) { return renderer.RatingFromPosition (actual_area_hack, x); } private bool restrict_size = true; public bool RestrictSize { get { return restrict_size; } set { restrict_size = value; } } private int Value { get { return BoundObject == null ? MinRating : renderer.ClampValue ((int)BoundObject); } set { BoundObject = renderer.ClampValue (value); } } public int MaxRating { get { return renderer.MaxRating; } set { renderer.MaxRating = value; } } public int MinRating { get { return renderer.MinRating; } set { renderer.MinRating = value; } } public int RatingLevels { get { return renderer.RatingLevels; } } public int Xpad { get { return renderer.Xpad; } set { renderer.Xpad = value; } } public int Ypad { get { return renderer.Ypad; } set { renderer.Ypad = value; } } public bool ReadOnly { get; set; } } } hyena-0.5/Hyena.Gui/Hyena.Data.Gui/RowActivatedHandler.cs0000644000175000001440000000331311377105500023245 0ustar00gabeusers00000000000000// // RowActivatedHandler.cs // // Author: // Aaron Bockover // // Copyright (C) 2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; namespace Hyena.Data.Gui { public delegate void RowActivatedHandler (object o, RowActivatedArgs args); public class RowActivatedArgs : EventArgs { private int row; private T row_value; public RowActivatedArgs (int row, T rowValue) { this.row = row; this.row_value = rowValue; } public int Row { get { return row; } } public T RowValue { get { return row_value; } } } } hyena-0.5/Hyena.Gui/Hyena.Data.Gui/ITextCell.cs0000644000175000001440000000245411377105500021215 0ustar00gabeusers00000000000000// // ITextCell.cs // // Author: // Gabriel Burt // // Copyright (C) 2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; namespace Hyena.Data.Gui { public interface ITextCell { Pango.Weight FontWeight { get; set; } } } hyena-0.5/Hyena.Gui/Hyena.Data.Gui/CellContext.cs0000644000175000001440000000372511377105500021606 0ustar00gabeusers00000000000000// // CellContext.cs // // Author: // Aaron Bockover // // Copyright (C) 2007 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using Hyena.Gui.Theming; namespace Hyena.Data.Gui { public class CellContext { public CellContext () { Opaque = true; } public Cairo.Context Context { get; set; } public Pango.Layout Layout { get; set; } public Gtk.Widget Widget { get; set; } public Gtk.StateType State { get; set; } public Gdk.Drawable Drawable { get; set; } public Theme Theme { get; set; } public Gdk.Rectangle Area { get; set; } public Gdk.Rectangle Clip { get; set; } public bool TextAsForeground { get; set; } public bool Opaque { get; set; } public int ViewRowIndex { get; set; } public int ViewColumnIndex { get; set; } public int ModelRowIndex { get; set; } } } hyena-0.5/Hyena.Gui/Hyena.Data.Gui/DataViewChild.cs0000644000175000001440000001213411377105500022024 0ustar00gabeusers00000000000000// // DataViewChild.cs // // Author: // Aaron Bockover // // Copyright 2010 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Reflection; using Hyena.Gui.Canvas; namespace Hyena.Data.Gui { public abstract class DataViewChild : CanvasItem { public DataViewLayout ParentLayout { get; set; } public int ModelRowIndex { get; set; } protected override void OnInvalidate (Rect area) { ParentLayout.View.QueueDirtyRegion (area); } #region Data Binding private PropertyInfo property_info; private PropertyInfo sub_property_info; public void BindDataItem (object item) { if (item == null) { BoundObjectParent = null; bound_object = null; return; } BoundObjectParent = item; if (Property != null) { EnsurePropertyInfo (Property, ref property_info, BoundObjectParent); bound_object = property_info.GetValue (BoundObjectParent, null); if (SubProperty != null) { EnsurePropertyInfo (SubProperty, ref sub_property_info, bound_object); bound_object = sub_property_info.GetValue (bound_object, null); } } else { bound_object = BoundObjectParent; } } private void EnsurePropertyInfo (string name, ref PropertyInfo prop, object obj) { if (prop == null || prop.ReflectedType != obj.GetType ()) { prop = obj.GetType ().GetProperty (name); if (prop == null) { throw new Exception (String.Format ( "In {0}, type {1} does not have property {2}", this, obj.GetType (), name)); } } } protected Type BoundType { get { return bound_object.GetType (); } } private object bound_object; protected object BoundObject { get { return bound_object; } set { if (Property != null) { EnsurePropertyInfo (Property, ref property_info, BoundObjectParent); property_info.SetValue (BoundObjectParent, value, null); } } } protected object BoundObjectParent { get; private set; } private string property; public string Property { get { return property; } set { property = value; if (value != null) { int i = value.IndexOf ("."); if (i != -1) { property = value.Substring (0, i); SubProperty = value.Substring (i + 1, value.Length - i - 1); } } } } public string SubProperty { get; set; } #endregion } public abstract class CanvasItem { public CanvasItem Parent { get; set; } public Rect Allocation { get; set; } public Rect VirtualAllocation { get; set; } public Thickness Margin { get; set; } public Thickness Padding { get; set; } public abstract void Render (CellContext context); public abstract void Arrange (); public abstract Size Measure (Size available); protected virtual void OnInvalidate (Rect area) { } public void Invalidate (Rect area) { area.Offset (Allocation.X, Allocation.Y); OnInvalidate (area); } public void Invalidate () { Invalidate (Allocation); } public virtual bool ButtonEvent (Point cursor, bool pressed, uint button) { return false; } public virtual bool CursorMotionEvent (Point cursor) { return false; } public virtual void CursorEnterEvent () { } public virtual void CursorLeaveEvent () { } } } hyena-0.5/Hyena.Gui/Hyena.Data.Gui/SortableColumn.cs0000644000175000001440000000446011377105500022310 0ustar00gabeusers00000000000000// // SortableColumn.cs // // Author: // Aaron Bockover // // Copyright (C) 2007 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Collections; using System.Collections.Generic; using Gtk; namespace Hyena.Data.Gui { public class SortableColumn : Column, ISortableColumn { private string sort_key; private SortType sort_type = SortType.Ascending; private Hyena.Query.QueryField field; public SortableColumn(string title, ColumnCell cell, double width, string sort_key, bool visible) : base(title, cell, width, visible) { this.sort_key = sort_key; } public SortableColumn(ColumnCell header_cell, string title, ColumnCell cell, double width, string sort_key, bool visible) : base(header_cell, title, cell, width, visible) { this.sort_key = sort_key; } public string SortKey { get { return sort_key; } set { sort_key = value; } } public SortType SortType { get { return sort_type; } set { sort_type = value; } } public Hyena.Query.QueryField Field { get { return field; } set { field = value; } } } } hyena-0.5/Hyena.Gui/Hyena.Data.Gui/ColumnController.cs0000644000175000001440000001304311377105500022655 0ustar00gabeusers00000000000000// // ColumnController.cs // // Author: // Aaron Bockover // // Copyright (C) 2007 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Collections; using System.Collections.Generic; namespace Hyena.Data.Gui { public class ColumnController : IEnumerable { private List columns = new List (); private ISortableColumn default_sort_column; private ISortableColumn sort_column; protected List Columns { get { return columns; } } public event EventHandler Updated; protected virtual void OnVisibilitiesChanged () { OnUpdated (); } protected virtual void OnWidthsChanged () { } protected void OnUpdated () { EventHandler handler = Updated; if (handler != null) { handler (this, EventArgs.Empty); } } public void Clear () { lock (this) { foreach (Column column in columns) { column.VisibilityChanged -= OnColumnVisibilityChanged; column.WidthChanged -= OnColumnWidthChanged; } columns.Clear (); } OnUpdated (); } public void AddRange (params Column [] range) { lock (this) { foreach (Column column in range) { column.VisibilityChanged += OnColumnVisibilityChanged; column.WidthChanged += OnColumnWidthChanged; } columns.AddRange (range); } OnUpdated (); } public void Add (Column column) { lock (this) { column.VisibilityChanged += OnColumnVisibilityChanged; column.WidthChanged += OnColumnWidthChanged; columns.Add (column); } OnUpdated (); } public void Insert (Column column, int index) { lock (this) { column.VisibilityChanged += OnColumnVisibilityChanged; column.WidthChanged += OnColumnWidthChanged; columns.Insert (index, column); } OnUpdated (); } public void Remove (Column column) { lock (this) { column.VisibilityChanged -= OnColumnVisibilityChanged; column.WidthChanged -= OnColumnWidthChanged; columns.Remove (column); } OnUpdated (); } public void Remove (int index) { lock (this) { Column column = columns[index]; column.VisibilityChanged -= OnColumnVisibilityChanged; column.WidthChanged -= OnColumnWidthChanged; columns.RemoveAt (index); } OnUpdated (); } public void Reorder (int index, int newIndex) { lock (this) { Column column = columns[index]; columns.RemoveAt (index); columns.Insert (newIndex, column); } OnUpdated (); } IEnumerator IEnumerable.GetEnumerator () { return columns.GetEnumerator (); } IEnumerator IEnumerable.GetEnumerator () { return columns.GetEnumerator (); } public int IndexOf (Column column) { lock (this) { return columns.IndexOf (column); } } public Column [] ToArray () { return columns.ToArray (); } private void OnColumnVisibilityChanged (object o, EventArgs args) { OnVisibilitiesChanged (); } private void OnColumnWidthChanged (object o, EventArgs args) { OnWidthsChanged (); } public Column this[int index] { get { return columns[index]; } } public ISortableColumn DefaultSortColumn { get { return default_sort_column; } set { default_sort_column = value; } } public virtual ISortableColumn SortColumn { get { return sort_column; } set { sort_column = value;} } public int Count { get { return columns.Count; } } public virtual bool EnableColumnMenu { get { return false; } } } } hyena-0.5/Hyena.Gui/Hyena.Data.Gui/ColumnCellText.cs0000644000175000001440000001742311377105500022264 0ustar00gabeusers00000000000000// // ColumnCellText.cs // // Author: // Aaron Bockover // // Copyright (C) 2007 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using Gtk; using Cairo; using Hyena.Gui; using Hyena.Gui.Theming; using Hyena.Data.Gui.Accessibility; namespace Hyena.Data.Gui { public class ColumnCellText : ColumnCell, ISizeRequestCell, ITextCell, ITooltipCell { internal const int Spacing = 4; public delegate string DataHandler (); private Pango.Weight font_weight = Pango.Weight.Normal; private Pango.EllipsizeMode ellipsize_mode = Pango.EllipsizeMode.End; private Pango.Alignment alignment = Pango.Alignment.Left; private int text_width; private int text_height; private string text_format = null; protected string MinString, MaxString; private string last_text = null; private bool use_markup; public ColumnCellText (string property, bool expand) : base (property, expand) { } public override Atk.Object GetAccessible (ICellAccessibleParent parent) { return new ColumnCellTextAccessible (BoundObject, this, parent); } public override string GetTextAlternative (object obj) { return GetText (obj); } public void SetMinMaxStrings (object min_max) { SetMinMaxStrings (min_max, min_max); } public void SetMinMaxStrings (object min, object max) { // Set the min/max strings from the min/max objects MinString = GetText (min); MaxString = GetText (max); RestrictSize = true; } public override void Render (CellContext context, StateType state, double cellWidth, double cellHeight) { UpdateText (context, cellWidth); if (String.IsNullOrEmpty (last_text)) { return; } context.Context.Rectangle (0, 0, cellWidth, cellHeight); context.Context.Clip (); context.Context.MoveTo (Spacing, ((int)cellHeight - text_height) / 2); Cairo.Color color = context.Theme.Colors.GetWidgetColor ( context.TextAsForeground ? GtkColorClass.Foreground : GtkColorClass.Text, state); color.A = context.Opaque ? 1.0 : 0.5; context.Context.Color = color; PangoCairoHelper.ShowLayout (context.Context, context.Layout); context.Context.ResetClip (); } public void UpdateText (CellContext context, double cellWidth) { string text = last_text = GetText (BoundObject); if (String.IsNullOrEmpty (text)) { return; } // TODO why doesn't Spacing (eg 4 atm) work here instead of 8? Rendering // seems to be off when changed to Spacing/4 context.Layout.Width = (int)((cellWidth - 8) * Pango.Scale.PangoScale); context.Layout.FontDescription.Weight = font_weight; context.Layout.Ellipsize = EllipsizeMode; context.Layout.Alignment = alignment; UpdateLayout (context.Layout, text); context.Layout.GetPixelSize (out text_width, out text_height); is_ellipsized = context.Layout.IsEllipsized; } private static char[] lfcr = new char[] {'\n', '\r'}; private void UpdateLayout (Pango.Layout layout, string text) { string final_text = GetFormattedText (text); if (final_text.IndexOfAny (lfcr) >= 0) { final_text = final_text.Replace ("\r\n", "\x20").Replace ('\n', '\x20').Replace ('\r', '\x20'); } if (use_markup) { layout.SetMarkup (final_text); } else { layout.SetText (final_text); } } public string GetTooltipMarkup (CellContext cellContext, double columnWidth) { UpdateText (cellContext, columnWidth); return IsEllipsized ? GLib.Markup.EscapeText (Text) : null; } protected virtual string GetText (object obj) { return obj == null ? String.Empty : obj.ToString (); } private string GetFormattedText (string text) { if (text_format == null) { return text; } return String.Format (text_format, text); } private bool is_ellipsized = false; public bool IsEllipsized { get { return is_ellipsized; } } public string Text { get { return last_text; } } protected int TextWidth { get { return text_width; } } protected int TextHeight { get { return text_height; } } public string TextFormat { get { return text_format; } set { text_format = value; } } public Pango.Alignment Alignment { get { return alignment; } set { alignment = value; } } public virtual Pango.Weight FontWeight { get { return font_weight; } set { font_weight = value; } } public virtual Pango.EllipsizeMode EllipsizeMode { get { return ellipsize_mode; } set { ellipsize_mode = value; } } internal static int ComputeRowHeight (Widget widget) { int w_width, row_height; Pango.Layout layout = new Pango.Layout (widget.PangoContext); layout.SetText ("W"); layout.GetPixelSize (out w_width, out row_height); layout.Dispose (); return row_height + 8; } #region ISizeRequestCell implementation public void GetWidthRange (Pango.Layout layout, out int min, out int max) { int height; min = max = -1; if (!String.IsNullOrEmpty (MinString)) { UpdateLayout (layout, MinString); layout.GetPixelSize (out min, out height); min += 2*Spacing; //Console.WriteLine ("for {0} got min {1} for {2}", this, min, MinString); } if (!String.IsNullOrEmpty (MaxString)) { UpdateLayout (layout, MaxString); layout.GetPixelSize (out max, out height); max += 2*Spacing; //Console.WriteLine ("for {0} got max {1} for {2}", this, max, MaxString); } } private bool restrict_size = false; public bool RestrictSize { get { return restrict_size; } set { restrict_size = value; } } public bool UseMarkup { get { return use_markup; } set { use_markup = value; } } #endregion } } hyena-0.5/Hyena.Gui/Hyena.Data.Gui/ColumnCellCheckBox.cs0000644000175000001440000001014311436010340023007 0ustar00gabeusers00000000000000// // ColumnCellCheckBox.cs // // Author: // Aaron Bockover // // Copyright (C) 2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using Gtk; namespace Hyena.Data.Gui { public class ColumnCellCheckBox : ColumnCell, IInteractiveCell, ISizeRequestCell { public event EventHandler Toggled; public ColumnCellCheckBox (string property, bool expand) : base (property, expand) { } public override void Render (CellContext context, StateType state, double cellWidth, double cellHeight) { int cell_width = context.Area.Width - 2 * Xpad; int cell_height = context.Area.Height - 2 * Ypad; int x = context.Area.X + xpad + ((cell_width - Size) / 2); int y = context.Area.Y + ypad + ((cell_height - Size) / 2); if (state == StateType.Normal && last_hover_bound == BoundObjectParent) { state = StateType.Prelight; } Style.PaintCheck (context.Widget.Style, context.Drawable, state, Value ? ShadowType.In : ShadowType.Out, context.Clip, context.Widget, "cellcheck", x, y, Size, Size); } private object last_pressed_bound; private object last_hover_bound; public bool ButtonEvent (int x, int y, bool pressed, Gdk.EventButton evnt) { if (pressed) { last_pressed_bound = BoundObjectParent; return false; } if (last_pressed_bound != null && last_pressed_bound.Equals (BoundObjectParent)) { Value = !Value; last_pressed_bound = null; var handler = Toggled; if (handler != null) { handler (BoundObjectParent, EventArgs.Empty); } } return true; } public bool MotionEvent (int x, int y, Gdk.EventMotion evnt) { if (last_hover_bound == BoundObjectParent) { return false; } last_hover_bound = BoundObjectParent; return true; } public bool PointerLeaveEvent () { last_hover_bound = null; return true; } public void GetWidthRange (Pango.Layout layout, out int min, out int max) { min = max = 2 * Xpad + Size; } private bool restrict_size = true; public bool RestrictSize { get { return restrict_size; } set { restrict_size = value; } } private bool Value { get { return (bool)BoundObject; } set { BoundObject = value; } } private int size = 13; public int Size { get { return size; } set { size = value; } } private int xpad = 2; public int Xpad { get { return xpad; } set { xpad = value; } } public int ypad = 2; public int Ypad { get { return ypad; } set { ypad = value; } } } } hyena-0.5/Hyena.Gui/Hyena.Data.Gui/IHeaderCell.cs0000644000175000001440000000240711377105500021457 0ustar00gabeusers00000000000000// // IHeaderCell.cs // // Author: // Aaron Bockover // // Copyright (C) 2007 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; namespace Hyena.Data.Gui { public interface IHeaderCell { } } hyena-0.5/Hyena.Gui/Hyena.Data.Gui/ColumnHeaderCellText.cs0000644000175000001440000000640211420137571023372 0ustar00gabeusers00000000000000// // ColumnHeaderCellText.cs // // Author: // Aaron Bockover // // Copyright (C) 2007 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using Gtk; using Cairo; using Hyena.Data.Gui.Accessibility; namespace Hyena.Data.Gui { public class ColumnHeaderCellText : ColumnCellText, IHeaderCell { public delegate Column DataHandler (); private DataHandler data_handler; private bool has_sort; public ColumnHeaderCellText (DataHandler data_handler) : base (null, true) { UseMarkup = true; this.data_handler = data_handler; } public override Atk.Object GetAccessible (ICellAccessibleParent parent) { return new ColumnHeaderCellTextAccessible (BoundObject, this, parent); } public override void Render (CellContext context, StateType state, double cellWidth, double cellHeight) { if (data_handler == null) { return; } if (!has_sort) { base.Render (context, state, cellWidth, cellHeight); return; } Gdk.Rectangle arrow_alloc = new Gdk.Rectangle (); arrow_alloc.Width = (int)(cellHeight / 3.0); arrow_alloc.Height = (int)((double)arrow_alloc.Width / 1.6); arrow_alloc.X = (int)cellWidth - arrow_alloc.Width - Spacing; arrow_alloc.Y = ((int)cellHeight - arrow_alloc.Height) / 2; double textWidth = arrow_alloc.X - Spacing; if (textWidth > 0) { base.Render (context, state, textWidth, cellHeight); } SortType sort_type = ((ISortableColumn)data_handler ()).SortType; if (sort_type != SortType.None) { context.Theme.DrawArrow (context.Context, arrow_alloc, sort_type); } } protected override string GetText (object obj) { return data_handler ().Title; } public bool HasSort { get { return has_sort; } set { has_sort = value; } } public static int GetArrowWidth (int headerHeight) { return (int)(headerHeight / 3.0) + Spacing; } } } hyena-0.5/Hyena.Gui/Hyena.Data.Gui/ObjectListView.cs0000644000175000001440000000344011377105500022251 0ustar00gabeusers00000000000000// // ObjectListView.cs // // Author: // Aaron Bockover // // Copyright (C) 2007 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; namespace Hyena.Data.Gui { public class ObjectListView : ListView { public ObjectListView () : base () { ColumnController = new ColumnController(); } protected override void OnModelReloaded () { ColumnController.Clear (); foreach (ColumnDescription column_description in Model.ColumnDescriptions) { ColumnController.Add (new Column (column_description)); } } public new IObjectListModel Model { get { return (IObjectListModel)base.Model; } } } } hyena-0.5/Hyena.Gui/Hyena.Data.Gui/DataViewLayout.cs0000644000175000001440000000716211377105500022263 0ustar00gabeusers00000000000000// // DataViewLayout.cs // // Author: // Aaron Bockover // // Copyright 2010 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Collections.Generic; using Hyena.Data; using Hyena.Gui.Canvas; namespace Hyena.Data.Gui { public abstract class DataViewLayout { private List children = new List (); protected List Children { get { return children; } } public IListModel Model { get; set; } public ListViewBase View { get; set; } public Rect ActualAllocation { get; protected set; } public Size VirtualSize { get; protected set; } public Size ChildSize { get; protected set; } public int XPosition { get; protected set; } public int YPosition { get; protected set; } public int ChildCount { get { return Children.Count; } } public DataViewChild this[int index] { get { return Children[index]; } } public void UpdatePosition (int x, int y) { XPosition = x; YPosition = y; InvalidateChildLayout (); } public void ModelUpdated () { InvalidateVirtualSize (); InvalidateChildLayout (); } public virtual void Allocate (Rect actualAllocation) { ActualAllocation = actualAllocation; InvalidateChildSize (); InvalidateChildCollection (); InvalidateVirtualSize (); InvalidateChildLayout (); } public virtual DataViewChild FindChildAtPoint (Point point) { return Children.Find (child => child.Allocation.Contains ( ActualAllocation.X + point.X, ActualAllocation.Y + point.Y)); } public virtual DataViewChild FindChildAtModelRowIndex (int modelRowIndex) { return Children.Find (child => child.ModelRowIndex == modelRowIndex); } protected abstract void InvalidateChildSize (); protected abstract void InvalidateVirtualSize (); protected abstract void InvalidateChildCollection (); protected abstract void InvalidateChildLayout (); protected Rect GetChildVirtualAllocation (Rect childAllocation) { return new Rect () { X = childAllocation.X - ActualAllocation.X, Y = childAllocation.Y - ActualAllocation.Y, Width = childAllocation.Width, Height = childAllocation.Height }; } } } hyena-0.5/Hyena.Gui/Hyena.Data.Gui/IInteractiveCell.cs0000644000175000001440000000271211377105500022543 0ustar00gabeusers00000000000000// // IInteractiveCell.cs // // Author: // Aaron Bockover // // Copyright (C) 2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using Gdk; namespace Hyena.Data.Gui { public interface IInteractiveCell { bool ButtonEvent (int x, int y, bool pressed, Gdk.EventButton evnt); bool MotionEvent (int x, int y, Gdk.EventMotion evnt); bool PointerLeaveEvent (); } }hyena-0.5/Hyena.Gui/Hyena.Gui.dll.config0000644000175000001440000000224211377105500020115 0ustar00gabeusers00000000000000 hyena-0.5/Hyena.Gui/Hyena.Gui.Theatrics/0000777000175000001440000000000011453151003020077 5ustar00gabeusers00000000000000hyena-0.5/Hyena.Gui/Hyena.Gui.Theatrics/Stage.cs0000644000175000001440000001661111377105500021500 0ustar00gabeusers00000000000000// // Stage.cs // // Author: // Aaron Bockover // // Copyright (C) 2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Collections.Generic; namespace Hyena.Gui.Theatrics { public class Stage { public delegate bool ActorStepHandler (Actor actor); private Dictionary> actors = new Dictionary> (); private uint timeout_id; private uint update_frequency = 30; private uint default_duration = 1000; private bool playing = true; public event ActorStepHandler ActorStep; #pragma warning disable 0067 // FIXME: This is to mute gmcs: https://bugzilla.novell.com/show_bug.cgi?id=360455 public event EventHandler Iteration; #pragma warning restore 0067 public Stage () { } public Stage (uint actorDuration) { default_duration = actorDuration; } public Actor this[T target] { get { if (actors.ContainsKey (target)) { return actors[target]; } return null; } } public bool Contains (T target) { return actors.ContainsKey (target); } public Actor Add (T target) { lock (this) { return Add (target, default_duration); } } public Actor Add (T target, uint duration) { lock (this) { if (Contains (target)) { throw new InvalidOperationException ("Stage already contains this actor"); } Actor actor = new Actor (target, duration); actors.Add (target, actor); CheckTimeout (); return actor; } } public Actor AddOrReset (T target) { lock (this) { return AddOrResetCore (target, null); } } public Actor AddOrReset (T target, uint duration) { lock (this) { return AddOrResetCore (target, duration); } } private Actor AddOrResetCore (T target, uint? duration) { lock (this) { if (Contains (target)) { Actor actor = this[target]; if (duration == null) { actor.Reset (); } else { actor.Reset (duration.Value); } CheckTimeout (); return actor; } return Add (target); } } public void Reset (T target) { lock (this) { ResetCore (target, null); } } public void Reset (T target, uint duration) { lock (this) { ResetCore (target, duration); } } private void ResetCore (T target, uint? duration) { lock (this) { if (!Contains (target)) { throw new InvalidOperationException ("Stage does not contain this actor"); } CheckTimeout (); if (duration == null) { this [target].Reset (); } else { this [target].Reset (duration.Value); } } } private void CheckTimeout () { if ((!Playing || actors.Count == 0) && timeout_id > 0) { GLib.Source.Remove (timeout_id); timeout_id = 0; return; } else if (Playing && actors.Count > 0 && timeout_id <= 0) { timeout_id = GLib.Timeout.Add (update_frequency, OnTimeout); return; } } private bool OnTimeout () { if (!Playing || this.actors.Count == 0) { timeout_id = 0; return false; } Queue> actors = new Queue> (this.actors.Values); while (actors.Count > 0) { Actor actor = actors.Dequeue (); actor.Step (); if (!OnActorStep (actor) || actor.Expired) { this.actors.Remove (actor.Target); } } OnIteration (); return true; } protected virtual bool OnActorStep (Actor actor) { ActorStepHandler handler = ActorStep; if (handler != null) { bool result = true; foreach (ActorStepHandler del in handler.GetInvocationList ()) { result &= del (actor); } return result; } return false; } protected virtual void OnIteration () { EventHandler handler = Iteration; if (handler != null) { handler (this, EventArgs.Empty); } } public void Play () { lock (this) { Playing = true; } } public void Pause () { lock (this) { Playing = false; } } public void Exeunt () { lock (this) { actors.Clear (); CheckTimeout (); } } public uint DefaultActorDuration { get { return default_duration; } set { lock (this) { default_duration = value; } } } public bool Playing { get { return playing; } set { lock (this) { if (playing == value) { return; } playing = value; CheckTimeout (); } } } public uint UpdateFrequency { get { return update_frequency; } set { lock (this) { bool _playing = Playing; update_frequency = value; Playing = _playing; } } } public int ActorCount { get { return actors.Count; } } } } hyena-0.5/Hyena.Gui/Hyena.Gui.Theatrics/Tests/0000777000175000001440000000000011453151003021201 5ustar00gabeusers00000000000000hyena-0.5/Hyena.Gui/Hyena.Gui.Theatrics/Tests/ChoreographerTests.cs0000644000175000001440000000730211377105500025347 0ustar00gabeusers00000000000000// // ChoreographerTests.cs // // Author: // Aaron Bockover // // Copyright (C) 2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // #if ENABLE_TESTS using System; using NUnit.Framework; using Hyena; using Hyena.Gui.Theatrics; namespace Hyena.Gui.Theatrics.Tests { [TestFixture] public class ChoreographerTests { private void _TestComposeRange (int [] values, Easing easing) { for (double i = 0, n = 100, p = 0, j = 0; i <= n; i += 5, p = i / n, j++) { int value = Choreographer.PixelCompose (p, (int)n, easing); Assert.AreEqual (values[(int)j], value); } } [Test] public void QuadraticInCompose () { _TestComposeRange (new int [] { 0, 0, 1, 2, 4, 6, 9, 12, 16, 20, 25, 30, 36, 42, 49, 56, 64, 72, 81, 90, 100 }, Easing.QuadraticIn); } [Test] public void QuadraticOutCompose () { _TestComposeRange (new int [] { 0, 10, 19, 28, 36, 44, 51, 58, 64, 70, 75, 80, 84, 88, 91, 94, 96, 98, 99, 100, 100 }, Easing.QuadraticOut); } [Test] public void QuadraticInOutCompose () { _TestComposeRange (new int [] { 0, 1, 2, 4, 8, 12, 18, 24, 32, 40, 50, 60, 68, 76, 82, 88, 92, 96, 98, 100, 100 }, Easing.QuadraticInOut); } [Test] public void ExponentialInCompose () { _TestComposeRange (new int [] { 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 4, 6, 9, 12, 18, 25, 35, 50, 71, 100 }, Easing.ExponentialIn); } [Test] public void ExponentialOutCompose () { _TestComposeRange (new int [] { 0, 29, 50, 65, 75, 82, 88, 91, 94, 96, 97, 98, 98, 99, 99, 99, 100, 100, 100, 100, 100 }, Easing.ExponentialOut); } [Test] public void ExponentialInOutCompose () { _TestComposeRange (new int [] { 0, 0, 0, 0, 1, 2, 3, 6, 13, 25, 50, 75, 88, 94, 97, 98, 99, 100, 100, 100, 100 }, Easing.ExponentialInOut); } [Test] public void LinearCompose () { _TestComposeRange (new int [] { 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100 }, Easing.Linear); } [Test] public void SineCompose () { _TestComposeRange (new int [] { 0, 16, 31, 45, 59, 71, 81, 89, 95, 99, 100, 99, 95, 89, 81, 71, 59, 45, 31, 16, 0 }, Easing.Sine); } } } #endif hyena-0.5/Hyena.Gui/Hyena.Gui.Theatrics/Choreographer.cs0000644000175000001440000000646511377105500023233 0ustar00gabeusers00000000000000// // Choreographer.cs // // Authors: // Scott Peterson // // Copyright (C) 2008 Scott Peterson // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using Hyena.Widgets; namespace Hyena.Widgets { public enum Blocking { Upstage, Downstage } } namespace Hyena.Gui.Theatrics { public enum Easing { Linear, QuadraticIn, QuadraticOut, QuadraticInOut, ExponentialIn, ExponentialOut, ExponentialInOut, Sine, } public static class Choreographer { public static int PixelCompose (double percent, int size, Easing easing) { return (int)Math.Round (Compose (percent, size, easing)); } public static double Compose (double percent, double scale, Easing easing) { return scale * Compose (percent, easing); } public static double Compose (double percent, Easing easing) { if (percent < 0.0 || percent > 1.0) { throw new ArgumentOutOfRangeException ("percent", "must be between 0 and 1 inclusive"); } switch (easing) { case Easing.QuadraticIn: return percent * percent; case Easing.QuadraticOut: return -1.0 * percent * (percent - 2.0); case Easing.QuadraticInOut: percent *= 2.0; return percent < 1.0 ? percent * percent * 0.5 : -0.5 * (--percent * (percent - 2.0) - 1.0); case Easing.ExponentialIn: return Math.Pow (2.0, 10.0 * (percent - 1.0)); case Easing.ExponentialOut: return -Math.Pow (2.0, -10.0 * percent) + 1.0; case Easing.ExponentialInOut: percent *= 2.0; return percent < 1.0 ? 0.5 * Math.Pow (2.0, 10.0 * (percent - 1.0)) : 0.5 * (-Math.Pow (2.0, -10.0 * --percent) + 2.0); case Easing.Sine: return Math.Sin (percent * Math.PI); case Easing.Linear: default: return percent; } } } }hyena-0.5/Hyena.Gui/Hyena.Gui.Theatrics/SingleActorStage.cs0000644000175000001440000000357211377105500023635 0ustar00gabeusers00000000000000// // SingleActorStage.cs // // Author: // Aaron Bockover // // Copyright (C) 2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; namespace Hyena.Gui.Theatrics { public class SingleActorStage : Stage { private object target = new object (); public SingleActorStage () : base () { } public SingleActorStage (uint actorDuration) : base (actorDuration) { } protected override bool OnActorStep (Actor actor) { return true; } public void Reset () { AddOrReset (target); } public void Reset (uint duration) { AddOrReset (target, duration); } public Actor Actor { get { return this[target]; } } } } hyena-0.5/Hyena.Gui/Hyena.Gui.Theatrics/Pulsator.cs0000644000175000001440000000640011377105500022241 0ustar00gabeusers00000000000000// // Pulsator.cs // // Author: // Aaron Bockover // // Copyright (C) 2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; namespace Hyena.Gui.Theatrics { public class Pulsator where T : class { private Stage stage; public Stage Stage { get { return stage; } set { if (stage == value) { return; } if (stage != null) { stage.ActorStep -= OnActorStep; } stage = value; if (stage != null) { stage.ActorStep += OnActorStep; } } } private T target; public T Target { get { return target; } set { target = value; } } public double Percent { get { return IsPulsing ? stage[Target].Percent : 0; } } public bool IsPulsing { get { return stage != null && stage.Contains (Target); } } public bool Stopping { get { return !IsPulsing ? true : stage[Target].CanExpire; } } #pragma warning disable 0067 // FIXME: This is to mute gmcs: https://bugzilla.novell.com/show_bug.cgi?id=360455 public event EventHandler Pulse; #pragma warning restore 0067 public Pulsator () { } public Pulsator (Stage stage) { Stage = stage; } public void StartPulsing () { if (!Stage.Contains (Target)) { Stage.Add (Target); } Stage[Target].CanExpire = false; } public void StopPulsing () { if (Stage.Contains (Target)) { Stage[Target].CanExpire = true; } } private bool OnActorStep (Actor actor) { if (actor.Target == target) { OnPulse (); } return true; } protected virtual void OnPulse () { EventHandler handler = Pulse; if (handler != null) { handler (this, EventArgs.Empty); } } } } hyena-0.5/Hyena.Gui/Hyena.Gui.Theatrics/Actor.cs0000644000175000001440000000575711377105500021516 0ustar00gabeusers00000000000000// // Actor.cs // // Author: // Aaron Bockover // // Copyright (C) 2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; namespace Hyena.Gui.Theatrics { public class Actor { private DateTime start_time; private DateTime last_step_time; public Actor (T target, double duration) { Target = target; Duration = duration; CanExpire = true; Reset (); } public void Reset () { Reset (Duration); } public void Reset (double duration) { start_time = DateTime.Now; last_step_time = DateTime.Now; Frames = 0.0; Percent = 0.0; Duration = duration; } public virtual void Step () { if (!CanExpire && Percent >= 1.0) { Reset (); } StepDelta = (DateTime.Now - last_step_time).TotalMilliseconds; last_step_time = DateTime.Now; Percent = PClamp ((last_step_time - start_time).TotalMilliseconds / Duration); StepDeltaPercent = PClamp (StepDelta / Duration); Frames++; } private static double PClamp (double value) { return Math.Max (0.1, Math.Min (1.0, value)); } public bool CanExpire { get; set; } public T Target { get; private set; } public double Duration { get; private set; } public DateTime StartTime { get; private set; } public double StepDelta { get; private set; } public double StepDeltaPercent { get; private set; } public double Percent { get; private set; } public double Frames { get; private set; } public double FramesPerSecond { get { return Frames / ((double)Duration / 1000.0); } } public bool Expired { get { return CanExpire && Percent >= 1.0; } } } } hyena-0.5/Hyena.Gui/Hyena.Gui.Canvas/0000777000175000001440000000000011453151003017364 5ustar00gabeusers00000000000000hyena-0.5/Hyena.Gui/Hyena.Gui.Canvas/Thickness.cs0000644000175000001440000000735511377105500021662 0ustar00gabeusers00000000000000// // Thickness.cs // // Author: // Aaron Bockover // // Copyright 2009-2010 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; namespace Hyena.Gui.Canvas { public struct Thickness { private double left; private double top; private double right; private double bottom; public Thickness (double thickness) : this (thickness, thickness, thickness, thickness) { } public Thickness (double xthickness, double ythickness) : this (xthickness, ythickness, xthickness, ythickness) { } public Thickness (double left, double top, double right, double bottom) { this.left = left; this.top = top; this.right = right; this.bottom = bottom; } public override string ToString () { return string.Format ("{0},{1},{2},{3}", Double.IsNaN (left) ? "Auto" : left.ToString (), Double.IsNaN (top) ? "Auto" : top.ToString (), Double.IsNaN (right) ? "Auto" : right.ToString (), Double.IsNaN (bottom) ? "Auto" : bottom.ToString ()); } public override bool Equals (object o) { if (!(o is Thickness)) { return false; } return this == (Thickness)o; } public bool Equals (Thickness thickness) { return this == thickness; } public override int GetHashCode () { return left.GetHashCode () ^ top.GetHashCode () ^ right.GetHashCode () ^ bottom.GetHashCode (); } public static bool operator == (Thickness t1, Thickness t2) { return t1.left == t2.left && t1.right == t2.right && t1.top == t2.top && t1.bottom == t2.bottom; } public static bool operator != (Thickness t1, Thickness t2) { return !(t1 == t2); } public double Left { get { return left; } set { left = value; } } public double Top { get { return top; } set { top = value; } } public double Right { get { return right; } set { right = value; } } public double Bottom { get { return bottom; } set { bottom = value; } } public double X { get { return Left + Right; } } public double Y { get { return Top + Bottom; } } } } hyena-0.5/Hyena.Gui/Hyena.Gui.Canvas/Point.cs0000644000175000001440000000461611377105500021015 0ustar00gabeusers00000000000000// // Point.cs // // Author: // Aaron Bockover // // Copyright 2009-2010 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; namespace Hyena.Gui.Canvas { public struct Point { public double X { get; set; } public double Y { get; set; } public Point (double x, double y) : this () { X = x; Y = y; } public void Offset (double dx, double dy) { X += dx; Y += dy; } public void Offset (Point delta) { X += delta.X; Y += delta.Y; } public override bool Equals (object o) { return o is Point ? Equals ((Point)o) : false; } public bool Equals (Point value) { return value.X == X && value.Y == Y; } public static bool operator == (Point point1, Point point2) { return point1.X == point2.X && point1.Y == point2.Y; } public static bool operator != (Point point1, Point point2) { return !(point1 == point2); } public override int GetHashCode () { return X.GetHashCode () ^ Y.GetHashCode (); } public override string ToString () { return String.Format ("{0},{1}", X, Y); } } } hyena-0.5/Hyena.Gui/Hyena.Gui.Canvas/Rect.cs0000644000175000001440000001663311377105500020623 0ustar00gabeusers00000000000000// // Rect.cs // // Author: // Aaron Bockover // // Copyright 2009-2010 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; namespace Hyena.Gui.Canvas { public struct Rect { private double x, y, w, h; public Rect (double x, double y, double width, double height) : this () { X = x; Y = y; Width = width; Height = height; } public Rect (Point point1, Point point2) : this () { X = Math.Min (point1.X, point2.X); Y = Math.Min (point1.Y, point2.Y); Width = Math.Abs (point2.X - point1.X); Height = Math.Abs (point2.Y - point1.Y); } public Rect (Point location, Size size) : this () { X = location.X; Y = location.Y; Width = size.Width; Height = size.Height; } public override string ToString () { if (IsEmpty) { return "Empty"; } return String.Format ("{0}+{1},{2}x{3}", x, y, w, h); } public double X { get { return x; } set { x = value; } } public double Y { get { return y; } set { y = value; } } public double Width { get { return w; } set { if (value < 0) { throw new ArgumentException (); } w = value; } } public double Height { get { return h; } set { if (value < 0) { throw new ArgumentException (); } h = value; } } public bool Contains (double px, double py) { return !(px < x || px > x + w || py < y || py > y + h); } public bool Contains (Point point) { return Contains (point.X, point.Y); } public bool IntersectsWith (Rect rect) { return !(Left > rect.Right || Right < rect.Left || Top > rect.Bottom || Bottom < rect.Top); } public static Rect Empty { get { var empty = new Rect (Double.PositiveInfinity, Double.PositiveInfinity, 0, 0); empty.w = empty.h = Double.NegativeInfinity; return empty; } } public bool IsEmpty { get { return w < 0 && h < 0; } } public double Left { get { return x; } } public double Top { get { return y; } } public double Right { get { return IsEmpty ? Double.NegativeInfinity : x + w; } } public double Bottom { get { return IsEmpty ? Double.NegativeInfinity : y + h; } } public void Intersect (Rect rect) { if (IsEmpty || rect.IsEmpty) { this = Rect.Empty; return; } double new_x = Math.Max (x, rect.x); double new_y = Math.Max (y, rect.y); double new_w = Math.Min (Right, rect.Right) - new_x; double new_h = Math.Min (Bottom, rect.Bottom) - new_y; x = new_x; y = new_y; w = new_w; h = new_h; if (w < 0 || h < 0) { this = Rect.Empty; } } public void Union (Rect rect) { if (IsEmpty) { x = rect.x; y = rect.y; h = rect.h; w = rect.w; } else if (!rect.IsEmpty) { double new_x = Math.Min (Left, rect.Left); double new_y = Math.Min (Top, rect.Top); double new_w = Math.Max (Right, rect.Right) - new_x; double new_h = Math.Max (Bottom, rect.Bottom) - new_y; x = new_x; y = new_y; w = new_w; h = new_h; } } public void Union (Point point) { Union (new Rect (point, point)); } public void Offset (Rect rect) { x += rect.X; y += rect.Y; } public void Offset (Point point) { x += point.X; y += point.Y; } public void Offset (double dx, double dy) { x += dx; y += dy; } public static bool operator == (Rect rect1, Rect rect2) { return rect1.x == rect2.x && rect1.y == rect2.y && rect1.w == rect2.w && rect1.h == rect2.h; } public static bool operator != (Rect rect1, Rect rect2) { return !(rect1 == rect2); } public override bool Equals (object o) { if (o is Rect) { return this == (Rect)o; } return false; } public bool Equals (Rect value) { return this == value; } public override int GetHashCode () { return x.GetHashCode () ^ y.GetHashCode () ^ w.GetHashCode () ^ h.GetHashCode (); } #region GDK/Cairo extensions public static explicit operator Rect (Gdk.Rectangle rect) { return new Rect () { X = rect.X, Y = rect.Y, Width = rect.Width, Height = rect.Height }; } public static explicit operator Gdk.Rectangle (Rect rect) { return new Gdk.Rectangle () { X = (int)Math.Floor (rect.X), Y = (int)Math.Floor (rect.Y), Width = (int)Math.Ceiling (rect.Width), Height = (int)Math.Ceiling (rect.Height) }; } public static explicit operator Rect (Cairo.Rectangle rect) { return new Rect (rect.X, rect.Y, rect.Width, rect.Height); } public static explicit operator Cairo.Rectangle (Rect rect) { return new Cairo.Rectangle (rect.X, rect.Y, rect.Width, rect.Height); } #endregion } } hyena-0.5/Hyena.Gui/Hyena.Gui.Canvas/Size.cs0000644000175000001440000000653711377105500020642 0ustar00gabeusers00000000000000// // Size.cs // // Author: // Aaron Bockover // // Copyright 2009-2010 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; namespace Hyena.Gui.Canvas { public struct Size { private double width; private double height; public Size (double width, double height) : this () { Width = width; Height = height; } public override bool Equals (object o) { if (!(o is Size)) { return false; } return Equals ((Size)o); } public bool Equals (Size value) { return value.width == width && value.height == height; } public override int GetHashCode () { return ((int)width) ^ ((int)height); } public static bool operator == (Size size1, Size size2) { return size1.width == size2.width && size1.height == size2.height; } public static bool operator != (Size size1, Size size2) { return size1.width != size2.width || size1.height != size2.height; } public double Height { get { return height; } set { if (value < 0) { throw new ArgumentException (); } height = value; } } public double Width { get { return width; } set { if (value < 0) { throw new ArgumentException (); } width = value; } } public bool IsEmpty { get { return width == Double.NegativeInfinity && height == Double.NegativeInfinity; } } public static Size Empty { get { Size size = new Size (); size.width = Double.NegativeInfinity; size.height = Double.NegativeInfinity; return size; } } public override string ToString () { if (IsEmpty) { return "Empty"; } return String.Format ("{0}x{1}", width, height); } } } hyena-0.5/Hyena.Gui/Makefile.am0000644000175000001440000001075511416417207016435 0ustar00gabeusers00000000000000ASSEMBLY = Hyena.Gui ASSEMBLY_BUILD_FLAGS = -unsafe TARGET = library LINK = -r:ICSharpCode.SharpZipLib -r:Mono.Posix -r:System -r:System.Core -r:Mono.Cairo \ $(GTKSHARP_LIBS) $(GLIBSHARP_LIBS) \ -r:$(DIR_BIN)/Hyena.dll SOURCES = \ Hyena.Data.Gui/Accessibility/ColumnCellAccessible.cs \ Hyena.Data.Gui/Accessibility/ColumnCellTextAccessible.cs \ Hyena.Data.Gui/Accessibility/ColumnHeaderCellTextAccessible.cs \ Hyena.Data.Gui/Accessibility/ICellAccessibleParent.cs \ Hyena.Data.Gui/Accessibility/ListViewAccessible.cs \ Hyena.Data.Gui/Accessibility/ListViewAccessible_Selection.cs \ Hyena.Data.Gui/Accessibility/ListViewAccessible_Table.cs \ Hyena.Data.Gui/CellContext.cs \ Hyena.Data.Gui/Column.cs \ Hyena.Data.Gui/ColumnCell.cs \ Hyena.Data.Gui/ColumnCellCheckBox.cs \ Hyena.Data.Gui/ColumnCellRating.cs \ Hyena.Data.Gui/ColumnCellText.cs \ Hyena.Data.Gui/ColumnController.cs \ Hyena.Data.Gui/ColumnHeaderCellText.cs \ Hyena.Data.Gui/DataViewChild.cs \ Hyena.Data.Gui/DataViewLayout.cs \ Hyena.Data.Gui/DataViewLayoutGrid.cs \ Hyena.Data.Gui/IHeaderCell.cs \ Hyena.Data.Gui/IInteractiveCell.cs \ Hyena.Data.Gui/IListView.cs \ Hyena.Data.Gui/ISizeRequestCell.cs \ Hyena.Data.Gui/ITextCell.cs \ Hyena.Data.Gui/ITooltipCell.cs \ Hyena.Data.Gui/ListView/ListView.cs \ Hyena.Data.Gui/ListView/ListView_Accessible.cs \ Hyena.Data.Gui/ListView/ListView_DragAndDrop.cs \ Hyena.Data.Gui/ListView/ListView_Header.cs \ Hyena.Data.Gui/ListView/ListView_Interaction.cs \ Hyena.Data.Gui/ListView/ListView_Model.cs \ Hyena.Data.Gui/ListView/ListView_Rendering.cs \ Hyena.Data.Gui/ListView/ListView_Windowing.cs \ Hyena.Data.Gui/ListView/ListViewBase.cs \ Hyena.Data.Gui/ListViewTestModule.cs \ Hyena.Data.Gui/ObjectListView.cs \ Hyena.Data.Gui/RowActivatedHandler.cs \ Hyena.Data.Gui/SortableColumn.cs \ Hyena.Gui.Canvas/Point.cs \ Hyena.Gui.Canvas/Rect.cs \ Hyena.Gui.Canvas/Size.cs \ Hyena.Gui.Canvas/Thickness.cs \ Hyena.Gui.Dialogs/ExceptionDialog.cs \ Hyena.Gui.Dialogs/VersionInformationDialog.cs \ Hyena.Gui.Theatrics/Actor.cs \ Hyena.Gui.Theatrics/Choreographer.cs \ Hyena.Gui.Theatrics/Pulsator.cs \ Hyena.Gui.Theatrics/SingleActorStage.cs \ Hyena.Gui.Theatrics/Stage.cs \ Hyena.Gui.Theatrics/Tests/ChoreographerTests.cs \ Hyena.Gui.Theming/GtkColors.cs \ Hyena.Gui.Theming/GtkTheme.cs \ Hyena.Gui.Theming/Theme.cs \ Hyena.Gui.Theming/ThemeContext.cs \ Hyena.Gui.Theming/ThemeEngine.cs \ Hyena.Gui.Theming/ThemeTestModule.cs \ Hyena.Gui/ActionManager.cs \ Hyena.Gui/BaseWidgetAccessible.cs \ Hyena.Gui/CairoDamageDebugger.cs \ Hyena.Gui/CairoExtensions.cs \ Hyena.Gui/CleanRoomStartup.cs \ Hyena.Gui/CompositeUtils.cs \ Hyena.Gui/Contrast.cs \ Hyena.Gui/DragDropList.cs \ Hyena.Gui/EditableEraseAction.cs \ Hyena.Gui/EditableInsertAction.cs \ Hyena.Gui/EditableUndoAdapter.cs \ Hyena.Gui/GtkUtilities.cs \ Hyena.Gui/GtkWorkarounds.cs \ Hyena.Gui/HyenaActionGroup.cs \ Hyena.Gui/PangoCairoHelper.cs \ Hyena.Gui/PangoExtensions.cs \ Hyena.Gui/PixbufImageSurface.cs \ Hyena.Gui/RatingRenderer.cs \ Hyena.Gui/ShadingTestWindow.cs \ Hyena.Gui/TestModuleAttribute.cs \ Hyena.Gui/TestModuleRunner.cs \ Hyena.Gui/TooltipSetter.cs \ Hyena.Query.Gui/DateQueryValueEntry.cs \ Hyena.Query.Gui/FileSizeQueryValueEntry.cs \ Hyena.Query.Gui/IntegerQueryValueEntry.cs \ Hyena.Query.Gui/NullQueryValueEntry.cs \ Hyena.Query.Gui/QueryBox.cs \ Hyena.Query.Gui/QueryDebugger.cs \ Hyena.Query.Gui/QueryLimitBox.cs \ Hyena.Query.Gui/QueryTermBox.cs \ Hyena.Query.Gui/QueryTermsBox.cs \ Hyena.Query.Gui/QueryValueEntry.cs \ Hyena.Query.Gui/RelativeTimeSpanQueryValueEntry.cs \ Hyena.Query.Gui/StringQueryValueEntry.cs \ Hyena.Query.Gui/TimeSpanQueryValueEntry.cs \ Hyena.Widgets/AnimatedBox.cs \ Hyena.Widgets/AnimatedHBox.cs \ Hyena.Widgets/AnimatedImage.cs \ Hyena.Widgets/AnimatedVBox.cs \ Hyena.Widgets/AnimatedWidget.cs \ Hyena.Widgets/ComplexMenuItem.cs \ Hyena.Widgets/EntryPopup.cs \ Hyena.Widgets/GenericToolItem.cs \ Hyena.Widgets/HigMessageDialog.cs \ Hyena.Widgets/ImageButton.cs \ Hyena.Widgets/MenuButton.cs \ Hyena.Widgets/MessageBar.cs \ Hyena.Widgets/PulsingButton.cs \ Hyena.Widgets/RatingEntry.cs \ Hyena.Widgets/RatingMenuItem.cs \ Hyena.Widgets/RoundedFrame.cs \ Hyena.Widgets/ScrolledWindow.cs \ Hyena.Widgets/SegmentedBar.cs \ Hyena.Widgets/SimpleTable.cs \ Hyena.Widgets/SmoothScrolledWindow.cs \ Hyena.Widgets/TextViewEditable.cs \ Hyena.Widgets/WrapLabel.cs include $(top_srcdir)/build/build.mk EXTRA_DIST += Hyena.Gui.dll.config module_SCRIPTS += Hyena.Gui.dll.config hyena-0.5/Hyena.Gui/Hyena.Query.Gui/0000777000175000001440000000000011453151003017256 5ustar00gabeusers00000000000000hyena-0.5/Hyena.Gui/Hyena.Query.Gui/DateQueryValueEntry.cs0000644000175000001440000000713611377105500023540 0ustar00gabeusers00000000000000// // DateQueryValueEntry.cs // // Authors: // Gabriel Burt // // Copyright (C) 2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using Mono.Unix; using Hyena.Query; using Gtk; namespace Hyena.Query.Gui { public class DateQueryValueEntry : QueryValueEntry { protected DateQueryValue query_value; protected SpinButton year_entry = new SpinButton (Double.MinValue, Double.MaxValue, 1.0); protected SpinButton month_entry = new SpinButton (0.0, 12.0, 1.0); protected SpinButton day_entry = new SpinButton (0.0, 31.0, 1.0); public DateQueryValueEntry () : base () { year_entry.MaxLength = year_entry.WidthChars = 4; month_entry.MaxLength = month_entry.WidthChars = 2; day_entry.MaxLength = day_entry.WidthChars = 2; year_entry.Numeric = month_entry.Numeric = day_entry.Numeric = true; month_entry.Wrap = day_entry.Wrap = true; year_entry.Value = (double) DateTime.Now.Year; month_entry.Value = (double) DateTime.Now.Month; day_entry.Value = (double) DateTime.Now.Day; year_entry.Changed += HandleValueChanged; month_entry.Changed += HandleValueChanged; day_entry.Changed += HandleValueChanged; Add (year_entry); Add (new Label ("-")); Add (month_entry); Add (new Label ("-")); Add (day_entry); } public override QueryValue QueryValue { get { return query_value; } set { year_entry.Changed -= HandleValueChanged; month_entry.Changed -= HandleValueChanged; day_entry.Changed -= HandleValueChanged; query_value = value as DateQueryValue; year_entry.Value = (double) query_value.DateTime.Year; month_entry.Value = (double) query_value.DateTime.Month; day_entry.Value = (double) query_value.DateTime.Day; year_entry.Changed += HandleValueChanged; month_entry.Changed += HandleValueChanged; day_entry.Changed += HandleValueChanged; } } protected void HandleValueChanged (object o, EventArgs args) { try { DateTime dt = new DateTime (year_entry.ValueAsInt, month_entry.ValueAsInt, day_entry.ValueAsInt); query_value.SetValue (dt); } catch { Log.Debug ("Caught exception raised because of invalid date"); } } } } hyena-0.5/Hyena.Gui/Hyena.Query.Gui/TimeSpanQueryValueEntry.cs0000644000175000001440000000664611377105500024410 0ustar00gabeusers00000000000000// // TimeSpanQueryValueEntry.cs // // Authors: // Gabriel Burt // // Copyright (C) 2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using Mono.Unix; using Hyena.Query; using Gtk; namespace Hyena.Query.Gui { public class TimeSpanQueryValueEntry : QueryValueEntry { protected SpinButton spin_button; protected ComboBox combo; protected TimeSpanQueryValue query_value; private int set_combo = 1; protected static readonly TimeFactor [] factors = new TimeFactor [] { TimeFactor.Second, TimeFactor.Minute, TimeFactor.Hour, TimeFactor.Day, TimeFactor.Week, TimeFactor.Month, TimeFactor.Year }; public TimeSpanQueryValueEntry () : base () { spin_button = new SpinButton (0.0, 1.0, 1.0); spin_button.Digits = 1; spin_button.WidthChars = 4; spin_button.SetRange (0.0, Double.MaxValue); Add (spin_button); combo = ComboBox.NewText (); combo.AppendText (Catalog.GetString ("seconds")); combo.AppendText (Catalog.GetString ("minutes")); combo.AppendText (Catalog.GetString ("hours")); combo.AppendText (Catalog.GetString ("days")); combo.AppendText (Catalog.GetString ("weeks")); combo.AppendText (Catalog.GetString ("months")); combo.AppendText (Catalog.GetString ("years")); combo.Realized += delegate { combo.Active = set_combo; }; Add (combo); spin_button.ValueChanged += HandleValueChanged; combo.Changed += HandleValueChanged; } public override QueryValue QueryValue { get { return query_value; } set { spin_button.ValueChanged -= HandleValueChanged; combo.Changed -= HandleValueChanged; query_value = value as TimeSpanQueryValue; spin_button.Value = query_value.FactoredValue; combo.Active = set_combo = Array.IndexOf (factors, query_value.Factor); spin_button.ValueChanged += HandleValueChanged; combo.Changed += HandleValueChanged; } } protected virtual void HandleValueChanged (object o, EventArgs args) { query_value.SetRelativeValue (spin_button.Value, factors [combo.Active]); } } } hyena-0.5/Hyena.Gui/Hyena.Query.Gui/FileSizeQueryValueEntry.cs0000644000175000001440000000645411377105500024377 0ustar00gabeusers00000000000000// // FileSizeQueryValueEntry.cs // // Authors: // Gabriel Burt // // Copyright (C) 2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using Mono.Unix; using Hyena.Query; using Gtk; namespace Hyena.Query.Gui { public class FileSizeQueryValueEntry : QueryValueEntry { protected SpinButton spin_button; protected ComboBox combo; protected FileSizeQueryValue query_value; protected static readonly FileSizeFactor [] factors = new FileSizeFactor [] { FileSizeFactor.None, FileSizeFactor.KB, FileSizeFactor.MB, FileSizeFactor.GB }; bool combo_set = false; // Relative: [<|>] [num] [minutes|hours] ago // TODO: Absolute: [>|>=|=|<|<=] [date/time] public FileSizeQueryValueEntry () : base () { spin_button = new SpinButton (0.0, 1.0, 1.0); spin_button.Digits = 1; spin_button.WidthChars = 4; spin_button.SetRange (0.0, Double.MaxValue); Add (spin_button); combo = ComboBox.NewText (); combo.AppendText (Catalog.GetString ("bytes")); combo.AppendText (Catalog.GetString ("KB")); combo.AppendText (Catalog.GetString ("MB")); combo.AppendText (Catalog.GetString ("GB")); combo.Realized += delegate { if (!combo_set) { combo.Active = 2; } }; Add (combo); spin_button.ValueChanged += HandleValueChanged; combo.Changed += HandleValueChanged; } public override QueryValue QueryValue { get { return query_value; } set { spin_button.ValueChanged -= HandleValueChanged; combo.Changed -= HandleValueChanged; query_value = value as FileSizeQueryValue; spin_button.Value = query_value.FactoredValue; combo_set = true; combo.Active = Array.IndexOf (factors, query_value.Factor); spin_button.ValueChanged += HandleValueChanged; combo.Changed += HandleValueChanged; } } protected void HandleValueChanged (object o, EventArgs args) { query_value.SetValue (spin_button.Value, factors [combo.Active]); } } } hyena-0.5/Hyena.Gui/Hyena.Query.Gui/QueryDebugger.cs0000644000175000001440000001165311377105500022367 0ustar00gabeusers00000000000000// // QueryDebugger.cs // // Author: // Aaron Bockover // // Copyright (C) 2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.IO; using System.Xml; using System.Reflection; using Gtk; using Hyena.Gui; using Hyena.Query; namespace Hyena.Query.Gui { [TestModule ("Query Debugger")] public class QueryDebugger : Window { private TextView input; private TextView sql; private TextView xml; private QueryFieldSet query_field_set; public QueryDebugger () : base ("Hyena.Query Debugger") { SetDefaultSize (800, 600); VBox input_box = new VBox (); input_box.Spacing = 8; ScrolledWindow sw = new ScrolledWindow (); sw.ShadowType = ShadowType.In; sw.HscrollbarPolicy = PolicyType.Never; input = new TextView (); input.AcceptsTab = false; input.KeyReleaseEvent += delegate (object o, KeyReleaseEventArgs args) { if (args.Event.Key == Gdk.Key.Return || args.Event.Key == Gdk.Key.KP_Enter) { input.Buffer.Text = input.Buffer.Text.Trim (); OnParseUserQuery (null, EventArgs.Empty); } }; input.WrapMode = WrapMode.Word; sw.Add (input); input_box.PackStart (sw, true, true, 0); HBox button_box = new HBox (); Button parse = new Button ("Parse as User Query"); parse.Clicked += OnParseUserQuery; button_box.PackStart (parse, false, false, 0); input_box.PackStart (button_box, false, false, 0); HBox output_box = new HBox (); output_box.Spacing = 8; sw = new ScrolledWindow (); sw.ShadowType = ShadowType.In; sw.HscrollbarPolicy = PolicyType.Never; sql = new TextView (); sql.WrapMode = WrapMode.Word; sw.Add (sql); output_box.PackStart (sw, true, true, 0); sw = new ScrolledWindow (); sw.ShadowType = ShadowType.In; sw.HscrollbarPolicy = PolicyType.Never; xml = new TextView (); xml.WrapMode = WrapMode.Word; sw.Add (xml); output_box.PackStart (sw, true, true, 0); VPaned pane = new VPaned (); pane.Add1 (input_box); pane.Add2 (output_box); pane.Position = 100; Add (pane); pane.ShowAll (); input.HasFocus = true; LoadQueryFieldSet (); } private void LoadQueryFieldSet () { Assembly asm = Assembly.LoadFile ("Banshee.Services.dll"); Type t = asm.GetType ("Banshee.Query.BansheeQuery"); FieldInfo f = t.GetField ("FieldSet", BindingFlags.Public | BindingFlags.Static); query_field_set = (QueryFieldSet)f.GetValue (null); } private StreamReader StringToStream (string s) { return new StreamReader (new MemoryStream (System.Text.Encoding.UTF8.GetBytes (s))); } private void OnParseUserQuery (object o, EventArgs args) { UserQueryParser parser = new UserQueryParser (); parser.InputReader = StringToStream (input.Buffer.Text); QueryNode node = parser.BuildTree (query_field_set); sql.Buffer.Text = node.ToSql (query_field_set) ?? String.Empty; XmlDocument doc = new XmlDocument (); doc.LoadXml (node.ToXml (query_field_set)); MemoryStream s = new MemoryStream (); XmlTextWriter w = new XmlTextWriter (s, System.Text.Encoding.UTF8); w.Formatting = Formatting.Indented; doc.WriteContentTo (w); w.Flush (); s.Flush (); s.Position = 0; xml.Buffer.Text = new StreamReader (s).ReadToEnd (); } } } hyena-0.5/Hyena.Gui/Hyena.Query.Gui/RelativeTimeSpanQueryValueEntry.cs0000644000175000001440000000327211377105500026074 0ustar00gabeusers00000000000000// // RelativeTimeSpanQueryValueEntry.cs // // Authors: // Gabriel Burt // // Copyright (C) 2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using Mono.Unix; using Hyena.Query; using Gtk; namespace Hyena.Query.Gui { public class RelativeTimeSpanQueryValueEntry : TimeSpanQueryValueEntry { public RelativeTimeSpanQueryValueEntry () : base () { Add (new Label (Catalog.GetString ("ago"))); } protected override void HandleValueChanged (object o, EventArgs args) { query_value.SetRelativeValue (-spin_button.ValueAsInt, factors [combo.Active]); } } } hyena-0.5/Hyena.Gui/Hyena.Query.Gui/NullQueryValueEntry.cs0000644000175000001440000000312111377105500023563 0ustar00gabeusers00000000000000// // NullQueryValueEntry.cs // // Authors: // Gabriel Burt // // Copyright (C) 2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using Hyena.Query; using Gtk; namespace Hyena.Query.Gui { public class NullQueryValueEntry : QueryValueEntry { protected NullQueryValue query_value; public NullQueryValueEntry () : base () { } public override QueryValue QueryValue { get { return query_value; } set { query_value = value as NullQueryValue; } } } } hyena-0.5/Hyena.Gui/Hyena.Query.Gui/QueryBox.cs0000644000175000001440000001424211377105500021370 0ustar00gabeusers00000000000000// // QueryBox.cs // // Authors: // Aaron Bockover // Gabriel Burt // // Copyright (C) 2005-2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Collections.Generic; using System.Text; using Mono.Unix; using Gtk; using Hyena; using Hyena.Query; namespace Hyena.Query.Gui { public class QueryBox : VBox { private QueryTermsBox terms_box; private bool complex_query = false; private HBox terms_entry_box; private Entry terms_entry; private QueryLimitBox limit_box; public QueryLimitBox LimitBox { get { return limit_box; } } private ComboBox terms_logic_combo; private CheckButton terms_enabled_checkbox; private Label terms_label; private QueryFieldSet field_set; private Frame matchesFrame; public QueryBox (QueryFieldSet fieldSet, QueryOrder [] orders, QueryLimit [] limits) : base () { //this.sorted_fields = fieldSet.Fields; this.field_set = fieldSet; terms_box = new QueryTermsBox (field_set); limit_box = new QueryLimitBox (orders, limits); BuildInterface (); } private void BuildInterface () { NoShowAll = true; Alignment matchesAlignment = new Alignment (0.0f, 0.0f, 1.0f, 1.0f); matchesAlignment.SetPadding (5, 5, 5, 5); matchesAlignment.Add (terms_box); matchesFrame = new Frame (null); matchesFrame.Add (matchesAlignment); matchesFrame.LabelWidget = BuildMatchHeader (); matchesFrame.ShowAll (); terms_entry_box = new HBox (); terms_entry_box.Spacing = 8; terms_entry_box.PackStart (new Label (Catalog.GetString ("Condition:")), false, false, 0); terms_entry = new Entry (); terms_entry_box.PackStart (terms_entry, true, true, 0); limit_box.ShowAll (); PackStart(matchesFrame, true, true, 0); PackStart(terms_entry_box, false, false, 0); PackStart(limit_box, false, false, 0); //ShowAll (); } private HBox BuildMatchHeader () { HBox header = new HBox (); header.Show (); terms_enabled_checkbox = new CheckButton (Catalog.GetString ("_Match")); terms_enabled_checkbox.Show (); terms_enabled_checkbox.Active = true; terms_enabled_checkbox.Toggled += OnMatchCheckBoxToggled; header.PackStart (terms_enabled_checkbox, false, false, 0); terms_logic_combo = ComboBox.NewText (); terms_logic_combo.AppendText (Catalog.GetString ("all")); terms_logic_combo.AppendText (Catalog.GetString ("any")); terms_logic_combo.Show (); terms_logic_combo.Active = 0; header.PackStart (terms_logic_combo, false, false, 0); terms_label = new Label (Catalog.GetString ("of the following:")); terms_label.Show (); terms_label.Xalign = 0.0f; header.PackStart (terms_label, true, true, 0); header.Spacing = 5; return header; } private void OnMatchCheckBoxToggled (object o, EventArgs args) { terms_box.Sensitive = terms_enabled_checkbox.Active; terms_logic_combo.Sensitive = terms_enabled_checkbox.Active; terms_label.Sensitive = terms_enabled_checkbox.Active; } public QueryNode QueryNode { get { if (!complex_query && !terms_enabled_checkbox.Active) { return null; } if (complex_query) { return UserQueryParser.Parse (terms_entry.Text, field_set); } QueryListNode node = new QueryListNode (terms_logic_combo.Active == 0 ? Keyword.And : Keyword.Or); foreach (QueryNode child in terms_box.QueryNodes) { node.AddChild (child); } return node.Trim (); } set { if (value != null) { terms_enabled_checkbox.Active = true; try { if (value is QueryListNode) { terms_logic_combo.Active = ((value as QueryListNode).Keyword == Keyword.And) ? 0 : 1; terms_box.QueryNodes = (value as QueryListNode).Children; } else { List nodes = new List (); nodes.Add (value); terms_box.QueryNodes = nodes; } } catch (ArgumentException) { complex_query = true; matchesFrame.HideAll (); terms_entry.Text = value.ToUserQuery (); terms_entry_box.ShowAll (); } } else { terms_enabled_checkbox.Active = false; } } } } } hyena-0.5/Hyena.Gui/Hyena.Query.Gui/QueryTermsBox.cs0000644000175000001440000001342411377105500022404 0ustar00gabeusers00000000000000// // QueryTermsBox.cs // // Authors: // Aaron Bockover // Gabriel Burt // Alexander Kojevnikov // // Copyright (C) 2005-2008 Novell, Inc. // Copyright (C) 2009 Alexander Kojevnikov // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Text; using System.Collections.Generic; using System.Linq; using Gtk; using Hyena; using Hyena.Query; namespace Hyena.Query.Gui { public class QueryTermsBox : Table { private QueryField [] sorted_fields; private List terms = new List (); public QueryTermBox FirstRow { get { return terms.Count > 0 ? terms[0] : null; } } public QueryTermsBox (QueryFieldSet fieldSet) : base (1, 4, false) { // Sort the fields alphabetically by their label sorted_fields = fieldSet.OrderBy (f => f.Label).ToArray (); ColumnSpacing = 5; RowSpacing = 5; CreateRow (false); } public List QueryNodes { get { return terms.Select (t => t.QueryNode).ToList (); } set { ClearRows (); first_add_node = true; foreach (QueryNode child in value) { AddNode (child); } } } private bool first_add_node; protected void AddNode (QueryNode node) { if (node is QueryTermNode) { QueryTermBox box = first_add_node ? FirstRow : CreateRow (true); box.QueryNode = node as QueryTermNode; first_add_node = false; } else { throw new ArgumentException ("Query is too complex for GUI query editor", "node"); } } protected QueryTermBox CreateRow (bool canDelete) { QueryTermBox row = new QueryTermBox (sorted_fields); row.ValueEntry.HeightRequest = 31; row.Buttons.HeightRequest = 31; Resize ((uint) terms.Count + 1, NColumns); Attach (row.FieldChooser, 0, 1, NRows - 1, NRows); Attach (row.OpChooser, 1, 2, NRows - 1, NRows); Attach (row.ValueEntry, 2, 3, NRows - 1, NRows); Attach (row.Buttons, 3, 4, NRows - 1, NRows); if (terms.Count > 0) { row.FieldChooser.Active = terms[terms.Count - 1].FieldChooser.Active; row.OpChooser.Active = terms[terms.Count - 1].OpChooser.Active; } row.Show (); row.CanDelete = canDelete; row.AddRequest += OnRowAddRequest; row.RemoveRequest += OnRowRemoveRequest; if (terms.Count == 0) { //row.FieldBox.GrabFocus (); } terms.Add (row); return row; } protected void OnRowAddRequest (object o, EventArgs args) { CreateRow (true); UpdateCanDelete (); } protected void OnRowRemoveRequest (object o, EventArgs args) { RemoveRow (terms.IndexOf (o as QueryTermBox)); } private void ClearRows () { for (int index = terms.Count - 1; index > 0; index--) { RemoveRow (index); } } private void RemoveRow (int index) { FreezeChildNotify (); QueryTermBox row = terms [index]; Remove (row.FieldChooser); Remove (row.OpChooser); Remove (row.ValueEntry); Remove (row.Buttons); for (int i = index + 1; i < terms.Count; i++) { Remove (terms[i].FieldChooser); Remove (terms[i].OpChooser); Remove (terms[i].ValueEntry); Remove (terms[i].Buttons); Attach (terms[i].FieldChooser, 0, 1, (uint) i - 1, (uint) i); Attach (terms[i].OpChooser, 1, 2, (uint) i - 1, (uint) i); Attach (terms[i].ValueEntry, 2, 3, (uint) i - 1, (uint) i); Attach (terms[i].Buttons, 3, 4, (uint) i - 1, (uint) i); } ThawChildNotify (); terms.Remove (row); UpdateCanDelete (); } protected void UpdateCanDelete () { if (FirstRow != null) { FirstRow.CanDelete = terms.Count > 1; } } private new void Attach (Widget widget, uint left_attach, uint right_attach, uint top_attach, uint bottom_attach) { Attach (widget, left_attach, right_attach, top_attach, bottom_attach, AttachOptions.Expand | AttachOptions.Fill, AttachOptions.Shrink, 0, 0); } } } hyena-0.5/Hyena.Gui/Hyena.Query.Gui/IntegerQueryValueEntry.cs0000644000175000001440000000464511377105500024262 0ustar00gabeusers00000000000000// // IntegerQueryValueEntry.cs // // Authors: // Gabriel Burt // // Copyright (C) 2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using Hyena.Query; using Gtk; namespace Hyena.Query.Gui { public class IntegerQueryValueEntry : QueryValueEntry { protected SpinButton spin_button; protected IntegerQueryValue query_value; public IntegerQueryValueEntry () : base () { spin_button = new SpinButton (0.0, 1.0, 1.0); spin_button.Digits = 0; spin_button.WidthChars = 4; spin_button.ValueChanged += HandleValueChanged; Add (spin_button); } public override QueryValue QueryValue { get { return query_value; } set { spin_button.ValueChanged -= HandleValueChanged; query_value = value as IntegerQueryValue; spin_button.SetRange (query_value.MinValue, query_value.MaxValue); spin_button.Value = (double) (query_value.IsEmpty ? query_value.DefaultValue : query_value.IntValue); query_value.SetValue (spin_button.ValueAsInt); spin_button.ValueChanged += HandleValueChanged; } } protected void HandleValueChanged (object o, EventArgs args) { query_value.SetValue (spin_button.ValueAsInt); } } } hyena-0.5/Hyena.Gui/Hyena.Query.Gui/QueryValueEntry.cs0000644000175000001440000000704611377105500022742 0ustar00gabeusers00000000000000// // QueryValueEntry.cs // // Authors: // Gabriel Burt // // Copyright (C) 2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Collections.Generic; using Hyena.Query; using Gtk; namespace Hyena.Query.Gui { public abstract class QueryValueEntry : HBox { private static Dictionary types = new Dictionary (); protected int DefaultWidth { get { return 170; } } public QueryValueEntry () : base () { Spacing = 5; } public abstract QueryValue QueryValue { get; set; } public static QueryValueEntry Create (QueryValue qv) { Type qv_type = qv.GetType (); Type entry_type = null; foreach (KeyValuePair pair in types) { if (pair.Value == qv_type) { entry_type = pair.Key; break; } } // If we don't have an entry type that's exactly for our type, take a more generic one if (entry_type == null) { foreach (KeyValuePair pair in types) { if (qv_type.IsSubclassOf (pair.Value)) { entry_type = pair.Key; break; } } } if (entry_type != null) { QueryValueEntry entry = Activator.CreateInstance (entry_type) as QueryValueEntry; entry.QueryValue = qv; return entry; } return null; } public static void AddSubType (Type entry_type, Type query_value_type) { types[entry_type] = query_value_type; } public static Type GetValueType (QueryValueEntry entry) { return types [entry.GetType ()]; } static QueryValueEntry () { AddSubType (typeof(StringQueryValueEntry), typeof(StringQueryValue)); AddSubType (typeof(IntegerQueryValueEntry), typeof(IntegerQueryValue)); AddSubType (typeof(DateQueryValueEntry), typeof(DateQueryValue)); AddSubType (typeof(FileSizeQueryValueEntry), typeof(FileSizeQueryValue)); AddSubType (typeof(TimeSpanQueryValueEntry), typeof(TimeSpanQueryValue)); AddSubType (typeof(RelativeTimeSpanQueryValueEntry), typeof(RelativeTimeSpanQueryValue)); AddSubType (typeof(NullQueryValueEntry), typeof(NullQueryValue)); } } } hyena-0.5/Hyena.Gui/Hyena.Query.Gui/StringQueryValueEntry.cs0000644000175000001440000000414611377105500024127 0ustar00gabeusers00000000000000// // StringQueryValueEntry.cs // // Authors: // Gabriel Burt // // Copyright (C) 2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using Hyena.Query; using Gtk; namespace Hyena.Query.Gui { public class StringQueryValueEntry : QueryValueEntry { protected Gtk.Entry entry; protected StringQueryValue query_value; public StringQueryValueEntry () : base () { entry = new Entry (); entry.WidthRequest = DefaultWidth; entry.Changed += HandleChanged; Add (entry); } public override QueryValue QueryValue { get { return query_value; } set { entry.Changed -= HandleChanged; query_value = value as StringQueryValue; entry.Text = (query_value.Value as string) ?? String.Empty; entry.Changed += HandleChanged; } } protected void HandleChanged (object o, EventArgs args) { query_value.ParseUserQuery (entry.Text); } } } hyena-0.5/Hyena.Gui/Hyena.Query.Gui/QueryLimitBox.cs0000644000175000001440000001131211377105500022362 0ustar00gabeusers00000000000000// // QueryLimitBox.cs // // Authors: // Aaron Bockover // Gabriel Burt // // Copyright (C) 2005-2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Text; using Mono.Unix; using Gtk; using Hyena; using Hyena.Query; namespace Hyena.Query.Gui { public class QueryLimitBox : HBox { private CheckButton enabled_checkbox; private SpinButton count_spin; private ComboBox limit_combo; private ComboBox order_combo; private QueryOrder [] orders; private QueryLimit [] limits; public QueryLimitBox (QueryOrder [] orders, QueryLimit [] limits) : base () { this.orders = orders; this.limits = limits; Spacing = 5; enabled_checkbox = new CheckButton (Catalog.GetString ("_Limit to")); enabled_checkbox.Toggled += OnEnabledToggled; count_spin = new SpinButton (0, Double.MaxValue, 1); count_spin.Numeric = true; count_spin.Digits = 0; count_spin.Value = 25; count_spin.SetSizeRequest (60, -1); limit_combo = ComboBox.NewText (); foreach (QueryLimit limit in limits) { limit_combo.AppendText (limit.Label); } order_combo = ComboBox.NewText (); order_combo.RowSeparatorFunc = IsRowSeparator; foreach (QueryOrder order in orders) { if (order == null) { order_combo.AppendText (String.Empty); } else { order_combo.AppendText (order.Label); } } PackStart (enabled_checkbox, false, false, 0); PackStart (count_spin, false, false, 0); PackStart (limit_combo, false, false, 0); PackStart (new Label (Catalog.GetString ("selected by")), false, false, 0); PackStart (order_combo, false, false, 0); enabled_checkbox.Active = false; limit_combo.Active = 0; order_combo.Active = 0; OnEnabledToggled (null, null); ShowAll (); } private bool IsRowSeparator (TreeModel model, TreeIter iter) { return String.IsNullOrEmpty (model.GetValue (iter, 0) as string); } public QueryLimit Limit { get { return Enabled ? limits [limit_combo.Active] : null; } set { if (value != null) limit_combo.Active = Array.IndexOf (limits, value); } } public IntegerQueryValue LimitValue { get { if (!Enabled) return null; IntegerQueryValue val = new IntegerQueryValue (); val.SetValue (count_spin.ValueAsInt); return val; } set { if (value != null && !value.IsEmpty) count_spin.Value = value.IntValue; } } public QueryOrder Order { get { return Enabled ? orders [order_combo.Active] : null; } set { if (value != null) { order_combo.Active = Array.IndexOf (orders, value); } } } private void OnEnabledToggled (object o, EventArgs args) { count_spin.Sensitive = enabled_checkbox.Active; limit_combo.Sensitive = enabled_checkbox.Active; order_combo.Sensitive = enabled_checkbox.Active; } public bool Enabled { get { return enabled_checkbox.Active; } set { enabled_checkbox.Active = value; } } } } hyena-0.5/Hyena.Gui/Hyena.Query.Gui/QueryTermBox.cs0000644000175000001440000002071711377105500022224 0ustar00gabeusers00000000000000// // QueryTermBox.cs // // Authors: // Aaron Bockover // Gabriel Burt // // Copyright (C) 2005-2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Text; using System.Collections.Generic; using Gtk; using Hyena; using Hyena.Query; namespace Hyena.Query.Gui { public class QueryTermBox { private Button add_button; private Button remove_button; public event EventHandler AddRequest; public event EventHandler RemoveRequest; private QueryField field; private List value_entries = new List (); private List operators = new List (); private Dictionary operator_entries = new Dictionary (); private QueryValueEntry current_value_entry; private Operator op; private QueryField [] sorted_fields; private ComboBox field_chooser; public ComboBox FieldChooser { get { return field_chooser; } } private ComboBox op_chooser; public ComboBox OpChooser { get { return op_chooser; } } private HBox value_box; public HBox ValueEntry { get { return value_box; } } private HBox button_box; public HBox Buttons { get { return button_box; } } public QueryTermBox (QueryField [] sorted_fields) : base () { this.sorted_fields = sorted_fields; BuildInterface (); } private void BuildInterface () { field_chooser = ComboBox.NewText (); field_chooser.Changed += HandleFieldChanged; op_chooser = ComboBox.NewText (); op_chooser.RowSeparatorFunc = IsRowSeparator; op_chooser.Changed += HandleOperatorChanged; value_box = new HBox (); remove_button = new Button (new Image ("gtk-remove", IconSize.Button)); remove_button.Relief = ReliefStyle.None; remove_button.Clicked += OnButtonRemoveClicked; add_button = new Button (new Image ("gtk-add", IconSize.Button)); add_button.Relief = ReliefStyle.None; add_button.Clicked += OnButtonAddClicked; button_box = new HBox (); button_box.PackStart (remove_button, false, false, 0); button_box.PackStart (add_button, false, false, 0); foreach (QueryField field in sorted_fields) { field_chooser.AppendText (field.Label); } Show (); field_chooser.Active = 0; } private bool IsRowSeparator (TreeModel model, TreeIter iter) { return String.IsNullOrEmpty (model.GetValue (iter, 0) as string); } public void Show () { field_chooser.ShowAll (); op_chooser.ShowAll (); value_box.ShowAll (); button_box.ShowAll (); } private bool first = true; private void SetValueEntry (QueryValueEntry entry) { if (first) { first = false; } else { value_box.Remove (value_box.Children [0]); } current_value_entry = entry; value_box.PackStart (current_value_entry, false, true, 0); current_value_entry.ShowAll (); } private void HandleFieldChanged (object o, EventArgs args) { if (field_chooser.Active < 0 || field_chooser.Active >= sorted_fields.Length) return; QueryField field = sorted_fields [field_chooser.Active]; // Leave everything as is unless the new field is a different type if (this.field != null && (field.ValueTypes.Length == 1 && this.field.ValueTypes.Length == 1 && field.ValueTypes[0] == this.field.ValueTypes[0])) { this.field = field; return; } op_chooser.Changed -= HandleOperatorChanged; this.field = field; // Remove old type's operators while (op_chooser.Model.IterNChildren () > 0) { op_chooser.RemoveText (0); } // Add new field's operators int val_count = 0; value_entries.Clear (); operators.Clear (); operator_entries.Clear (); foreach (QueryValue val in this.field.CreateQueryValues ()) { QueryValueEntry entry = QueryValueEntry.Create (val); value_entries.Add (entry); if (val_count++ > 0) { op_chooser.AppendText (String.Empty); operators.Add (null); } foreach (Operator op in val.OperatorSet) { op_chooser.AppendText (op.Label); operators.Add (op); operator_entries [op] = entry; } } SetValueEntry (value_entries[0]); // TODO: If we have the same operator that was previously selected, select it op_chooser.Changed += HandleOperatorChanged; op_chooser.Active = 0; } private void HandleOperatorChanged (object o, EventArgs args) { if (op_chooser.Active < 0 || op_chooser.Active >= operators.Count) { return; } this.op = operators [op_chooser.Active]; if (operator_entries [this.op] != current_value_entry) { SetValueEntry (operator_entries [this.op]); } //value_entry = new QueryValueEntry (); } private void OnButtonAddClicked (object o, EventArgs args) { EventHandler handler = AddRequest; if (handler != null) handler (this, new EventArgs ()); } private void OnButtonRemoveClicked (object o, EventArgs args) { EventHandler handler = RemoveRequest; if (handler != null) handler (this, new EventArgs ()); } public bool CanDelete { get { return remove_button.Sensitive; } set { remove_button.Sensitive = value; } } public QueryTermNode QueryNode { get { QueryTermNode node = new QueryTermNode (); node.Field = field; node.Operator = op; node.Value = current_value_entry.QueryValue; return node; } set { QueryTermNode node = value; if (node == null) { return; } field_chooser.Active = Array.IndexOf (sorted_fields, node.Field); op_chooser.Active = operators.IndexOf (node.Operator); current_value_entry.QueryValue = node.Value; /*foreach (QueryValueEntry entry in value_entries) { if (QueryValueEntry.GetValueType (entry) == node.Value.GetType ()) { Console.WriteLine ("In QueryTermBox, setting QueryNode, got matching value types, value is {0}, empty? {1}", node.Value.ToString (), node.Value.IsEmpty); entry.QueryValue = node.Value; SetValueEntry (entry); break; } }*/ } } } } hyena-0.5/Hyena.Gui/Hyena.Gui/0000777000175000001440000000000011453151003016152 5ustar00gabeusers00000000000000hyena-0.5/Hyena.Gui/Hyena.Gui/CleanRoomStartup.cs0000644000175000001440000000431611377105500021751 0ustar00gabeusers00000000000000// // CleanRoomStartup.cs // // Author: // Aaron Bockover // // Copyright (C) 2006-2007 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; namespace Hyena.Gui { public static class CleanRoomStartup { public delegate void StartupInvocationHandler(); public static void Startup(StartupInvocationHandler startup) { bool disable_clean_room = false; foreach(string arg in Environment.GetCommandLineArgs ()) { if(arg == "--disable-clean-room") { disable_clean_room = true; break; } } if(disable_clean_room) { startup(); return; } try { startup(); } catch(Exception e) { Console.WriteLine(e.Message); Console.WriteLine(e); Gtk.Application.Init(); Hyena.Gui.Dialogs.ExceptionDialog dialog = new Hyena.Gui.Dialogs.ExceptionDialog(e); dialog.Run(); dialog.Destroy(); System.Environment.Exit(1); } } } } hyena-0.5/Hyena.Gui/Hyena.Gui/CairoDamageDebugger.cs0000644000175000001440000000406011377105500022304 0ustar00gabeusers00000000000000// // CairoDamageDebugger.cs // // Author: // Aaron Bockover // // Copyright 2010 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using Cairo; namespace Hyena.Gui { public static class CairoDamageDebugger { private static Random rand = new Random (); public static void RenderDamage (this Context cr, Gdk.Rectangle damage) { RenderDamage (cr, damage.X, damage.Y, damage.Width, damage.Height); } public static void RenderDamage (this Context cr, Cairo.Rectangle damage) { RenderDamage (cr, damage.X, damage.Y, damage.Width, damage.Height); } public static void RenderDamage (this Context cr, double x, double y, double w, double h) { cr.Save (); cr.LineWidth = 1.0; cr.Color = CairoExtensions.RgbToColor ((uint)rand.Next (0, 0xffffff)); cr.Rectangle (x + 0.5, y + 0.5, w - 1, h - 1); cr.Stroke (); cr.Restore (); } } } hyena-0.5/Hyena.Gui/Hyena.Gui/EditableEraseAction.cs0000644000175000001440000000665011377105500022341 0ustar00gabeusers00000000000000// // EditableEraseAction.cs // // Author: // Aaron Bockover // // Copyright (C) 2007-2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using Gtk; using Hyena; namespace Hyena.Gui { internal class EditableEraseAction : IUndoAction { private Editable editable; private string text; private int start; private int end; private bool is_forward; private bool is_cut; public EditableEraseAction (Editable editable, int start, int end) { this.editable = editable; this.text = editable.GetChars (start, end); this.start = start; this.end = end; this.is_cut = end - start > 1; this.is_forward = editable.Position < start; } public void Undo () { int start_r = start; editable.InsertText (text, ref start_r); editable.Position = is_forward ? start_r : end; } public void Redo () { editable.DeleteText (start, end); editable.Position = start; } public void Merge (IUndoAction action) { EditableEraseAction erase = (EditableEraseAction)action; if (start == erase.start) { text += erase.text; end += erase.end - erase.start; } else { text = erase.text + text; start = erase.start; } } public bool CanMerge (IUndoAction action) { EditableEraseAction erase = action as EditableEraseAction; if (erase == null) { return false; } return !( is_cut || erase.is_cut || // don't group separate text cuts start != (is_forward ? erase.start : erase.end) || // must meet eachother is_forward != erase.is_forward || // don't group deletes with backspaces text[0] == '\n' || // don't group more than one line (inclusive) erase.text[0] == ' ' || erase.text[0] == '\t' // don't group more than one word (exclusive) ); } public override string ToString () { return String.Format ("Erased: [{0}] ({1},{2})", text, start, end); } } } hyena-0.5/Hyena.Gui/Hyena.Gui/DragDropList.cs0000644000175000001440000000550211377105500021043 0ustar00gabeusers00000000000000// // DragDropList.cs // // Author: // Aaron Bockover // // Copyright (C) 2005-2007 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Text; using System.Collections; using System.Collections.Generic; using System.Runtime.InteropServices; using Gtk; namespace Hyena.Gui { public class DragDropList : List { public DragDropList() : base() { } public DragDropList(T o) : base() { Add(o); } public DragDropList(T o, Gtk.SelectionData selectionData, Gdk.Atom target) : base() { Add(o); AssignToSelection(selectionData, target); } public void AssignToSelection(Gtk.SelectionData selectionData, Gdk.Atom target) { byte [] data = this; selectionData.Set(target, 8, data, data.Length); } public static implicit operator byte [](DragDropList transferrable) { IntPtr handle = (IntPtr)GCHandle.Alloc(transferrable); return System.Text.Encoding.ASCII.GetBytes(Convert.ToString(handle)); } public static implicit operator DragDropList(byte [] transferrable) { try { string str_handle = System.Text.Encoding.ASCII.GetString(transferrable); IntPtr handle_ptr = (IntPtr)Convert.ToInt64(str_handle); GCHandle handle = (GCHandle)handle_ptr; DragDropList o = (DragDropList)handle.Target; handle.Free(); return o; } catch { return null; } } public static implicit operator DragDropList(Gtk.SelectionData transferrable) { return transferrable.Data; } } } hyena-0.5/Hyena.Gui/Hyena.Gui/GtkWorkarounds.cs0000644000175000001440000000650411377105500021474 0ustar00gabeusers00000000000000// // GtkWorkarounds.cs // // Author: // Aaron Bockover // // Copyright (C) 2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Reflection; namespace Hyena.Gui { public static class GtkWorkarounds { private static bool toggle_ref_supported; private static MethodInfo g_object_ref; private static MethodInfo gdk_window_destroy; private static object [] invoke_args; static GtkWorkarounds () { if (!(toggle_ref_supported = Assembly.GetAssembly (typeof (GLib.Object)).GetType ( "GLib.ToggleRef") != null)) { return; } // Find the P/Invoke signatures we need so we can avoid a dllmap g_object_ref = typeof (GLib.Object).GetMethod ("g_object_ref", BindingFlags.NonPublic | BindingFlags.Static); gdk_window_destroy = typeof (Gdk.Window).GetMethod ("gdk_window_destroy", BindingFlags.NonPublic | BindingFlags.Static); } public static void WindowDestroy (Gdk.Window window) { // There is a bug in GDK, and subsequently in Gdk# 2.8.5 through 2.12.1 // where the managed Gdk.Window.Destroy function does not obtain a // normal reference (non-toggle) on the GdkWindow before calling // _destroy on it, which the native function apparently expects. // https://bugzilla.novell.com/show_bug.cgi?id=382186 // http://anonsvn.mono-project.com/viewcvs/trunk/gtk-sharp/gdk/Window.custom?rev=101734&r1=42529&r2=101734 if (window == null) { return; } if (!toggle_ref_supported) { window.Destroy (); return; } // If this ever happens I will move out west and start farming... if (g_object_ref == null || gdk_window_destroy == null) { window.Destroy (); return; } if (invoke_args == null) { invoke_args = new object[1]; } invoke_args[0] = window.Handle; g_object_ref.Invoke (null, invoke_args); gdk_window_destroy.Invoke (null, invoke_args); window.Dispose (); } } } hyena-0.5/Hyena.Gui/Hyena.Gui/TestModuleAttribute.cs0000644000175000001440000000300711377105500022454 0ustar00gabeusers00000000000000// // TestModuleAttribute.cs // // Author: // Aaron Bockover // // Copyright (C) 2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; namespace Hyena.Gui { internal class TestModuleAttribute : Attribute { private string name; public string Name { get { return name; } set { name = value; } } public TestModuleAttribute (string name) { this.name = name; } } } hyena-0.5/Hyena.Gui/Hyena.Gui/HyenaActionGroup.cs0000644000175000001440000001323211436010340021714 0ustar00gabeusers00000000000000// // HyenaActionGroup.cs // // Author: // Gabriel Burt // // Copyright (C) 2007 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Collections.Generic; using Gtk; namespace Hyena.Gui { public class HyenaActionGroup : ActionGroup { private List ui_merge_ids = new List (); private ActionManager action_manager; private bool important_by_default = true; protected bool ImportantByDefault { get { return important_by_default; } set { important_by_default = value; } } public HyenaActionGroup (ActionManager action_manager, string name) : base (name) { this.action_manager = action_manager; } public void AddUiFromFile (string ui_file) { Hyena.ThreadAssist.AssertInMainThread (); ui_merge_ids.Add (ActionManager.AddUiFromFile (ui_file, System.Reflection.Assembly.GetCallingAssembly ())); } public void AddUiFromString (string ui_string) { Hyena.ThreadAssist.AssertInMainThread (); ui_merge_ids.Add (ActionManager.UIManager.AddUiFromString (ui_string)); } public void Register () { if (ActionManager.FindActionGroup (this.Name) == null) { ActionManager.AddActionGroup (this); } } public void UnRegister () { if (ActionManager.FindActionGroup (this.Name) != null) { ActionManager.RemoveActionGroup (this); } } public override void Dispose () { Hyena.ThreadAssist.ProxyToMain (delegate { UnRegister (); foreach (uint merge_id in ui_merge_ids) { if (merge_id > 0) { ActionManager.UIManager.RemoveUi (merge_id); } } ui_merge_ids.Clear (); base.Dispose (); }); } public new void Add (params ActionEntry [] action_entries) { if (ImportantByDefault) { AddImportant (action_entries); } else { base.Add (action_entries); } } public void AddImportant (params ActionEntry [] action_entries) { base.Add (action_entries); foreach (ActionEntry entry in action_entries) { this[entry.name].IsImportant = true; } } public void AddImportant (params ToggleActionEntry [] action_entries) { base.Add (action_entries); foreach (ToggleActionEntry entry in action_entries) { this[entry.name].IsImportant = true; } } public void Remove (string actionName) { Gtk.Action action = this[actionName]; if (action != null) { Remove (action); } } public void UpdateActions (bool visible, bool sensitive, params string [] action_names) { foreach (string name in action_names) { UpdateAction (this[name], visible, sensitive); } } public void UpdateAction (string action_name, bool visible_and_sensitive) { UpdateAction (this[action_name], visible_and_sensitive, visible_and_sensitive); } public void UpdateAction (string action_name, bool visible, bool sensitive) { UpdateAction (this[action_name], visible, sensitive); } public static void UpdateAction (Gtk.Action action, bool visible_and_sensitive) { UpdateAction (action, visible_and_sensitive, visible_and_sensitive); } public static void UpdateAction (Gtk.Action action, bool visible, bool sensitive) { action.Visible = visible; action.Sensitive = visible && sensitive; } protected void ShowContextMenu (string menu_name) { Gtk.Menu menu = ActionManager.UIManager.GetWidget (menu_name) as Menu; if (menu == null || menu.Children.Length == 0) { return; } int visible_children = 0; foreach (Widget child in menu) if (child.Visible) visible_children++; if (visible_children == 0) { return; } menu.Show (); menu.Popup (null, null, null, 0, Gtk.Global.CurrentEventTime); } public ActionManager ActionManager { get { return action_manager; } } } } hyena-0.5/Hyena.Gui/Hyena.Gui/CairoExtensions.cs0000644000175000001440000003247211377105500021630 0ustar00gabeusers00000000000000// // CairoExtensions.cs // // Author: // Aaron Bockover // // Copyright (C) 2007 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Reflection; using System.Runtime.InteropServices; using Gdk; using Cairo; namespace Hyena.Gui { [Flags] public enum CairoCorners { None = 0, TopLeft = 1, TopRight = 2, BottomLeft = 4, BottomRight = 8, All = 15 } public static class CairoExtensions { public static Pango.Layout CreateLayout (Gtk.Widget widget, Cairo.Context cairo_context) { Pango.Layout layout = PangoCairoHelper.CreateLayout (cairo_context); layout.FontDescription = widget.PangoContext.FontDescription; double resolution = widget.Screen.Resolution; if (resolution != -1) { Pango.Context context = PangoCairoHelper.LayoutGetContext (layout); PangoCairoHelper.ContextSetResolution (context, resolution); context.Dispose (); } Log.Debug ("Creating Pango.Layout, configuring Cairo.Context"); return layout; } public static Surface CreateSurfaceForPixbuf (Cairo.Context cr, Gdk.Pixbuf pixbuf) { Surface surface = cr.Target.CreateSimilar (cr.Target.Content, pixbuf.Width, pixbuf.Height); Cairo.Context surface_cr = new Context (surface); Gdk.CairoHelper.SetSourcePixbuf (surface_cr, pixbuf, 0, 0); surface_cr.Paint (); ((IDisposable)surface_cr).Dispose (); return surface; } public static Cairo.Color AlphaBlend (Cairo.Color ca, Cairo.Color cb, double alpha) { return new Cairo.Color ( (1.0 - alpha) * ca.R + alpha * cb.R, (1.0 - alpha) * ca.G + alpha * cb.G, (1.0 - alpha) * ca.B + alpha * cb.B); } public static Cairo.Color GdkColorToCairoColor(Gdk.Color color) { return GdkColorToCairoColor(color, 1.0); } public static Cairo.Color GdkColorToCairoColor(Gdk.Color color, double alpha) { return new Cairo.Color( (double)(color.Red >> 8) / 255.0, (double)(color.Green >> 8) / 255.0, (double)(color.Blue >> 8) / 255.0, alpha); } public static Cairo.Color RgbToColor (uint rgbColor) { return RgbaToColor ((rgbColor << 8) | 0x000000ff); } public static Cairo.Color RgbaToColor (uint rgbaColor) { return new Cairo.Color ( (byte)(rgbaColor >> 24) / 255.0, (byte)(rgbaColor >> 16) / 255.0, (byte)(rgbaColor >> 8) / 255.0, (byte)(rgbaColor & 0x000000ff) / 255.0); } public static bool ColorIsDark (Cairo.Color color) { double h, s, b; HsbFromColor (color, out h, out s, out b); return b < 0.5; } public static void HsbFromColor(Cairo.Color color, out double hue, out double saturation, out double brightness) { double min, max, delta; double red = color.R; double green = color.G; double blue = color.B; hue = 0; saturation = 0; brightness = 0; if(red > green) { max = Math.Max(red, blue); min = Math.Min(green, blue); } else { max = Math.Max(green, blue); min = Math.Min(red, blue); } brightness = (max + min) / 2; if(Math.Abs(max - min) < 0.0001) { hue = 0; saturation = 0; } else { saturation = brightness <= 0.5 ? (max - min) / (max + min) : (max - min) / (2 - max - min); delta = max - min; if(red == max) { hue = (green - blue) / delta; } else if(green == max) { hue = 2 + (blue - red) / delta; } else if(blue == max) { hue = 4 + (red - green) / delta; } hue *= 60; if(hue < 0) { hue += 360; } } } private static double Modula(double number, double divisor) { return ((int)number % divisor) + (number - (int)number); } public static Cairo.Color ColorFromHsb(double hue, double saturation, double brightness) { int i; double [] hue_shift = { 0, 0, 0 }; double [] color_shift = { 0, 0, 0 }; double m1, m2, m3; m2 = brightness <= 0.5 ? brightness * (1 + saturation) : brightness + saturation - brightness * saturation; m1 = 2 * brightness - m2; hue_shift[0] = hue + 120; hue_shift[1] = hue; hue_shift[2] = hue - 120; color_shift[0] = color_shift[1] = color_shift[2] = brightness; i = saturation == 0 ? 3 : 0; for(; i < 3; i++) { m3 = hue_shift[i]; if(m3 > 360) { m3 = Modula(m3, 360); } else if(m3 < 0) { m3 = 360 - Modula(Math.Abs(m3), 360); } if(m3 < 60) { color_shift[i] = m1 + (m2 - m1) * m3 / 60; } else if(m3 < 180) { color_shift[i] = m2; } else if(m3 < 240) { color_shift[i] = m1 + (m2 - m1) * (240 - m3) / 60; } else { color_shift[i] = m1; } } return new Cairo.Color(color_shift[0], color_shift[1], color_shift[2]); } public static Cairo.Color ColorShade (Cairo.Color @base, double ratio) { double h, s, b; HsbFromColor (@base, out h, out s, out b); b = Math.Max (Math.Min (b * ratio, 1), 0); s = Math.Max (Math.Min (s * ratio, 1), 0); Cairo.Color color = ColorFromHsb (h, s, b); color.A = @base.A; return color; } public static Cairo.Color ColorAdjustBrightness(Cairo.Color @base, double br) { double h, s, b; HsbFromColor(@base, out h, out s, out b); b = Math.Max(Math.Min(br, 1), 0); return ColorFromHsb(h, s, b); } public static string ColorGetHex (Cairo.Color color, bool withAlpha) { if (withAlpha) { return String.Format("#{0:x2}{1:x2}{2:x2}{3:x2}", (byte)(color.R * 255), (byte)(color.G * 255), (byte)(color.B * 255), (byte)(color.A * 255)); } else { return String.Format("#{0:x2}{1:x2}{2:x2}", (byte)(color.R * 255), (byte)(color.G * 255), (byte)(color.B * 255)); } } public static void RoundedRectangle(Cairo.Context cr, double x, double y, double w, double h, double r) { RoundedRectangle(cr, x, y, w, h, r, CairoCorners.All, false); } public static void RoundedRectangle(Cairo.Context cr, double x, double y, double w, double h, double r, CairoCorners corners) { RoundedRectangle(cr, x, y, w, h, r, corners, false); } public static void RoundedRectangle(Cairo.Context cr, double x, double y, double w, double h, double r, CairoCorners corners, bool topBottomFallsThrough) { if(topBottomFallsThrough && corners == CairoCorners.None) { cr.MoveTo(x, y - r); cr.LineTo(x, y + h + r); cr.MoveTo(x + w, y - r); cr.LineTo(x + w, y + h + r); return; } else if(r < 0.0001 || corners == CairoCorners.None) { cr.Rectangle(x, y, w, h); return; } if((corners & (CairoCorners.TopLeft | CairoCorners.TopRight)) == 0 && topBottomFallsThrough) { y -= r; h += r; cr.MoveTo(x + w, y); } else { if((corners & CairoCorners.TopLeft) != 0) { cr.MoveTo(x + r, y); } else { cr.MoveTo(x, y); } if((corners & CairoCorners.TopRight) != 0) { cr.Arc(x + w - r, y + r, r, Math.PI * 1.5, Math.PI * 2); } else { cr.LineTo(x + w, y); } } if((corners & (CairoCorners.BottomLeft | CairoCorners.BottomRight)) == 0 && topBottomFallsThrough) { h += r; cr.LineTo(x + w, y + h); cr.MoveTo(x, y + h); cr.LineTo(x, y + r); cr.Arc(x + r, y + r, r, Math.PI, Math.PI * 1.5); } else { if((corners & CairoCorners.BottomRight) != 0) { cr.Arc(x + w - r, y + h - r, r, 0, Math.PI * 0.5); } else { cr.LineTo(x + w, y + h); } if((corners & CairoCorners.BottomLeft) != 0) { cr.Arc(x + r, y + h - r, r, Math.PI * 0.5, Math.PI); } else { cr.LineTo(x, y + h); } if((corners & CairoCorners.TopLeft) != 0) { cr.Arc(x + r, y + r, r, Math.PI, Math.PI * 1.5); } else { cr.LineTo(x, y); } } } public static void DisposeContext (Cairo.Context cr) { ((IDisposable)cr.Target).Dispose (); ((IDisposable)cr).Dispose (); } private struct CairoInteropCall { public string Name; public MethodInfo ManagedMethod; public bool CallNative; public CairoInteropCall (string name) { Name = name; ManagedMethod = null; CallNative = false; } } private static bool CallCairoMethod (Cairo.Context cr, ref CairoInteropCall call) { if (call.ManagedMethod == null && !call.CallNative) { MemberInfo [] members = typeof (Cairo.Context).GetMember (call.Name, MemberTypes.Method, BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.Public); if (members != null && members.Length > 0 && members[0] is MethodInfo) { call.ManagedMethod = (MethodInfo)members[0]; } else { call.CallNative = true; } } if (call.ManagedMethod != null) { call.ManagedMethod.Invoke (cr, null); return true; } return false; } private static bool native_push_pop_exists = true; [DllImport ("libcairo-2.dll")] private static extern void cairo_push_group (IntPtr ptr); private static CairoInteropCall cairo_push_group_call = new CairoInteropCall ("PushGroup"); public static void PushGroup (Cairo.Context cr) { if (!native_push_pop_exists) { return; } try { if (!CallCairoMethod (cr, ref cairo_push_group_call)) { cairo_push_group (cr.Handle); } } catch { native_push_pop_exists = false; } } [DllImport ("libcairo-2.dll")] private static extern void cairo_pop_group_to_source (IntPtr ptr); private static CairoInteropCall cairo_pop_group_to_source_call = new CairoInteropCall ("PopGroupToSource"); public static void PopGroupToSource (Cairo.Context cr) { if (!native_push_pop_exists) { return; } try { if (!CallCairoMethod (cr, ref cairo_pop_group_to_source_call)) { cairo_pop_group_to_source (cr.Handle); } } catch (EntryPointNotFoundException) { native_push_pop_exists = false; } } } } hyena-0.5/Hyena.Gui/Hyena.Gui/ActionManager.cs0000644000175000001440000001357011452674367021241 0ustar00gabeusers00000000000000// // ActionManager.cs // // Author: // Aaron Bockover // // Copyright (C) 2006-2007 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.IO; using System.Reflection; using System.Collections.Generic; using Gtk; using Action = Gtk.Action; using Hyena; namespace Hyena.Gui { public class ActionManager { private UIManager ui_manager; private Dictionary action_groups = new Dictionary (); public ActionManager () { ui_manager = new UIManager (); } public virtual void Initialize () { } private void InnerAddActionGroup (ActionGroup group) { action_groups.Add (group.Name, group); ui_manager.InsertActionGroup (group, 0); } public void AddActionGroup (string name) { lock (this) { if (action_groups.ContainsKey (name)) { throw new ApplicationException ("Group already exists"); } InnerAddActionGroup (new ActionGroup (name)); } } public void AddActionGroup (ActionGroup group) { lock (this) { if (action_groups.ContainsKey (group.Name)) { throw new ApplicationException ("Group already exists"); } InnerAddActionGroup (group); } } public void RemoveActionGroup (string name) { lock (this) { if (action_groups.ContainsKey (name)) { ActionGroup group = action_groups[name]; ui_manager.RemoveActionGroup (group); action_groups.Remove (name); } } } public void RemoveActionGroup (ActionGroup group) { RemoveActionGroup (group.Name); } public ActionGroup FindActionGroup (string actionGroupId) { foreach (ActionGroup group in action_groups.Values) { if (group.Name == actionGroupId) { return group; } } return null; } public Gtk.Action FindAction (string actionId) { string [] parts = actionId.Split ('.'); if (parts == null || parts.Length < 2) { return null; } string group_name = parts[0]; string action_name = parts[1]; ActionGroup group = FindActionGroup (group_name); return group == null ? null : group.GetAction (action_name); } public void PopulateToolbarPlaceholder (Toolbar toolbar, string path, Widget item) { PopulateToolbarPlaceholder (toolbar, path, item, false); } public void PopulateToolbarPlaceholder (Toolbar toolbar, string path, Widget item, bool expand) { ToolItem placeholder = (ToolItem)UIManager.GetWidget (path); int position = toolbar.GetItemIndex (placeholder); toolbar.Remove (placeholder); if (item is ToolItem) { ((ToolItem)item).Expand = expand; toolbar.Insert ((ToolItem)item, position); } else { ToolItem container_item = new Hyena.Widgets.GenericToolItem (item); container_item.Expand = expand; container_item.Show (); container_item.ToolbarReconfigured += (o, a) => { SetItemSize (container_item, container_item.IconSize); }; toolbar.Insert (container_item, position); } } private void SetItemSize (Gtk.Widget widget, Gtk.IconSize size) { var container = widget as Container; if (container != null) { foreach (var child in container.Children) { SetItemSize (child, size); } } var img = widget as Image; if (img != null) { img.IconSize = (int)size; } } public uint AddUiFromFileInCurrentAssembly (string ui_file) { return AddUiFromFile (ui_file, Assembly.GetCallingAssembly ()); } public uint AddUiFromFile (string ui_file, Assembly assembly) { if (ui_file != null) { using (StreamReader reader = new StreamReader (assembly.GetManifestResourceStream (ui_file))) { return ui_manager.AddUiFromString (reader.ReadToEnd ()); } } return 0; } public Gtk.Action this[string actionId] { get { return FindAction (actionId); } } public UIManager UIManager { get { return ui_manager; } } } } hyena-0.5/Hyena.Gui/Hyena.Gui/Contrast.cs0000644000175000001440000002777711377105500020324 0ustar00gabeusers00000000000000// // Contrast.cs // // Authors: // David Trowbridge // Sebastian Dröge // // Copyright (C) 2006-2007 David Trowbridge // Copyright (C) 2008 Sebastian Dröge // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using Cairo; namespace Hyena.Gui { /* Defined colors. Keep this list alphabetized if you add new ones, * but set the enum value to be at the end of the color_regions table * in contrast.c to maintain binary compatibility */ public enum ContrastPaletteColor { Aqua = 0, Black = 1, Blue = 2, Brown = 3, Cyan = 4, DarkBlue = 5, DarkGreen = 6, DarkGrey = 7, DarkRed = 8, Green = 9, Grey = 10, LightBlue = 11, LightBrown = 12, LightGreen = 13, LightGrey = 14, LightRed = 15, Magenta = 16, Orange = 17, Purple = 18, Red = 19, Violet = 20, White = 21, Yellow = 22, Last = 23 }; public static class Contrast { /* Data for color palette optimization. * * These numbers are completely arbitrary decisions, uninformed by the experts * at crayola. These colors are defined as boxes within the CIE L*a*b* color * space -- while they're not fully inclusive, they are "safe" in that anywhere * within a given region is guaranteed to be the expected color. The data here * are endpoints in each dimension of CIELAB, from which the 8 corners of the * region are created to test. * * Add new entries to the end of this list. */ private static readonly float[,] color_regions = { {40.0f, 60.0f, -100.0f, -80.0f, -10.0f, 20.0f}, /* Aqua */ { 0.0f, 30.0f, 0.0f, 0.0f, 0.0f, 0.0f}, /* Black */ {25.0f, 35.0f, -100.0f, 0.0f, -100.0f, -50.0f}, /* Blue */ {30.0f, 60.0f, 30.0f, 50.0f, 70.0f, 100.0f}, /* Brown */ {50.0f, 65.0f, -100.0f, -30.0f, -100.0f, -50.0f}, /* Cyan */ { 0.0f, 20.0f, -40.0f, 50.0f, -100.0f, -60.0f}, /* Dark Blue */ {20.0f, 35.0f, -100.0f, -70.0f, 60.0f, 100.0f}, /* Dark Green */ {20.0f, 40.0f, 0.0f, 0.0f, 0.0f, 0.0f}, /* Dark Grey */ {10.0f, 40.0f, 90.0f, 100.0f, 70.0f, 100.0f}, /* Dark Red */ {15.0f, 40.0f, -100.0f, -80.0f, 80.0f, 100.0f}, /* Green */ {35.0f, 60.0f, 0.0f, 0.0f, 0.0f, 0.0f}, /* Grey */ {40.0f, 50.0f, -100.0f, 0.0f, -100.0f, -60.0f}, /* Light Blue */ {60.0f, 75.0f, 30.0f, 50.0f, 80.0f, 100.0f}, /* Light Brown */ {80.0f, 90.0f, -100.0f, -70.0f, 70.0f, 100.0f}, /* Light Green */ {50.0f, 80.0f, 0.0f, 0.0f, 0.0f, 0.0f}, /* Light Grey */ {55.0f, 65.0f, 80.0f, 90.0f, 75.0f, 100.0f}, /* Light Red */ {40.0f, 55.0f, 90.0f, 100.0f, -50.0f, 0.0f}, /* Magenta */ {65.0f, 80.0f, 20.0f, 65.0f, 90.0f, 100.0f}, /* Orange */ {35.0f, 45.0f, 85.0f, 100.0f, -90.0f, -80.0f}, /* Purple */ {40.0f, 50.0f, 80.0f, 100.0f, 75.0f, 100.0f}, /* Red */ {70.0f, 95.0f, 90.0f, 100.0f, -100.0f, 0.0f}, /* Violet */ {75.0f, 100.0f, 0.0f, 0.0f, 0.0f, 0.0f}, /* White */ {90.0f, 100.0f, 5.0f, 15.0f, 92.5f, 105.0f}, /* Yellow */ }; /* This performs the non-linear transformation that accounts for the gamma curve * in sRGB, but avoids numerical problems. */ private static float srgb_to_xyz_g (float K) { const float a = 0.055f; const float gamma = 2.4f; if (K > 0.04045f) return (float) Math.Pow((K + a) / (1 + a), gamma); else return K / 12.92f; } private static float xyz_to_lab_f(float t) { if (t > 0.008856f) return (float) Math.Pow(t, 1.0f/3.0f); else return 7.787f*t + 16.0f/116.0f; } private static void rgb_to_lab(ushort R, ushort G, ushort B, out float L, out float a, out float b) { float x, y, z, gr, gg, gb, fy; /* This is the reference white point. Since we're treating "RGB" as * sRGB, this is the D65 point. */ const float Xn = 0.93819f; const float Yn = 0.98705f; const float Zn = 1.07475f; gr = srgb_to_xyz_g(R / 65535.0f); gg = srgb_to_xyz_g(G / 65535.0f); gb = srgb_to_xyz_g(B / 65535.0f); x = 0.412424f * gr + 0.357579f * gg + 0.180464f * gb; y = 0.212656f * gr + 0.715158f * gg + 0.072186f * gb; z = 0.019332f * gr + 0.119193f * gg + 0.950444f * gb; fy = xyz_to_lab_f(y / Yn); L = 116.0f * fy - 16.0f; a = 500.0f * (xyz_to_lab_f(x / Xn) - fy); b = 200.0f * (fy - xyz_to_lab_f(z / Zn)); } private static float xyz_to_srgb_C(float K) { const float a = 0.055f; const float gamma = 2.4f; if (K > 0.00304f) return (1.0f + a) * ((float) Math.Pow(K, (1.0f / gamma))) - a; else return K * 12.92f; } private static void lab_to_rgb(float L, float a, float b, out ushort R, out ushort G, out ushort B) { float x, y, z, fy, fx, fz, delta, delta2, rs, gs, bs; const float Xn = 0.93819f; const float Yn = 0.98705f; const float Zn = 1.07475f; fy = (L + 16.0f) / 116.0f; fx = fy + a / 500.0f; fz = fy - b / 200.0f; delta = 6.0f / 29.0f; delta2 = (float) Math.Pow(delta, 2.0f); if (fx > delta) x = Xn * ((float) Math.Pow(fx, 3.0f)); else x = (fx - 16.0f/116.0f) * 3.0f * delta2 * Xn; if (fy > delta) y = Yn * ((float) Math.Pow(fy, 3.0f)); else y = (fy - 16.0f/116.0f) * 3.0f * delta2 * Yn; if (fz > delta) z = Zn * ((float) Math.Pow(fz, 3.0f)); else z = (fz - 16.0f/116.0f) * 3.0f * delta2 * Zn; rs = 3.2410f * x - 1.5374f * y - 0.4986f * z; gs = -0.9692f * x + 1.8760f * y + 0.0416f * z; bs = 0.0556f * x - 0.2040f * y + 1.0570f * z; float tmp; tmp = (float) Math.Floor(xyz_to_srgb_C(rs) * 65535.0f + 0.5f); if (tmp < 0.0f) R = 0; else if (tmp > 65535.0f) R = 65535; else R = (ushort) tmp; tmp = (float) Math.Floor(xyz_to_srgb_C(gs) * 65535.0f + 0.5f); if (tmp < 0.0f) G = 0; else if (tmp > 65535.0f) G = 65535; else G = (ushort) tmp; tmp = (float) Math.Floor(xyz_to_srgb_C(bs) * 65535.0f + 0.5f); if (tmp < 0.0f) B = 0; else if (tmp > 65535.0f) B = 65535; else B = (ushort) tmp; } private static float lab_distance(float La, float aa, float ba, float Lb, float ab, float bb) { float dL, da, db; dL = Math.Abs(Lb - La); da = Math.Abs(ab - aa); db = Math.Abs(bb - ba); return (float) Math.Sqrt(dL*dL + da*da + db*db); } /* Creates a specific color value for a foreground color, optimizing for * maximum readability against the background. */ public static Color RenderForegroundColor(Color background, ContrastPaletteColor color) { float L, a, b; int max_color; float max_dist; float[,] points = new float[8,3]; float ld, cd; int i; rgb_to_lab((ushort)(background.R * 255), (ushort)(background.G * 255), (ushort)(background.B * 255), out L, out a, out b); points[0,0] = color_regions[(int)color,0]; points[0,1] = color_regions[(int)color,2]; points[0,2] = color_regions[(int)color,4]; points[1,0] = color_regions[(int)color,0]; points[1,1] = color_regions[(int)color,2]; points[1,2] = color_regions[(int)color,5]; points[2,0] = color_regions[(int)color,0]; points[2,1] = color_regions[(int)color,3]; points[2,2] = color_regions[(int)color,4]; points[3,0] = color_regions[(int)color,0]; points[3,1] = color_regions[(int)color,3]; points[3,2] = color_regions[(int)color,5]; points[4,0] = color_regions[(int)color,1]; points[4,1] = color_regions[(int)color,2]; points[4,2] = color_regions[(int)color,4]; points[5,0] = color_regions[(int)color,1]; points[5,1] = color_regions[(int)color,2]; points[5,2] = color_regions[(int)color,5]; points[6,0] = color_regions[(int)color,1]; points[6,1] = color_regions[(int)color,3]; points[6,2] = color_regions[(int)color,4]; points[7,0] = color_regions[(int)color,1]; points[7,1] = color_regions[(int)color,3]; points[7,2] = color_regions[(int)color,5]; max_dist = 0; max_color = 0; for (i = 0; i < 8; i++) { float dist = lab_distance(L, a, b, points[i,0], points[i,1], points[i,2]); if (dist > max_dist) { max_dist = dist; max_color = i; } } /* If the luminosity distance is really short, extend the vector further * out. This may push it outside the bounds of the region that a color * is specified in, but it keeps things readable when the background and * foreground are really close. */ ld = Math.Abs(L - points[max_color,0]); cd = (float) Math.Sqrt (Math.Pow (Math.Abs (a - points[max_color,1]), 2.0f) + Math.Pow (Math.Abs (b - points[max_color,2]), 2.0f)); if ((ld < 10.0f) && (cd < 60.0f)) { float dL, da, db; dL = points[max_color,0] - L; da = points[max_color,1] - a; db = points[max_color,2] - b; points[max_color,0] = L + (dL * 4.0f); points[max_color,1] = a + (da * 1.5f); points[max_color,2] = b + (db * 1.5f); } ushort red, green, blue; lab_to_rgb(points[max_color,0], points[max_color,1], points[max_color,2], out red, out green, out blue); return new Color (red / 255.0, green / 255.0, blue / 255.0); } } } hyena-0.5/Hyena.Gui/Hyena.Gui/CompositeUtils.cs0000644000175000001440000001400411377105500021465 0ustar00gabeusers00000000000000// // CompositeUtils.cs // // Author: // Larry Ewing // // Copyright (C) 2007-2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Runtime.InteropServices; using Gdk; using Gtk; namespace Hyena.Gui { public static class CompositeUtils { [DllImport ("libgdk-win32-2.0-0.dll")] private static extern IntPtr gdk_screen_get_rgba_visual (IntPtr screen); [DllImport ("libgtk-win32-2.0-0.dll")] private static extern void gtk_widget_input_shape_combine_mask (IntPtr raw, IntPtr shape_mask, int offset_x, int offset_y); [DllImport ("libgdk-win32-2.0-0.dll")] private static extern IntPtr gdk_screen_get_rgba_colormap (IntPtr screen); public static Colormap GetRgbaColormap (Screen screen) { try { IntPtr raw_ret = gdk_screen_get_rgba_colormap (screen.Handle); Gdk.Colormap ret = GLib.Object.GetObject(raw_ret) as Gdk.Colormap; return ret; } catch { Gdk.Visual visual = Gdk.Visual.GetBestWithDepth (32); if (visual != null) { Gdk.Colormap cmap = new Gdk.Colormap (visual, false); return cmap; } } return null; } public static bool SetRgbaColormap (Widget w) { Gdk.Colormap cmap = GetRgbaColormap (w.Screen); if (cmap != null) { w.Colormap = cmap; return true; } return false; } public static Visual GetRgbaVisual (Screen screen) { try { IntPtr raw_ret = gdk_screen_get_rgba_visual (screen.Handle); Gdk.Visual ret = GLib.Object.GetObject (raw_ret) as Gdk.Visual; return ret; } catch { Gdk.Visual visual = Gdk.Visual.GetBestWithDepth (32); if (visual != null) { return visual; } } return null; } [DllImport ("libgdk-win32-2.0-0.dll")] private static extern void gdk_property_change (IntPtr window, IntPtr property, IntPtr type, int format, int mode, uint [] data, int nelements); [DllImport ("libgdk-win32-2.0-0.dll")] private static extern void gdk_property_change (IntPtr window, IntPtr property, IntPtr type, int format, int mode, byte [] data, int nelements); public static void ChangeProperty (Gdk.Window win, Atom property, Atom type, PropMode mode, uint [] data) { gdk_property_change (win.Handle, property.Handle, type.Handle, 32, (int)mode, data, data.Length * 4); } public static void ChangeProperty (Gdk.Window win, Atom property, Atom type, PropMode mode, byte [] data) { gdk_property_change (win.Handle, property.Handle, type.Handle, 8, (int)mode, data, data.Length); } [DllImport ("libgdk-win32-2.0-0.dll")] private static extern bool gdk_x11_screen_supports_net_wm_hint (IntPtr screen, IntPtr property); public static bool SupportsHint (Screen screen, string name) { try { Atom atom = Atom.Intern (name, false); return gdk_x11_screen_supports_net_wm_hint (screen.Handle, atom.Handle); } catch { return false; } } [DllImport ("libgdk-win32-2.0-0.dll")] private static extern bool gdk_screen_is_composited (IntPtr screen); public static bool IsComposited (Screen screen) { bool composited; try { composited = gdk_screen_is_composited (screen.Handle); } catch (EntryPointNotFoundException) { Atom atom = Atom.Intern (String.Format ("_NET_WM_CM_S{0}", screen.Number), false); composited = Gdk.Selection.OwnerGetForDisplay (screen.Display, atom) != null; } // FIXME check for WINDOW_OPACITY so that we support compositing on older composite manager // versions before they started supporting the real check given above if (!composited) { composited = CompositeUtils.SupportsHint (screen, "_NET_WM_WINDOW_OPACITY"); } return composited; } public static void SetWinOpacity (Gtk.Window win, double opacity) { CompositeUtils.ChangeProperty (win.GdkWindow, Atom.Intern ("_NET_WM_WINDOW_OPACITY", false), Atom.Intern ("CARDINAL", false), PropMode.Replace, new uint [] { (uint) (0xffffffff * opacity) } ); } public static void InputShapeCombineMask (Widget w, Pixmap shape_mask, int offset_x, int offset_y) { gtk_widget_input_shape_combine_mask (w.Handle, shape_mask == null ? IntPtr.Zero : shape_mask.Handle, offset_x, offset_y); } } } hyena-0.5/Hyena.Gui/Hyena.Gui/TooltipSetter.cs0000644000175000001440000000625411377105500021333 0ustar00gabeusers00000000000000// // TooltipSetter.cs // // Author: // Aaron Bockover // // Copyright (C) 2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Reflection; using Gtk; namespace Hyena.Gui { public static class TooltipSetter { private static Type host_type; private static MethodInfo host_set_tip_method; private static PropertyInfo tooltip_text_property; private static bool reflected; public static object CreateHost () { if (tooltip_text_property != null) { return null; } Type type = reflected ? null : typeof (Widget); if (type != null) { tooltip_text_property = type.GetProperty ("TooltipText", BindingFlags.Instance | BindingFlags.Public); if (tooltip_text_property != null) { reflected = true; return null; } } if (host_set_tip_method == null && !reflected) { reflected = true; host_type = Type.GetType (String.Format ("Gtk.Tooltips, {0}", type.Assembly.FullName)); if (type == null) { return null; } host_set_tip_method = host_type.GetMethod ("SetTip", BindingFlags.Instance | BindingFlags.Public | BindingFlags.InvokeMethod); if (host_set_tip_method == null) { return null; } } return host_set_tip_method != null ? Activator.CreateInstance (host_type) : null; } public static void Set (object host, Widget widget, string textTip) { if (tooltip_text_property != null) { tooltip_text_property.SetValue (widget, textTip, null); } else if (host != null && host_set_tip_method != null) { host_set_tip_method.Invoke (host, new object [] { widget, textTip, null }); } else { throw new ApplicationException ("You must call TooltipSetter.CreateHost before calling TooltipSetter.Set"); } } } } hyena-0.5/Hyena.Gui/Hyena.Gui/EditableUndoAdapter.cs0000644000175000001440000001220111377105500022337 0ustar00gabeusers00000000000000// // EditableUndoAdapter.cs // // Author: // Aaron Bockover // // Copyright (C) 2007-2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Reflection; using Gtk; using Hyena; namespace Hyena.Gui { public class EditableUndoAdapter where T : Widget, Editable { private T editable; private UndoManager undo_manager = new UndoManager (); private AccelGroup accel_group = new AccelGroup (); private EventInfo popup_event_info; private Delegate populate_popup_handler; public EditableUndoAdapter (T editable) { this.editable = editable; popup_event_info = editable.GetType ().GetEvent ("PopulatePopup"); if (popup_event_info != null) { populate_popup_handler = new PopulatePopupHandler (OnPopulatePopup); } } public void Connect () { editable.KeyPressEvent += OnKeyPressEvent; editable.TextDeleted += OnTextDeleted; editable.TextInserted += OnTextInserted; TogglePopupConnection (true); } public void Disconnect () { editable.KeyPressEvent -= OnKeyPressEvent; editable.TextDeleted -= OnTextDeleted; editable.TextInserted -= OnTextInserted; TogglePopupConnection (false); } private void TogglePopupConnection (bool connect) { // Ugh, stupid Gtk+/Gtk# and lack of interfaces if (popup_event_info != null && populate_popup_handler != null) { if (connect) { popup_event_info.AddEventHandler (editable, populate_popup_handler); } else { popup_event_info.RemoveEventHandler (editable, populate_popup_handler); } } } private void OnKeyPressEvent (object o, KeyPressEventArgs args) { if ((args.Event.State & Gdk.ModifierType.ControlMask) != 0) { switch (args.Event.Key) { case Gdk.Key.z: undo_manager.Undo (); args.RetVal = true; break; case Gdk.Key.Z: case Gdk.Key.y: undo_manager.Redo (); args.RetVal = true; break; } } args.RetVal = false; } [GLib.ConnectBefore] private void OnTextDeleted (object o, TextDeletedArgs args) { if (args.StartPos != args.EndPos) { undo_manager.AddUndoAction (new EditableEraseAction (editable, args.StartPos, args.EndPos)); } } [GLib.ConnectBefore] private void OnTextInserted (object o, TextInsertedArgs args) { undo_manager.AddUndoAction (new EditableInsertAction (editable, args.Position, args.Text, args.Length)); } private void OnPopulatePopup (object o, PopulatePopupArgs args) { Menu menu = args.Menu; MenuItem item; item = new SeparatorMenuItem (); item.Show (); menu.Prepend (item); item = new ImageMenuItem (Stock.Redo, null); item.Sensitive = undo_manager.CanRedo; item.Activated += delegate { undo_manager.Redo (); }; item.AddAccelerator ("activate", accel_group, (uint)Gdk.Key.z, Gdk.ModifierType.ControlMask | Gdk.ModifierType.ShiftMask, AccelFlags.Visible); item.Show (); menu.Prepend (item); item = new ImageMenuItem (Stock.Undo, null); item.Sensitive = undo_manager.CanUndo; item.Activated += delegate { undo_manager.Undo (); }; item.AddAccelerator ("activate", accel_group, (uint)Gdk.Key.z, Gdk.ModifierType.ControlMask, AccelFlags.Visible); item.Show (); menu.Prepend (item); } public UndoManager UndoManager { get { return undo_manager; } } } } hyena-0.5/Hyena.Gui/Hyena.Gui/PangoCairoHelper.cs0000644000175000001440000000630211377105500021666 0ustar00gabeusers00000000000000// // CairoHelper.cs // // Author: // Aaron Bockover // // Copyright (C) 2007 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Runtime.InteropServices; namespace Hyena.Gui { public static class PangoCairoHelper { [DllImport ("libpangocairo-1.0-0.dll")] private static extern void pango_cairo_show_layout (IntPtr cr, IntPtr layout); public static void ShowLayout (Cairo.Context cr, Pango.Layout layout) { pango_cairo_show_layout (cr == null ? IntPtr.Zero : cr.Handle, layout == null ? IntPtr.Zero : layout.Handle); } [DllImport ("libpangocairo-1.0-0.dll")] private static extern IntPtr pango_cairo_create_layout (IntPtr cr); public static Pango.Layout CreateLayout (Cairo.Context cr) { IntPtr raw_ret = pango_cairo_create_layout (cr == null ? IntPtr.Zero : cr.Handle); return GLib.Object.GetObject (raw_ret) as Pango.Layout; } [DllImport ("libpangocairo-1.0-0.dll")] private static extern void pango_cairo_layout_path (IntPtr cr, IntPtr layout); public static void LayoutPath (Cairo.Context cr, Pango.Layout layout, bool iUnderstandThePerformanceImplications) { pango_cairo_layout_path (cr == null ? IntPtr.Zero : cr.Handle, layout == null ? IntPtr.Zero : layout.Handle); } [DllImport ("libpangocairo-1.0-0.dll")] private static extern void pango_cairo_context_set_resolution (IntPtr pango_context, double dpi); public static void ContextSetResolution (Pango.Context context, double dpi) { pango_cairo_context_set_resolution (context == null ? IntPtr.Zero : context.Handle, dpi); } [DllImport ("libpangocairo-1.0-0.dll")] private static extern IntPtr pango_layout_get_context (IntPtr layout); public static Pango.Context LayoutGetContext (Pango.Layout layout) { IntPtr handle = pango_layout_get_context (layout.Handle); return handle.Equals (IntPtr.Zero) ? null : GLib.Object.GetObject (handle) as Pango.Context; } } } hyena-0.5/Hyena.Gui/Hyena.Gui/GtkUtilities.cs0000644000175000001440000001575511416417747021156 0ustar00gabeusers00000000000000// // GtkUtilities.cs // // Author: // Aaron Bockover // // Copyright 2007-2010 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using Gtk; namespace Hyena.Gui { public delegate void WidgetAction (T widget) where T : class; public static class GtkUtilities { private static Gdk.ModifierType [] important_modifiers = new Gdk.ModifierType [] { Gdk.ModifierType.ControlMask, Gdk.ModifierType.ShiftMask }; public static bool NoImportantModifiersAreSet () { return NoImportantModifiersAreSet (important_modifiers); } public static bool NoImportantModifiersAreSet (params Gdk.ModifierType [] modifiers) { Gdk.ModifierType state; if (Global.CurrentEvent is Gdk.EventKey) { state = ((Gdk.EventKey)Global.CurrentEvent).State; } else if (Global.CurrentEvent is Gdk.EventButton) { state = ((Gdk.EventButton)Global.CurrentEvent).State; } else { return false; } foreach (Gdk.ModifierType modifier in modifiers) { if ((state & modifier) == modifier) { return false; } } return true; } public static FileFilter GetFileFilter (string name, System.Collections.Generic.IEnumerable extensions) { FileFilter filter = new FileFilter (); filter.Name = name; foreach (string extension in extensions) { filter.AddPattern (String.Format ("*.{0}", extension.ToLower ())); filter.AddPattern (String.Format ("*.{0}", extension.ToUpper ())); } return filter; } public static void SetChooserShortcuts (Gtk.FileChooserDialog chooser, params string [] shortcuts) { foreach (string shortcut in shortcuts) { try { chooser.AddShortcutFolder (shortcut); } catch {} } } public static Gdk.Color ColorBlend (Gdk.Color a, Gdk.Color b) { // at some point, might be nice to allow any blend? double blend = 0.5; if (blend < 0.0 || blend > 1.0) { throw new ApplicationException ("blend < 0.0 || blend > 1.0"); } double blendRatio = 1.0 - blend; int aR = a.Red >> 8; int aG = a.Green >> 8; int aB = a.Blue >> 8; int bR = b.Red >> 8; int bG = b.Green >> 8; int bB = b.Blue >> 8; double mR = aR + bR; double mG = aG + bG; double mB = aB + bB; double blR = mR * blendRatio; double blG = mG * blendRatio; double blB = mB * blendRatio; Gdk.Color color = new Gdk.Color ((byte)blR, (byte)blG, (byte)blB); Gdk.Colormap.System.AllocColor (ref color, true, true); return color; } public static void AdaptGtkRcStyle (Widget adaptee, Type adapter) { GLib.GType type = (GLib.GType)adapter; string path = String.Format ("*.{0}", type); AdaptGtkRcStyle (adaptee, type, path, path); } public static void AdaptGtkRcStyle (Widget adaptee, GLib.GType adapter, string widgetPath, string classPath) { Style style = Gtk.Rc.GetStyleByPaths (adaptee.Settings, widgetPath, classPath, adapter); if (style == null) { return; } foreach (StateType state in Enum.GetValues (typeof (StateType))) { adaptee.ModifyBase (state, style.Base (state)); adaptee.ModifyBg (state, style.Background (state)); adaptee.ModifyFg (state, style.Foreground (state)); adaptee.ModifyText (state, style.Text (state)); } } public static T StyleGetProperty (Widget widget, string property, T default_value) { object result = null; try { result = widget.StyleGetProperty (property); } catch {} return result != null && result.GetType () == typeof (T) ? (T)result : default_value; } public static void ForeachWidget (Container container, WidgetAction action) where T : class { if (container == null) { return; } foreach (Widget child in container.Children) { T widget = child as T; if (widget != null) { action (widget); } else { Container child_container = child as Container; if (child_container != null) { ForeachWidget (child_container, action); } } } } public static bool ShowUri (string uri) { return ShowUri (null, uri); } public static bool ShowUri (Gdk.Screen screen, string uri) { return ShowUri (screen, uri, Gtk.Global.CurrentEventTime); } [System.Runtime.InteropServices.DllImport ("libgtk-win32-2.0-0.dll")] private static extern unsafe bool gtk_show_uri (IntPtr screen, IntPtr uri, uint timestamp, out IntPtr error); public static bool ShowUri (Gdk.Screen screen, string uri, uint timestamp) { var native_uri = GLib.Marshaller.StringToPtrGStrdup (uri); var native_error = IntPtr.Zero; try { return gtk_show_uri (screen == null ? IntPtr.Zero : screen.Handle, native_uri, timestamp, out native_error); } finally { GLib.Marshaller.Free (native_uri); if (native_error != IntPtr.Zero) { throw new GLib.GException (native_error); } } } } } hyena-0.5/Hyena.Gui/Hyena.Gui/BaseWidgetAccessible.cs0000644000175000001440000002023111377105500022475 0ustar00gabeusers00000000000000// // BaseWidgetAccessible.cs // // Author: // Gabriel Burt // // Copyright (C) 2009 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Linq; using System.Collections.Generic; using Atk; namespace Hyena.Gui { #if ENABLE_ATK public class BaseWidgetAccessible : Gtk.Accessible, Atk.ComponentImplementor { private Gtk.Widget widget; private uint focus_id = 0; private Dictionary focus_handlers = new Dictionary (); public BaseWidgetAccessible (Gtk.Widget widget) { this.widget = widget; widget.SizeAllocated += OnAllocated; widget.Mapped += OnMap; widget.Unmapped += OnMap; widget.FocusInEvent += OnFocus; widget.FocusOutEvent += OnFocus; widget.AddNotification ("sensitive", (o, a) => NotifyStateChange (StateType.Sensitive, widget.Sensitive)); widget.AddNotification ("visible", (o, a) => NotifyStateChange (StateType.Visible, widget.Visible)); } public virtual new Atk.Layer Layer { get { return Layer.Widget; } } protected override Atk.StateSet OnRefStateSet () { var s = base.OnRefStateSet (); AddStateIf (s, widget.CanFocus, StateType.Focusable); AddStateIf (s, widget.HasFocus, StateType.Focused); AddStateIf (s, widget.Sensitive, StateType.Sensitive); AddStateIf (s, widget.Sensitive, StateType.Enabled); AddStateIf (s, widget.HasDefault, StateType.Default); AddStateIf (s, widget.Visible, StateType.Visible); AddStateIf (s, widget.Visible && widget.IsMapped, StateType.Showing); return s; } private static void AddStateIf (StateSet s, bool condition, StateType t) { if (condition) { s.AddState (t); } } private void OnFocus (object o, EventArgs args) { NotifyStateChange (StateType.Focused, widget.HasFocus); var handler = FocusChanged; if (handler != null) { handler (this, widget.HasFocus); } } private void OnMap (object o, EventArgs args) { NotifyStateChange (StateType.Showing, widget.Visible && widget.IsMapped); } private void OnAllocated (object o, EventArgs args) { var a = widget.Allocation; var bounds = new Atk.Rectangle () { X = a.X, Y = a.Y, Width = a.Width, Height = a.Height }; GLib.Signal.Emit (this, "bounds_changed", bounds); /*var handler = BoundsChanged; if (handler != null) { handler (this, new BoundsChangedArgs () { Args = new object [] { bounds } }); }*/ } private event FocusHandler FocusChanged; #region Atk.Component public uint AddFocusHandler (Atk.FocusHandler handler) { if (!focus_handlers.ContainsValue (handler)) { FocusChanged += handler; focus_handlers[++focus_id] = handler; return focus_id; } return 0; } public bool Contains (int x, int y, Atk.CoordType coordType) { int x_extents, y_extents, w, h; GetExtents (out x_extents, out y_extents, out w, out h, coordType); Gdk.Rectangle extents = new Gdk.Rectangle (x_extents, y_extents, w, h); return extents.Contains (x, y); } public virtual Atk.Object RefAccessibleAtPoint (int x, int y, Atk.CoordType coordType) { return new NoOpObject (widget); } public void GetExtents (out int x, out int y, out int w, out int h, Atk.CoordType coordType) { w = widget.Allocation.Width; h = widget.Allocation.Height; GetPosition (out x, out y, coordType); } public void GetPosition (out int x, out int y, Atk.CoordType coordType) { Gdk.Window window = null; if (!widget.IsDrawable) { x = y = Int32.MinValue; return; } if (widget.Parent != null) { x = widget.Allocation.X; y = widget.Allocation.Y; window = widget.ParentWindow; } else { x = 0; y = 0; window = widget.GdkWindow; } int x_window, y_window; window.GetOrigin (out x_window, out y_window); x += x_window; y += y_window; if (coordType == Atk.CoordType.Window) { window = widget.GdkWindow.Toplevel; int x_toplevel, y_toplevel; window.GetOrigin (out x_toplevel, out y_toplevel); x -= x_toplevel; y -= y_toplevel; } } public void GetSize (out int w, out int h) { w = widget.Allocation.Width; h = widget.Allocation.Height; } public bool GrabFocus () { if (!widget.CanFocus) { return false; } widget.GrabFocus (); var toplevel_window = widget.Toplevel as Gtk.Window; if (toplevel_window != null) { toplevel_window.Present (); } return true; } public void RemoveFocusHandler (uint handlerId) { if (focus_handlers.ContainsKey (handlerId)) { FocusChanged -= focus_handlers[handlerId]; focus_handlers.Remove (handlerId); } } public bool SetExtents (int x, int y, int w, int h, Atk.CoordType coordType) { return SetSizeAndPosition (x, y, w, h, coordType, true); } public bool SetPosition (int x, int y, Atk.CoordType coordType) { return SetSizeAndPosition (x, y, 0, 0, coordType, false); } private bool SetSizeAndPosition (int x, int y, int w, int h, Atk.CoordType coordType, bool setSize) { if (!widget.IsTopLevel) { return false; } if (coordType == CoordType.Window) { int x_off, y_off; widget.GdkWindow.GetOrigin (out x_off, out y_off); x += x_off; y += y_off; if (x < 0 || y < 0) { return false; } } #pragma warning disable 0612 widget.SetUposition (x, y); #pragma warning restore 0612 if (setSize) { widget.SetSizeRequest (w, h); } return true; } public bool SetSize (int w, int h) { if (widget.IsTopLevel) { widget.SetSizeRequest (w, h); return true; } else { return false; } } public double Alpha { get { return 1.0; } } #endregion Atk.Component } #endif } hyena-0.5/Hyena.Gui/Hyena.Gui/EditableInsertAction.cs0000644000175000001440000000565711377105500022554 0ustar00gabeusers00000000000000// // EditableInsertAction.cs // // Author: // Aaron Bockover // // Copyright (C) 2007-2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using Gtk; using Hyena; namespace Hyena.Gui { internal class EditableInsertAction : IUndoAction { private Editable editable; private string text; private int index; private bool is_paste; public EditableInsertAction (Editable editable, int start, string text, int length) { this.editable = editable; this.text = text; this.index = start; this.is_paste = length > 1; } public void Undo () { editable.DeleteText (index, index + text.Length); editable.Position = index; } public void Redo () { int index_r = index; editable.InsertText (text, ref index_r); editable.Position = index_r; } public void Merge (IUndoAction action) { text += ((EditableInsertAction)action).text; } public bool CanMerge (IUndoAction action) { EditableInsertAction insert = action as EditableInsertAction; if (insert == null || String.IsNullOrEmpty (text)) { return false; } return !( is_paste || insert.is_paste || // Don't group text pastes insert.index != index + text.Length || // Must meet eachother text[0] == '\n' || // Don't group more than one line (inclusive) insert.text[0] == ' ' || insert.text[0] == '\t' // Don't group more than one word (exclusive) ); } public override string ToString () { return String.Format ("Inserted: [{0}] ({1})", text, index); } } } hyena-0.5/Hyena.Gui/Hyena.Gui/ShadingTestWindow.cs0000644000175000001440000000566311377105500022122 0ustar00gabeusers00000000000000// // ShadingTestWindow.cs // // Author: // Aaron Bockover // // Copyright (C) 2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using Gtk; namespace Hyena.Gui { public class ShadingTestWindow : Window { private int steps = 16; public ShadingTestWindow () : base ("Shading Test") { SetSizeRequest (512, 512); } protected override bool OnExposeEvent (Gdk.EventExpose evnt) { Cairo.Context cr = Gdk.CairoHelper.Create (evnt.Window); double step_width = Allocation.Width / (double)steps; double step_height = Allocation.Height / (double)steps; double h = 1.0; double s = 0.0; for (int xi = 0, i = 0; xi < steps; xi++) { for (int yi = 0; yi < steps; yi++, i++) { double bg_b = (double)(i / 255.0); double fg_b = 1.0 - bg_b; double x = Allocation.X + xi * step_width; double y = Allocation.Y + yi * step_height; cr.Rectangle (x, y, step_width, step_height); cr.Color = CairoExtensions.ColorFromHsb (h, s, bg_b); cr.Fill (); int tw, th; Pango.Layout layout = new Pango.Layout (PangoContext); layout.SetText (((int)(bg_b * 255.0)).ToString ()); layout.GetPixelSize (out tw, out th); cr.Translate (0.5, 0.5); cr.MoveTo (x + (step_width - tw) / 2.0, y + (step_height - th) / 2.0); cr.Color = CairoExtensions.ColorFromHsb (h, s, fg_b); PangoCairoHelper.ShowLayout (cr, layout); cr.Translate (-0.5, -0.5); } } CairoExtensions.DisposeContext (cr); return true; } } } hyena-0.5/Hyena.Gui/Hyena.Gui/TestModuleRunner.cs0000644000175000001440000000665411377105500021775 0ustar00gabeusers00000000000000// // TestModuleRunner.cs // // Author: // Aaron Bockover // // Copyright (C) 2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Reflection; using Gtk; namespace Hyena.Gui { public class TestModuleRunner : Window { public static void Run () { Application.Init (); TestModuleRunner runner = new TestModuleRunner (); runner.DeleteEvent += delegate { Application.Quit (); }; runner.ShowAll (); Application.Run (); } private TreeStore store; public TestModuleRunner () : base ("Hyena.Gui Module Tester") { SetSizeRequest (-1, 300); Move (100, 100); BuildModuleList (); BuildView (); } private void BuildModuleList () { store = new TreeStore (typeof (string), typeof (Type)); foreach (Type type in Assembly.GetExecutingAssembly ().GetTypes ()) { foreach (TestModuleAttribute attr in type.GetCustomAttributes (typeof (TestModuleAttribute), false)) { store.AppendValues (attr.Name, type); } } } private void BuildView () { VBox box = new VBox (); Add (box); ScrolledWindow sw = new ScrolledWindow (); sw.HscrollbarPolicy = PolicyType.Never; TreeView view = new TreeView (); view.RowActivated += delegate (object o, RowActivatedArgs args) { TreeIter iter; if (store.GetIter (out iter, args.Path)) { Type type = (Type)store.GetValue (iter, 1); Window window = (Window)Activator.CreateInstance (type); window.WindowPosition = WindowPosition.Center; window.DeleteEvent += delegate { window.Destroy (); }; window.Show (); } }; view.Model = store; view.AppendColumn ("Module", new CellRendererText (), "text", 0); sw.Add (view); box.PackStart (sw, true, true, 0); sw.ShowAll (); Button button = new Button (Stock.Quit); button.Clicked += delegate { Destroy (); Application.Quit (); }; box.PackStart (button, false, false, 0); box.ShowAll (); } } } hyena-0.5/Hyena.Gui/Hyena.Gui/PangoExtensions.cs0000644000175000001440000000344211377105500021632 0ustar00gabeusers00000000000000// // PangoExtensions.cs // // Author: // Aaron Bockover // // Copyright 2009 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. using System; using Pango; namespace Hyena.Gui { public static class PangoExtensions { public static int MeasureTextHeight (this FontDescription description, Context context) { return MeasureTextHeight (description, context, context.Language); } public static int MeasureTextHeight (this FontDescription description, Context context, Language language) { using (var metrics = context.GetMetrics (description, language)) { return ((int)(metrics.Ascent + metrics.Descent) + 512) >> 10; // PANGO_PIXELS (d) } } } } hyena-0.5/Hyena.Gui/Hyena.Gui/RatingRenderer.cs0000644000175000001440000001352411436010340021414 0ustar00gabeusers00000000000000// // RatingRenderer.cs // // Author: // Aaron Bockover // // Copyright (C) 2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using Gtk; using Cairo; namespace Hyena.Gui { public class RatingRenderer { private static double [,] star_plot = new double[,] { { 0, 0.425 }, { 0.375, 0.375 }, { 0.5, 0.05 }, { 0.625, 0.375 }, { 1, 0.425 }, { 0.75, 0.625 }, { 0.8, 0.95 }, { 0.5, 0.75 }, { 0.2, 0.95 }, { 0.25, 0.625 }, { 0, 0.425 }, }; public RatingRenderer () { } public virtual void Render (Context cr, Gdk.Rectangle area, Color color, bool showEmptyStars, bool isHovering, int hoverValue, double fillOpacity, double hoverFillOpacity, double strokeOpacity) { if (Value == MinRating && !isHovering && !showEmptyStars) { return; } Cairo.Color fill_color = color; fill_color.A = fillOpacity; Cairo.Color stroke_color = fill_color; stroke_color.A = strokeOpacity; Cairo.Color hover_fill_color = fill_color; hover_fill_color.A = hoverFillOpacity; double x, y; ComputePosition (area, out x, out y); cr.LineWidth = 1.0; cr.Translate (0.5, 0.5); for (int i = MinRating + 1, s = isHovering || showEmptyStars ? MaxRating : Value; i <= s; i++, x += Size) { bool fill = i <= Value && Value > MinRating; bool hover_fill = i <= hoverValue && hoverValue > MinRating; double scale = fill || hover_fill ? Size : Size - 2; double ofs = fill || hover_fill ? 0 : 1; for (int p = 0, n = star_plot.GetLength (0); p < n; p++) { double px = x + ofs + star_plot[p, 0] * scale; double py = y + ofs + star_plot[p, 1] * scale; if (p == 0) { cr.MoveTo (px, py); } else { cr.LineTo (px, py); } } cr.ClosePath (); if (fill || hover_fill) { if (!isHovering || hoverValue >= Value) { cr.Color = fill ? fill_color : hover_fill_color; } else { cr.Color = hover_fill ? fill_color : hover_fill_color; } cr.Fill (); } else { cr.Color = stroke_color; cr.Stroke (); } } } protected void ComputePosition (Gdk.Rectangle area, out double x, out double y) { double cell_width = area.Width - 2 * Xpad; double cell_height = area.Height - 2 * Ypad; double stars_width = MaxRating * Size; double stars_height = Size; x = area.X + Xpad + (cell_width - stars_width) / 2.0; y = area.Y + Ypad + (cell_height - stars_height) / 2.0; } public int RatingFromPosition (Gdk.Rectangle area, double x) { double r_x, r_y; ComputePosition (area, out r_x, out r_y); return x <= r_x ? 0 : Clamp (MinRating, MaxRating, (int)Math.Ceiling ((x - r_x) / Size) + MinRating); } private static int Clamp (int min, int max, int value) { return Math.Max (min, Math.Min (max, value)); } public int ClampValue (int value) { return Clamp (MinRating, MaxRating, value); } private int value; public int Value { get { return ClampValue (this.value); } set { this.value = ClampValue (value); } } private int size = 14; public int Size { get { return size; } set { size = value; } } private int min_rating = 0; public int MinRating { get { return min_rating; } set { min_rating = value; } } private int max_rating = 5; public int MaxRating { get { return max_rating; } set { max_rating = value; } } public int RatingLevels { get { return MaxRating - MinRating + 1; } } private int xpad = 2; public int Xpad { get { return xpad; } set { xpad = value; } } public int ypad = 2; public int Ypad { get { return ypad; } set { ypad = value; } } public int Width { get { return Xpad * 2 + RatingLevels * Size; } } public int Height { get { return Ypad * 2 + Size; } } } } hyena-0.5/Hyena.Gui/Hyena.Gui/PixbufImageSurface.cs0000644000175000001440000001623111377105500022217 0ustar00gabeusers00000000000000// // PixbufImageSurface.cs // // Author: // Aaron Bockover // // Copyright 2008-2010 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Runtime.InteropServices; using Cairo; namespace Hyena.Gui { public class PixbufImageSurface : ImageSurface, IDisposable { private delegate void cairo_destroy_func_t (IntPtr userdata); private static bool is_le = BitConverter.IsLittleEndian; private static int user_data_key = 0; private static cairo_destroy_func_t destroy_func; private static void DestroyPixelData (IntPtr data) { Marshal.FreeHGlobal (data); } static PixbufImageSurface () { destroy_func = new cairo_destroy_func_t (DestroyPixelData); } public static ImageSurface Create (Gdk.Pixbuf pixbuf) { return Create (pixbuf, false); } public static ImageSurface Create (Gdk.Pixbuf pixbuf, bool disposePixbuf) { if (pixbuf == null || pixbuf.Handle == IntPtr.Zero) { return null; } if (!PlatformDetection.IsWindows) { try { return new PixbufImageSurface (pixbuf, disposePixbuf); } catch { return null; } } else { // FIXME: // Windows has some trouble running the PixbufImageSurface, so as a // workaround a slower but working version of this factory method is // implemented. One day we can come back and optimize this by finding // out what's causing the PixbufImageSurface to result in access // violations when the object is disposed. ImageSurface target = new ImageSurface (Format.ARGB32, pixbuf.Width, pixbuf.Height); Context context = new Context (target); try { Gdk.CairoHelper.SetSourcePixbuf (context, pixbuf, 0, 0); context.Paint (); } finally { ((IDisposable)context).Dispose (); if (disposePixbuf) { ((IDisposable)pixbuf).Dispose (); } } return target; } } private IntPtr data; public PixbufImageSurface (Gdk.Pixbuf pixbuf) : this (pixbuf, false) { } public PixbufImageSurface (Gdk.Pixbuf pixbuf, bool disposePixbuf) : this (disposePixbuf ? pixbuf : null, pixbuf.Width, pixbuf.Height, pixbuf.NChannels, pixbuf.Rowstride, pixbuf.Pixels) { } // This ctor is to avoid multiple queries against the GdkPixbuf for width/height private PixbufImageSurface (Gdk.Pixbuf pixbuf, int width, int height, int channels, int rowstride, IntPtr pixels) : this (pixbuf, Marshal.AllocHGlobal (width * height * 4), width, height, channels, rowstride, pixels) { } private PixbufImageSurface (Gdk.Pixbuf pixbuf, IntPtr data, int width, int height, int channels, int rowstride, IntPtr pixels) : base (data, channels == 3 ? Format.Rgb24 : Format.Argb32, width, height, width * 4) { this.data = data; CreateSurface (width, height, channels, rowstride, pixels); SetDestroyFunc (); if (pixbuf != null && pixbuf.Handle != IntPtr.Zero) { pixbuf.Dispose (); } } private unsafe void CreateSurface (int width, int height, int channels, int gdk_rowstride, IntPtr pixels) { byte *gdk_pixels = (byte *)pixels; byte *cairo_pixels = (byte *)data; for (int i = height; i > 0; i--) { byte *p = gdk_pixels; byte *q = cairo_pixels; if (channels == 3) { byte *end = p + 3 * width; while (p < end) { if (is_le) { q[0] = p[2]; q[1] = p[1]; q[2] = p[0]; } else { q[1] = p[0]; q[2] = p[1]; q[3] = p[2]; } p += 3; q += 4; } } else { byte *end = p + 4 * width; while (p < end) { if (is_le) { q[0] = Mult (p[2], p[3]); q[1] = Mult (p[1], p[3]); q[2] = Mult (p[0], p[3]); q[3] = p[3]; } else { q[0] = p[3]; q[1] = Mult (p[0], p[3]); q[2] = Mult (p[1], p[3]); q[3] = Mult (p[2], p[3]); } p += 4; q += 4; } } gdk_pixels += gdk_rowstride; cairo_pixels += 4 * width; } } private static byte Mult (byte c, byte a) { int t = c * a + 0x7f; return (byte)(((t >> 8) + t) >> 8); } [DllImport ("libcairo-2.dll")] private static extern Cairo.Status cairo_surface_set_user_data (IntPtr surface, ref int key, IntPtr userdata, cairo_destroy_func_t destroy); private void SetDestroyFunc () { try { Status status = cairo_surface_set_user_data (Handle, ref user_data_key, data, destroy_func); if (status != Status.Success) { throw new ApplicationException (String.Format ( "cairo_surface_set_user_data returned {0}", status)); } } catch (Exception e) { Console.Error.WriteLine ("WARNING: Image data will be leaked! ({0} bytes)", Width * Height * 4); Console.Error.WriteLine (e); } } } } hyena-0.5/Hyena.Gui/Hyena.Gui.Dialogs/0000777000175000001440000000000011453151003017533 5ustar00gabeusers00000000000000hyena-0.5/Hyena.Gui/Hyena.Gui.Dialogs/ExceptionDialog.cs0000644000175000001440000002006211414712056023144 0ustar00gabeusers00000000000000// // ExceptionDialog.cs // // Author: // Aaron Bockover // // Copyright (C) 2005-2007 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Reflection; using System.Resources; using System.Diagnostics; using System.Collections.Generic; using System.IO; using Mono.Unix; using Gtk; namespace Hyena.Gui.Dialogs { 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; //Translators: {0} is substituted with the application name Title = String.Format(Catalog.GetString("{0} Encountered a Fatal Error"), ApplicationContext.ApplicationName); 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.UseUnderline = false; label.Justify = Gtk.Justification.Left; label.LineWrap = true; label.Selectable = 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: ")); Stack exception_chain = new Stack (); while (e != null) { exception_chain.Push (e); e = e.InnerException; } while (exception_chain.Count > 0) { e = exception_chain.Pop (); msg.AppendFormat ("{0}\n\n{1}\n", e.Message, e.StackTrace); }; msg.Append("\n"); msg.AppendFormat(".NET Version: {0}\n", Environment.Version); msg.AppendFormat("OS Version: {0}\n", Environment.OSVersion); msg.Append("\nAssembly Version Information:\n\n"); foreach(Assembly asm in AppDomain.CurrentDomain.GetAssemblies()) { AssemblyName name = asm.GetName(); msg.AppendFormat("{0} ({1})\n", name.Name, name.Version); } if(Environment.OSVersion.Platform != PlatformID.Unix) { return msg.ToString(); } try { msg.AppendFormat("\nPlatform Information: {0}", BuildPlatformString()); msg.Append("\n\nDisribution Information:\n\n"); Dictionary lsb = LsbVersionInfo.Harvest; foreach(string lsbfile in lsb.Keys) { msg.AppendFormat("[{0}]\n", lsbfile); msg.AppendFormat("{0}\n", lsb[lsbfile]); } } catch { } 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 Dictionary harvest = new Dictionary(); 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 Dictionary Findings { get { return harvest; } } public static Dictionary Harvest { get { return (new LsbVersionInfo()).Findings; } } } } } hyena-0.5/Hyena.Gui/Hyena.Gui.Dialogs/VersionInformationDialog.cs0000644000175000001440000001043511377105500025042 0ustar00gabeusers00000000000000// // VersionInformationDialog.cs // // Author: // Aaron Bockover // // Copyright (C) 2005-2007 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Reflection; using Gtk; using Mono.Unix; namespace Hyena.Gui.Dialogs { public class VersionInformationDialog : Dialog { private Label path_label; private TreeView version_tree; private TreeStore version_store; public VersionInformationDialog() : base() { AccelGroup accel_group = new AccelGroup(); AddAccelGroup(accel_group); Modal = true; Button button = new Button("gtk-close"); button.CanDefault = true; button.UseStock = true; button.Show(); DefaultResponse = ResponseType.Close; button.AddAccelerator("activate", accel_group, (uint)Gdk.Key.Escape, 0, Gtk.AccelFlags.Visible); AddActionWidget(button, ResponseType.Close); Title = Catalog.GetString("Assembly Version Information"); BorderWidth = 10; version_tree = new TreeView(); version_tree.RulesHint = true; version_tree.AppendColumn(Catalog.GetString("Assembly Name"), new CellRendererText(), "text", 0); version_tree.AppendColumn(Catalog.GetString("Version"), new CellRendererText(), "text", 1); version_tree.Model = FillStore(); version_tree.CursorChanged += OnCursorChanged; ScrolledWindow scroll = new ScrolledWindow(); scroll.Add(version_tree); scroll.ShadowType = ShadowType.In; scroll.SetSizeRequest(420, 200); VBox.PackStart(scroll, true, true, 0); VBox.Spacing = 5; path_label = new Label(); path_label.Ellipsize = Pango.EllipsizeMode.End; path_label.Hide(); path_label.Xalign = 0.0f; path_label.Yalign = 1.0f; VBox.PackStart(path_label, false, true, 0); scroll.ShowAll(); } private void OnCursorChanged(object o, EventArgs args) { TreeIter iter; if(!version_tree.Selection.GetSelected(out iter)) { path_label.Hide(); return; } object path = version_store.GetValue(iter, 2); if(path == null) { path_label.Hide(); return; } path_label.Text = path as string; path_label.Show(); } private TreeStore FillStore() { version_store = new TreeStore(typeof(string), typeof(string), typeof(string)); foreach(Assembly asm in AppDomain.CurrentDomain.GetAssemblies()) { string loc; AssemblyName name = asm.GetName(); try { loc = System.IO.Path.GetFullPath(asm.Location); } catch(Exception) { loc = "dynamic"; } version_store.AppendValues(name.Name, name.Version.ToString(), loc); } version_store.SetSortColumnId(0, SortType.Ascending); return version_store; } } } hyena-0.5/Hyena.Gui/Hyena.Gui.Theming/0000777000175000001440000000000011453151003017544 5ustar00gabeusers00000000000000hyena-0.5/Hyena.Gui/Hyena.Gui.Theming/Theme.cs0000644000175000001440000002150511377105500021142 0ustar00gabeusers00000000000000// // Theme.cs // // Author: // Aaron Bockover // // Copyright (C) 2007-2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Collections.Generic; using Gtk; using Gdk; using Cairo; using Hyena.Gui; namespace Hyena.Gui.Theming { public abstract class Theme { private static Cairo.Color black = new Cairo.Color (0, 0, 0); private Stack contexts = new Stack (); private GtkColors colors; private Cairo.Color selection_fill; private Cairo.Color selection_stroke; private Cairo.Color view_fill; private Cairo.Color view_fill_transparent; private Cairo.Color text_mid; public GtkColors Colors { get { return colors; } } public Widget Widget { get; private set; } public Theme (Widget widget) : this (widget, new GtkColors ()) { } public Theme (Widget widget, GtkColors colors) { this.Widget = widget; this.colors = colors; this.colors.Refreshed += delegate { OnColorsRefreshed (); }; this.colors.Widget = widget; PushContext (); } protected virtual void OnColorsRefreshed () { selection_fill = colors.GetWidgetColor (GtkColorClass.Dark, StateType.Active); selection_stroke = colors.GetWidgetColor (GtkColorClass.Background, StateType.Selected); view_fill = colors.GetWidgetColor (GtkColorClass.Base, StateType.Normal); view_fill_transparent = view_fill; view_fill_transparent.A = 0; text_mid = CairoExtensions.AlphaBlend ( colors.GetWidgetColor (GtkColorClass.Base, StateType.Normal), colors.GetWidgetColor (GtkColorClass.Text, StateType.Normal), 0.5); } #region Drawing public abstract void DrawPie (double fraction); public abstract void DrawArrow (Cairo.Context cr, Gdk.Rectangle alloc, Hyena.Data.SortType type); public void DrawFrame (Cairo.Context cr, Gdk.Rectangle alloc, bool baseColor) { DrawFrameBackground (cr, alloc, baseColor); DrawFrameBorder (cr, alloc); } public void DrawFrame (Cairo.Context cr, Gdk.Rectangle alloc, Cairo.Color color) { DrawFrameBackground (cr, alloc, color); DrawFrameBorder (cr, alloc); } public void DrawFrameBackground (Cairo.Context cr, Gdk.Rectangle alloc, bool baseColor) { DrawFrameBackground (cr, alloc, baseColor ? colors.GetWidgetColor (GtkColorClass.Base, StateType.Normal) : colors.GetWidgetColor (GtkColorClass.Background, StateType.Normal)); } public void DrawFrameBackground (Cairo.Context cr, Gdk.Rectangle alloc, Cairo.Color color) { DrawFrameBackground (cr, alloc, color, null); } public void DrawFrameBackground (Cairo.Context cr, Gdk.Rectangle alloc, Cairo.Pattern pattern) { DrawFrameBackground (cr, alloc, black , pattern); } public abstract void DrawFrameBackground (Cairo.Context cr, Gdk.Rectangle alloc, Cairo.Color color, Cairo.Pattern pattern); public abstract void DrawFrameBorder (Cairo.Context cr, Gdk.Rectangle alloc); public abstract void DrawHeaderBackground (Cairo.Context cr, Gdk.Rectangle alloc); public abstract void DrawColumnHeaderFocus (Cairo.Context cr, Gdk.Rectangle alloc); public abstract void DrawHeaderSeparator (Cairo.Context cr, Gdk.Rectangle alloc, int x); public void DrawListBackground (Cairo.Context cr, Gdk.Rectangle alloc, bool baseColor) { DrawListBackground (cr, alloc, baseColor ? colors.GetWidgetColor (GtkColorClass.Base, StateType.Normal) : colors.GetWidgetColor (GtkColorClass.Background, StateType.Normal)); } public abstract void DrawListBackground (Cairo.Context cr, Gdk.Rectangle alloc, Cairo.Color color); public void DrawColumnHighlight (Cairo.Context cr, double cellWidth, double cellHeight) { Gdk.Rectangle alloc = new Gdk.Rectangle (); alloc.Width = (int)cellWidth; alloc.Height = (int)cellHeight; DrawColumnHighlight (cr, alloc); } public void DrawColumnHighlight (Cairo.Context cr, Gdk.Rectangle alloc) { DrawColumnHighlight (cr, alloc, colors.GetWidgetColor (GtkColorClass.Background, StateType.Selected)); } public abstract void DrawColumnHighlight (Cairo.Context cr, Gdk.Rectangle alloc, Cairo.Color color); public void DrawRowSelection (Cairo.Context cr, int x, int y, int width, int height) { DrawRowSelection (cr, x, y, width, height, true); } public void DrawRowSelection (Cairo.Context cr, int x, int y, int width, int height, bool filled) { DrawRowSelection (cr, x, y, width, height, filled, true, colors.GetWidgetColor (GtkColorClass.Background, StateType.Selected), CairoCorners.All); } public void DrawRowSelection (Cairo.Context cr, int x, int y, int width, int height, bool filled, bool stroked, Cairo.Color color) { DrawRowSelection (cr, x, y, width, height, filled, stroked, color, CairoCorners.All); } public void DrawRowCursor (Cairo.Context cr, int x, int y, int width, int height) { DrawRowCursor (cr, x, y, width, height, colors.GetWidgetColor (GtkColorClass.Background, StateType.Selected)); } public void DrawRowCursor (Cairo.Context cr, int x, int y, int width, int height, Cairo.Color color) { DrawRowCursor (cr, x, y, width, height, color, CairoCorners.All); } public abstract void DrawRowCursor (Cairo.Context cr, int x, int y, int width, int height, Cairo.Color color, CairoCorners corners); public abstract void DrawRowSelection (Cairo.Context cr, int x, int y, int width, int height, bool filled, bool stroked, Cairo.Color color, CairoCorners corners); public abstract void DrawRowRule (Cairo.Context cr, int x, int y, int width, int height); public Cairo.Color ViewFill { get { return view_fill; } } public Cairo.Color ViewFillTransparent { get { return view_fill_transparent; } } public Cairo.Color SelectionFill { get { return selection_fill; } } public Cairo.Color SelectionStroke { get { return selection_stroke; } } public Cairo.Color TextMidColor { get { return text_mid; } protected set { text_mid = value; } } public virtual int BorderWidth { get { return 1; } } public virtual int InnerBorderWidth { get { return 4; } } public int TotalBorderWidth { get { return BorderWidth + InnerBorderWidth; } } #endregion #region Contexts public virtual void PushContext () { PushContext (new ThemeContext ()); } public virtual void PushContext (ThemeContext context) { lock (this) { contexts.Push (context); } } public virtual ThemeContext PopContext () { lock (this) { return contexts.Pop (); } } public virtual ThemeContext Context { get { lock (this) { return contexts.Peek (); } } } #endregion #region Static Utilities public static double Clamp (double min, double max, double value) { return Math.Max (min, Math.Min (max, value)); } #endregion } } hyena-0.5/Hyena.Gui/Hyena.Gui.Theming/ThemeContext.cs0000644000175000001440000000457411377105500022516 0ustar00gabeusers00000000000000// // Theme.cs // // Author: // Aaron Bockover // // Copyright (C) 2007-2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using Cairo; namespace Hyena.Gui.Theming { public class ThemeContext { public bool ToplevelBorderCollapse { get; set; } private double radius = 0.0; public double Radius { get { return radius; } set { radius = value; } } private double fill_alpha = 1.0; public double FillAlpha { get { return fill_alpha; } set { fill_alpha = Theme.Clamp (0.0, 1.0, value); } } private double line_width = 1.0; public double LineWidth { get { return line_width; } set { line_width = value; } } private bool show_stroke = true; public bool ShowStroke { get { return show_stroke; } set { show_stroke = value; } } private double x; public double X { get { return x; } set { x = value; } } private double y; public double Y { get { return y; } set { y = value; } } private Cairo.Context cairo; public Cairo.Context Cairo { get { return cairo; } set { cairo = value; } } } } hyena-0.5/Hyena.Gui/Hyena.Gui.Theming/GtkColors.cs0000644000175000001440000001111211377105500022000 0ustar00gabeusers00000000000000// // GtkColors.cs // // Author: // Aaron Bockover // // Copyright (C) 2007-2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using Cairo; using Gtk; namespace Hyena.Gui.Theming { public enum GtkColorClass { Light, Mid, Dark, Base, Text, Background, Foreground } public class GtkColors { private Cairo.Color [] gtk_colors; private Widget widget; private bool refreshing = false; public event EventHandler Refreshed; public Widget Widget { get { return widget; } set { if (widget == value) { return; } else if (widget != null) { widget.Realized -= OnWidgetRealized; widget.StyleSet -= OnWidgetStyleSet; } widget = value; if (widget.IsRealized) { RefreshColors (); } widget.Realized += OnWidgetRealized; widget.StyleSet += OnWidgetStyleSet; } } public GtkColors () { } private void OnWidgetRealized (object o, EventArgs args) { RefreshColors (); } private void OnWidgetStyleSet (object o, StyleSetArgs args) { RefreshColors (); } public Cairo.Color GetWidgetColor (GtkColorClass @class, StateType state) { if (gtk_colors == null) { RefreshColors (); } return gtk_colors[(int)@class * ((int)StateType.Insensitive + 1) + (int)state]; } public void RefreshColors () { if (refreshing) { return; } refreshing = true; int sn = (int)StateType.Insensitive + 1; int cn = (int)GtkColorClass.Foreground + 1; if (gtk_colors == null) { gtk_colors = new Cairo.Color[sn * cn]; } for (int c = 0, i = 0; c < cn; c++) { for (int s = 0; s < sn; s++, i++) { Gdk.Color color = Gdk.Color.Zero; if (widget != null && widget.IsRealized) { switch ((GtkColorClass)c) { case GtkColorClass.Light: color = widget.Style.LightColors[s]; break; case GtkColorClass.Mid: color = widget.Style.MidColors[s]; break; case GtkColorClass.Dark: color = widget.Style.DarkColors[s]; break; case GtkColorClass.Base: color = widget.Style.BaseColors[s]; break; case GtkColorClass.Text: color = widget.Style.TextColors[s]; break; case GtkColorClass.Background: color = widget.Style.Backgrounds[s]; break; case GtkColorClass.Foreground: color = widget.Style.Foregrounds[s]; break; } } else { color = new Gdk.Color (0, 0, 0); } gtk_colors[c * sn + s] = CairoExtensions.GdkColorToCairoColor (color); } } OnRefreshed (); refreshing = false; } protected virtual void OnRefreshed () { EventHandler handler = Refreshed; if (handler != null) { handler (this, EventArgs.Empty); } } } } hyena-0.5/Hyena.Gui/Hyena.Gui.Theming/ThemeTestModule.cs0000644000175000001440000000700311377105500023145 0ustar00gabeusers00000000000000// // ThemeTestModule.cs // // Author: // Aaron Bockover // // Copyright 2010 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. using System; using Gtk; using Hyena.Gui; namespace Hyena.Gui.Theming { [TestModule ("Theme")] public class ThemeTestModule : Window { public ThemeTestModule () : base ("Theme") { var align = new Alignment (0.0f, 0.0f, 1.0f, 1.0f); var theme_widget = new ThemeTestWidget (); align.Add (theme_widget); Add (align); ShowAll (); int state = 0; uint[,] borders = { {0, 0, 0, 0}, {10, 0, 0, 0}, {0, 10, 0, 0}, {0, 0, 10, 0}, {0, 0, 0, 10}, {10, 10, 0, 0}, {10, 10, 10, 0}, {10, 10, 10, 10}, {10, 0, 0, 10}, {0, 10, 10, 0} }; GLib.Timeout.Add (2000, delegate { Console.WriteLine (state); align.TopPadding = borders[state, 0]; align.RightPadding = borders[state, 1]; align.BottomPadding = borders[state, 2]; align.LeftPadding = borders[state, 3]; if (++state % borders.GetLength (0) == 0) { state = 0; } return true; }); } private class ThemeTestWidget : DrawingArea { private Theme theme; protected override void OnStyleSet (Style previous_style) { base.OnStyleSet (previous_style); theme = ThemeEngine.CreateTheme (this); theme.Context.Radius = 10; } protected override bool OnExposeEvent (Gdk.EventExpose evnt) { Cairo.Context cr = null; try { var alloc = new Gdk.Rectangle () { X = Allocation.X, Y = Allocation.Y, Width = Allocation.Width, Height = Allocation.Height }; cr = Gdk.CairoHelper.Create (evnt.Window); theme.DrawListBackground (cr, alloc, true); theme.DrawFrameBorder (cr, alloc); } finally { CairoExtensions.DisposeContext (cr); } return true; } } } } hyena-0.5/Hyena.Gui/Hyena.Gui.Theming/ThemeEngine.cs0000644000175000001440000000324211377105500022266 0ustar00gabeusers00000000000000// // ThemeEngine.cs // // Author: // Aaron Bockover // // Copyright 2009 Aaron Bockover // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. using System; namespace Hyena.Gui.Theming { public static class ThemeEngine { private static Type theme_type; public static void SetCurrentTheme () where T : Theme { theme_type = typeof (T); } public static Theme CreateTheme (Gtk.Widget widget) { return theme_type == null ? new GtkTheme (widget) : (Theme)Activator.CreateInstance (theme_type, new object [] { widget }); } } }hyena-0.5/Hyena.Gui/Hyena.Gui.Theming/GtkTheme.cs0000644000175000001440000003510411377105500021610 0ustar00gabeusers00000000000000// // GtkTheme.cs // // Author: // Aaron Bockover // // Copyright (C) 2007-2008 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using Cairo; using Gtk; namespace Hyena.Gui.Theming { public class GtkTheme : Theme { private Cairo.Color rule_color; private Cairo.Color border_color; public GtkTheme (Widget widget) : base (widget) { } public static Cairo.Color GetCairoTextMidColor (Widget widget) { Cairo.Color text_color = CairoExtensions.GdkColorToCairoColor (widget.Style.Foreground (StateType.Normal)); Cairo.Color background_color = CairoExtensions.GdkColorToCairoColor (widget.Style.Background (StateType.Normal)); return CairoExtensions.AlphaBlend (text_color, background_color, 0.5); } public static Gdk.Color GetGdkTextMidColor (Widget widget) { Cairo.Color color = GetCairoTextMidColor (widget); Gdk.Color gdk_color = new Gdk.Color ((byte)(color.R * 255), (byte)(color.G * 255), (byte)(color.B * 255)); Gdk.Colormap.System.AllocColor (ref gdk_color, true, true); return gdk_color; } protected override void OnColorsRefreshed () { base.OnColorsRefreshed (); rule_color = CairoExtensions.ColorShade (ViewFill, 0.95); border_color = Colors.GetWidgetColor (GtkColorClass.Dark, StateType.Active); } public override void DrawPie (double fraction) { // Calculate the pie path fraction = Theme.Clamp (0.0, 1.0, fraction); double a1 = 3.0 * Math.PI / 2.0; double a2 = a1 + 2.0 * Math.PI * fraction; if (fraction == 0.0) { return; } Context.Cairo.MoveTo (Context.X, Context.Y); Context.Cairo.Arc (Context.X, Context.Y, Context.Radius, a1, a2); Context.Cairo.LineTo (Context.X, Context.Y); // Fill the pie Color color_a = Colors.GetWidgetColor (GtkColorClass.Background, StateType.Selected); Color color_b = CairoExtensions.ColorShade (color_a, 1.4); RadialGradient fill = new RadialGradient (Context.X, Context.Y, 0, Context.X, Context.Y, 2.0 * Context.Radius); fill.AddColorStop (0, color_a); fill.AddColorStop (1, color_b); Context.Cairo.Pattern = fill; Context.Cairo.FillPreserve (); fill.Destroy (); // Stroke the pie Context.Cairo.Color = CairoExtensions.ColorShade (color_a, 0.8); Context.Cairo.LineWidth = Context.LineWidth; Context.Cairo.Stroke (); } public override void DrawArrow (Context cr, Gdk.Rectangle alloc, Hyena.Data.SortType type) { cr.LineWidth = 1; cr.Translate (0.5, 0.5); double x1 = alloc.X; double x3 = alloc.X + alloc.Width / 2.0; double x2 = x3 + (x3 - x1); double y1 = alloc.Y; double y2 = alloc.Bottom; if (type == Hyena.Data.SortType.Ascending) { cr.MoveTo (x1, y1); cr.LineTo (x2, y1); cr.LineTo (x3, y2); cr.LineTo (x1, y1); } else { cr.MoveTo (x3, y1); cr.LineTo (x2, y2); cr.LineTo (x1, y2); cr.LineTo (x3, y1); } cr.Color = Colors.GetWidgetColor (GtkColorClass.Base, StateType.Normal); cr.FillPreserve (); cr.Color = Colors.GetWidgetColor (GtkColorClass.Text, StateType.Normal); cr.Stroke (); cr.Translate (-0.5, -0.5); } public override void DrawFrameBackground (Cairo.Context cr, Gdk.Rectangle alloc, Cairo.Color color, Cairo.Pattern pattern) { color.A = Context.FillAlpha; if (pattern != null) { cr.Pattern = pattern; } else { cr.Color = color; } CairoExtensions.RoundedRectangle (cr, alloc.X, alloc.Y, alloc.Width, alloc.Height, Context.Radius, CairoCorners.All); cr.Fill (); } public override void DrawFrameBorder (Cairo.Context cr, Gdk.Rectangle alloc) { var corners = CairoCorners.All; double top_extend = 0; double bottom_extend = 0; double left_extend = 0; double right_extend = 0; if (Context.ToplevelBorderCollapse) { if (Widget.Allocation.Top <= Widget.Toplevel.Allocation.Top) { corners &= ~(CairoCorners.TopLeft | CairoCorners.TopRight); top_extend = cr.LineWidth; } if (Widget.Allocation.Bottom >= Widget.Toplevel.Allocation.Bottom) { corners &= ~(CairoCorners.BottomLeft | CairoCorners.BottomRight); bottom_extend = cr.LineWidth; } if (Widget.Allocation.Left <= Widget.Toplevel.Allocation.Left) { corners &= ~(CairoCorners.BottomLeft | CairoCorners.TopLeft); left_extend = cr.LineWidth; } if (Widget.Allocation.Right >= Widget.Toplevel.Allocation.Right) { corners &= ~(CairoCorners.BottomRight | CairoCorners.TopRight); right_extend = cr.LineWidth; } } if (Widget.HasFocus) { cr.LineWidth = BorderWidth * 1.5; cr.Color = CairoExtensions.ColorShade (border_color, 0.8); } else { cr.LineWidth = BorderWidth; cr.Color = border_color; } double offset = (double)cr.LineWidth / 2.0; CairoExtensions.RoundedRectangle (cr, alloc.X + offset - left_extend, alloc.Y + offset - top_extend, alloc.Width - cr.LineWidth + left_extend + right_extend, alloc.Height - cr.LineWidth - top_extend + bottom_extend, Context.Radius, corners); cr.Stroke (); } public override void DrawColumnHighlight (Cairo.Context cr, Gdk.Rectangle alloc, Cairo.Color color) { Cairo.Color light_color = CairoExtensions.ColorShade (color, 1.6); Cairo.Color dark_color = CairoExtensions.ColorShade (color, 1.3); LinearGradient grad = new LinearGradient (alloc.X, alloc.Y, alloc.X, alloc.Bottom - 1); grad.AddColorStop (0, light_color); grad.AddColorStop (1, dark_color); cr.Pattern = grad; cr.Rectangle (alloc.X + 1.5, alloc.Y + 1.5, alloc.Width - 3, alloc.Height - 2); cr.Fill (); grad.Destroy (); } public override void DrawHeaderBackground (Cairo.Context cr, Gdk.Rectangle alloc) { Cairo.Color gtk_background_color = Colors.GetWidgetColor (GtkColorClass.Background, StateType.Normal); Cairo.Color light_color = CairoExtensions.ColorShade (gtk_background_color, 1.1); Cairo.Color dark_color = CairoExtensions.ColorShade (gtk_background_color, 0.95); CairoCorners corners = CairoCorners.TopLeft | CairoCorners.TopRight; LinearGradient grad = new LinearGradient (alloc.X, alloc.Y, alloc.X, alloc.Bottom); grad.AddColorStop (0, light_color); grad.AddColorStop (0.75, dark_color); grad.AddColorStop (0, light_color); cr.Pattern = grad; CairoExtensions.RoundedRectangle (cr, alloc.X, alloc.Y, alloc.Width, alloc.Height, Context.Radius, corners); cr.Fill (); cr.Color = border_color; cr.Rectangle (alloc.X, alloc.Bottom, alloc.Width, BorderWidth); cr.Fill (); grad.Destroy (); } public override void DrawColumnHeaderFocus (Cairo.Context cr, Gdk.Rectangle alloc) { double top_offset = 2.0; double right_offset = 2.0; double margin = 0.5; double line_width = 0.7; Cairo.Color stroke_color = CairoExtensions.ColorShade ( Colors.GetWidgetColor (GtkColorClass.Background, StateType.Selected), 0.8); stroke_color.A = 0.1; cr.Color = stroke_color; CairoExtensions.RoundedRectangle (cr, alloc.X + margin + line_width + right_offset, alloc.Y + margin + line_width + top_offset, alloc.Width - (margin + line_width)*2.0 - right_offset, alloc.Height - (margin + line_width)*2.0 - top_offset, Context.Radius/2.0, CairoCorners.None); cr.Fill (); stroke_color.A = 1.0; cr.LineWidth = line_width; cr.Color = stroke_color; CairoExtensions.RoundedRectangle (cr, alloc.X + margin + line_width + right_offset, alloc.Y + margin + line_width + top_offset, alloc.Width - (line_width + margin)*2.0 - right_offset, alloc.Height - (line_width + margin)*2.0 - right_offset, Context.Radius/2.0, CairoCorners.All); cr.Stroke (); } public override void DrawHeaderSeparator (Cairo.Context cr, Gdk.Rectangle alloc, int x) { Cairo.Color gtk_background_color = Colors.GetWidgetColor (GtkColorClass.Background, StateType.Normal); Cairo.Color dark_color = CairoExtensions.ColorShade (gtk_background_color, 0.80); Cairo.Color light_color = CairoExtensions.ColorShade (gtk_background_color, 1.1); int y_1 = alloc.Top + 4; int y_2 = alloc.Bottom - 3; cr.LineWidth = 1; cr.Antialias = Cairo.Antialias.None; cr.Color = dark_color; cr.MoveTo (x, y_1); cr.LineTo (x, y_2); cr.Stroke (); cr.Color = light_color; cr.MoveTo (x + 1, y_1); cr.LineTo (x + 1, y_2); cr.Stroke (); cr.Antialias = Cairo.Antialias.Default; } public override void DrawListBackground (Context cr, Gdk.Rectangle alloc, Color color) { color.A = Context.FillAlpha; cr.Color = color; cr.Rectangle (alloc.X, alloc.Y, alloc.Width, alloc.Height); cr.Fill (); } public override void DrawRowCursor (Cairo.Context cr, int x, int y, int width, int height, Cairo.Color color, CairoCorners corners) { cr.LineWidth = 1.25; cr.Color = color; CairoExtensions.RoundedRectangle (cr, x + cr.LineWidth/2.0, y + cr.LineWidth/2.0, width - cr.LineWidth, height - cr.LineWidth, Context.Radius, corners, true); cr.Stroke (); } public override void DrawRowSelection (Cairo.Context cr, int x, int y, int width, int height, bool filled, bool stroked, Cairo.Color color, CairoCorners corners) { DrawRowSelection (cr, x, y, width, height, filled, stroked, color, corners, false); } public void DrawRowSelection (Cairo.Context cr, int x, int y, int width, int height, bool filled, bool stroked, Cairo.Color color, CairoCorners corners, bool flat_fill) { Cairo.Color selection_color = color; Cairo.Color selection_highlight = CairoExtensions.ColorShade (selection_color, 1.24); Cairo.Color selection_stroke = CairoExtensions.ColorShade (selection_color, 0.85); selection_highlight.A = 0.5; selection_stroke.A = color.A; LinearGradient grad = null; if (filled) { if (flat_fill) { cr.Color = selection_color; } else { Cairo.Color selection_fill_light = CairoExtensions.ColorShade (selection_color, 1.12); Cairo.Color selection_fill_dark = selection_color; selection_fill_light.A = color.A; selection_fill_dark.A = color.A; grad = new LinearGradient (x, y, x, y + height); grad.AddColorStop (0, selection_fill_light); grad.AddColorStop (0.4, selection_fill_dark); grad.AddColorStop (1, selection_fill_light); cr.Pattern = grad; } CairoExtensions.RoundedRectangle (cr, x, y, width, height, Context.Radius, corners, true); cr.Fill (); if (grad != null) { grad.Destroy (); } } if (filled && stroked) { cr.LineWidth = 1.0; cr.Color = selection_highlight; CairoExtensions.RoundedRectangle (cr, x + 1.5, y + 1.5, width - 3, height - 3, Context.Radius - 1, corners, true); cr.Stroke (); } if (stroked) { cr.LineWidth = 1.0; cr.Color = selection_stroke; CairoExtensions.RoundedRectangle (cr, x + 0.5, y + 0.5, width - 1, height - 1, Context.Radius, corners, true); cr.Stroke (); } } public override void DrawRowRule (Cairo.Context cr, int x, int y, int width, int height) { cr.Color = new Cairo.Color (rule_color.R, rule_color.G, rule_color.B, Context.FillAlpha); cr.Rectangle (x, y, width, height); cr.Fill (); } } } hyena-0.5/NEWS0000644000175000001440000000435011453150732013301 0ustar00gabeusers00000000000000========================== Version 0.5 - Oct 6, 2010 ========================== Add .config file to hyena.pc's Files variable ========================== Version 0.4 - Oct 5, 2010 ========================== General: * Update to build on Windows with MonoDevelop 2.2.1 * Disable CheckForOverflowUnderflow in many .csproj * Can now include hyena as a git submodule within other projects Hyena: * Bind gtk_show_uri (bgo#587320) * Add StringUtil.EscapeLike * Add stream based hashing * Add an ApplicationName property to ApplicationContext * New SafeUri class * New Hyena.Downloader namespace/API * New Paths class (bgo#605891) * Handle bad indices in MemoryListModel * Fix LruCache item expiration * Add thread id to Hyena.Log when debugging. * Fix file location queries (bgo#612152) * Make CryptoUtil.Md5Encode thread-safe * [Json] Add serializer * New Hyena.Metrics classes for instrumenting apps * More extensive platform detection probing * Bundle HttpUtility; dependency on System.Web (bgo#607713) Hyena.Gui * New ListView grid mode * Fix ListView a11y crasher (bgo#615892). * [Hyena.Gui] Fix ActionManager toolitem icon sizing bgo#609265 Hyena.Data.Sqlite: * Add HYENA_MD5 method * Extend SqliteConnection to handle double and nullable values. * Case-insensitive column checks * Add BinaryFunction class; Lets extensions etc call custom methods from SQL even if they're not loaded initially * Fix exception handling (bgo#609799) Contributors: Aaron Bockover, Alan McGovern, Alexander Kojevnikov, Anders Petersson, Andrés G. Aragoneses, Bertrand Lorentz, David Nielsen, Gabriel Burt, Ján Sokoly, Jeroen Budts, Mike Gemünde, Paul Lange, Pete Johanson, Ruben Vermeersch, Sandy Armstrong ========================== Version 0.3 - May 6, 2010 ========================== Synced with Banshee ========================== Version 0.2 - Sept 9, 2009 ========================== Contributors: Romain Tartière Bugs Fixed: * Build fix for *bsd * Fix dll mappings for *bsd ========================== Version 0.1 - Aug 18, 2009 ========================== * Initial release * Hyena, Hyena.Gui, and Hyena.Data.Sqlite built as separate assemblies and each with their own .pc file for convenient copying into your project. See README for details on using Hyena in your app.