[banshee] [Banshee.Gio] Add GIO-based IO backend



commit 233f61c2801d81688122349d6c4bb33d0990e826
Author: Gabriel Burt <gabriel burt gmail com>
Date:   Wed Aug 26 15:01:49 2009 -0700

    [Banshee.Gio] Add GIO-based IO backend
    
    Depends on gio# and gtk#-beans. Add a LocalOnly property to IO
    backends so we can pass that onto Gtk's FileChoosers (BGO #597451)

 Banshee.sln                                        |    7 +
 build/build.environment.mk                         |    2 +
 build/m4/banshee/gio.m4                            |   17 ++
 configure.ac                                       |    5 +
 src/Backends/Banshee.Gio/Banshee.Gio.addin.xml     |   18 ++
 src/Backends/Banshee.Gio/Banshee.Gio.csproj        |   93 ++++++++++
 .../Banshee.Gio/Banshee.IO.Gio/DemuxVfs.cs         |   72 ++++++++
 .../Banshee.Gio/Banshee.IO.Gio/Directory.cs        |  152 ++++++++++++++++
 src/Backends/Banshee.Gio/Banshee.IO.Gio/File.cs    |   97 ++++++++++
 .../Banshee.Gio/Banshee.IO.Gio/Provider.cs         |   49 +++++
 src/Backends/Banshee.Gio/Banshee.IO.Gio/Tests.cs   |  189 ++++++++++++++++++++
 src/Backends/Banshee.Gio/Makefile.am               |   21 +++
 .../Banshee.Unix/Banshee.IO.Unix/Provider.cs       |    2 +
 src/Backends/Makefile.am                           |    1 +
 .../Banshee.Core/Banshee.IO.SystemIO/Provider.cs   |    2 +
 src/Core/Banshee.Core/Banshee.IO/IProvider.cs      |    1 +
 src/Core/Banshee.Core/Banshee.IO/Provider.cs       |    7 +-
 .../Banshee.Gui.Dialogs/FileChooserDialog.cs       |    1 +
 tests/Makefile.am                                  |    1 +
 19 files changed, 736 insertions(+), 1 deletions(-)
---
diff --git a/Banshee.sln b/Banshee.sln
index 9810e63..fd0f2a5 100644
--- a/Banshee.sln
+++ b/Banshee.sln
@@ -101,6 +101,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Banshee.Unix", "src\Backend
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Banshee.Gnome", "src\Backends\Banshee.Gnome\Banshee.Gnome.csproj", "{CA8BAD3C-1545-4B04-AF6B-4105DFD3A9A1}"
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Banshee.Gio", "src\Backends\Banshee.Gio\Banshee.Gio.csproj", "{5F696A8F-B216-4ECE-9E35-907DDFC760BD}"
+EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Banshee.GStreamer", "src\Backends\Banshee.GStreamer\Banshee.GStreamer.csproj", "{6171E5DE-5B36-4AE4-8707-F6BEE0AD945B}"
 EndProject
 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Core", "Core", "{48EA1A64-29EE-4555-9E79-49453EB51976}"
@@ -223,6 +225,8 @@ Global
 		{C856EFD8-E812-4E61-8B76-E3583D94C233}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{C9E904B1-1141-49F4-BE84-85222A8E8A79}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{C9E904B1-1141-49F4-BE84-85222A8E8A79}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{5F696A8F-B216-4ECE-9E35-907DDFC760BD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{5F696A8F-B216-4ECE-9E35-907DDFC760BD}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{CA8BAD3C-1545-4B04-AF6B-4105DFD3A9A1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{CA8BAD3C-1545-4B04-AF6B-4105DFD3A9A1}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{CE2AB4B9-F618-4CCA-8805-E1603741147E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
@@ -261,6 +265,8 @@ Global
 		{CE2AB4B9-F618-4CCA-8805-E1603741147E}.Windows|Any CPU.ActiveCfg = Windows|Any CPU
 		{6171E5DE-5B36-4AE4-8707-F6BEE0AD945B}.Windows|Any CPU.Build.0 = Windows|Any CPU
 		{6171E5DE-5B36-4AE4-8707-F6BEE0AD945B}.Windows|Any CPU.ActiveCfg = Windows|Any CPU
+		{5F696A8F-B216-4ECE-9E35-907DDFC760BD}.Windows|Any CPU.Build.0 = Windows|Any CPU
+		{5F696A8F-B216-4ECE-9E35-907DDFC760BD}.Windows|Any CPU.ActiveCfg = Windows|Any CPU
 		{CA8BAD3C-1545-4B04-AF6B-4105DFD3A9A1}.Windows|Any CPU.Build.0 = Windows|Any CPU
 		{CA8BAD3C-1545-4B04-AF6B-4105DFD3A9A1}.Windows|Any CPU.ActiveCfg = Windows|Any CPU
 		{C1065582-4F64-4810-8C35-E7EB2D2A432C}.Windows|Any CPU.Build.0 = Windows|Any CPU
@@ -393,6 +399,7 @@ Global
 		{3935AE8A-E283-4C0D-9094-7435A937DC90} = {057215DF-2773-4B42-8B8A-64F2CF7764F2}
 		{371ECE68-8D0F-4AFE-AC8F-147167AE3674} = {057215DF-2773-4B42-8B8A-64F2CF7764F2}
 		{6171E5DE-5B36-4AE4-8707-F6BEE0AD945B} = {A03B194F-F644-4E95-A602-87200029240D}
+		{5F696A8F-B216-4ECE-9E35-907DDFC760BD} = {A03B194F-F644-4E95-A602-87200029240D}
 		{CA8BAD3C-1545-4B04-AF6B-4105DFD3A9A1} = {A03B194F-F644-4E95-A602-87200029240D}
 		{C1065582-4F64-4810-8C35-E7EB2D2A432C} = {A03B194F-F644-4E95-A602-87200029240D}
 		{3B7DD288-5546-4907-B302-0CD0271D9713} = {A03B194F-F644-4E95-A602-87200029240D}
diff --git a/build/build.environment.mk b/build/build.environment.mk
index 1aa978e..740240e 100644
--- a/build/build.environment.mk
+++ b/build/build.environment.mk
@@ -18,6 +18,7 @@ LINK_GLIB = $(GLIBSHARP_LIBS)
 LINK_GTK = $(GTKSHARP_LIBS)
 LINK_GCONF = $(GCONFSHARP_LIBS)
 LINK_GNOME = $(GNOMESHARP_LIBS)
+LINK_GIO = $(GTKSHARP_BEANS_LIBS) $(GIOSHARP_LIBS)
 LINK_DBUS = $(NDESK_DBUS_LIBS) $(NDESK_DBUS_GLIB_LIBS)
 LINK_DBUS_NO_GLIB = $(NDESK_DBUS_LIBS) 
 LINK_TAGLIB = $(TAGLIB_SHARP_LIBS)
@@ -145,6 +146,7 @@ REF_EXTENSION_SAMPLE = $(LINK_BANSHEE_THICKCLIENT_DEPS)
 REF_EXTENSION_REMOTE_AUDIO = $(LINK_BANSHEE_THICKCLIENT_DEPS) $(LINK_MONO_ZEROCONF)
 
 # Backends
+REF_BACKEND_GIO = $(LINK_BANSHEE_SERVICES_DEPS) $(LINK_GIO)
 REF_BACKEND_GNOME = $(LINK_BANSHEE_SERVICES_DEPS) $(LINK_BANSHEE_THICKCLIENT_DEPS) $(LINK_GCONF) $(LINK_GNOME)
 REF_BACKEND_GSTREAMER = $(LINK_BANSHEE_SERVICES_DEPS) $(LINK_GLIB)
 REF_BACKEND_UNIX = $(LINK_BANSHEE_CORE_DEPS) $(LINK_MONO_POSIX)
diff --git a/build/m4/banshee/gio.m4 b/build/m4/banshee/gio.m4
new file mode 100644
index 0000000..e475465
--- /dev/null
+++ b/build/m4/banshee/gio.m4
@@ -0,0 +1,17 @@
+AC_DEFUN([BANSHEE_CHECK_GIO_SHARP],
+[
+	GNOMESHARP_REQUIRED=2.8
+
+    enable_gio=no
+
+	PKG_CHECK_MODULES(GTKSHARP_BEANS,
+		gtk-sharp-beans-2.0 >= $GNOMESHARP_REQUIRED,
+        enable_gio=yes, enable_gio=no)
+
+	PKG_CHECK_MODULES(GIOSHARP,
+		gio-sharp-2.0 >= $GNOMESHARP_REQUIRED,
+        enable_gio="$enable_gio", enable_gio=no)
+
+	AM_CONDITIONAL(ENABLE_GIO, test "x$enable_gio" = "xyes")
+])
+
diff --git a/configure.ac b/configure.ac
index 18a761a..85d7a2a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -95,6 +95,9 @@ SHAMROCK_CHECK_MONODOC
 dnl webkit (optional through --enable-webkit)
 BANSHEE_CHECK_WEBKIT
 
+dnl gtk#-beans and gio#
+BANSHEE_CHECK_GIO_SHARP
+
 dnl Moonlight (optional through --enable-moonlight)
 BANSHEE_CHECK_MOONLIGHT
 
@@ -245,6 +248,7 @@ src/Core/Banshee.ThickClient/Makefile
 src/Core/Banshee.Widgets/Makefile
 
 src/Backends/Makefile
+src/Backends/Banshee.Gio/Makefile
 src/Backends/Banshee.Gnome/Makefile
 src/Backends/Banshee.GStreamer/Makefile
 src/Backends/Banshee.Hal/Makefile
@@ -319,6 +323,7 @@ ${PACKAGE}-${VERSION}
   Operating System/Desktop Environment:
     GNOME Support:     ${enable_gnome}
     Builtin Equalizer: ${enable_builtin_equalizer}
+    GIO Support:       ${enable_gio} (requires gtk-sharp-beans and gio-sharp)
     OSX Support:       ${enable_osx}
 
   Digital Audio Player (DAP) Support:
diff --git a/src/Backends/Banshee.Gio/Banshee.Gio.addin.xml b/src/Backends/Banshee.Gio/Banshee.Gio.addin.xml
new file mode 100644
index 0000000..8faf806
--- /dev/null
+++ b/src/Backends/Banshee.Gio/Banshee.Gio.addin.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Addin 
+    id="Banshee.Gio"
+    version="1.0"
+    compatVersion="1.0"
+    copyright="© 2009 Novell Inc. Licensed under the MIT X11 license."
+    category="required:Backends"
+    description="GIO IO backend"
+    defaultEnabled="true">
+
+  <Dependencies>
+    <Addin id="Banshee.Core" version="1.0"/>
+  </Dependencies>
+  
+  <Extension path="/Banshee/Platform/IOProvider">
+    <IOProvider class="Banshee.IO.Gio.Provider" id="Banshee.IO.Gio.Provider" />
+  </Extension>
+</Addin>
diff --git a/src/Backends/Banshee.Gio/Banshee.Gio.csproj b/src/Backends/Banshee.Gio/Banshee.Gio.csproj
new file mode 100644
index 0000000..7fb3064
--- /dev/null
+++ b/src/Backends/Banshee.Gio/Banshee.Gio.csproj
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"; ToolsVersion="3.5">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>8.0.50727</ProductVersion>
+    <ProjectGuid>{5F696A8F-B216-4ECE-9E35-907DDFC760BD}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <UseParentDirectoryAsNamespace>true</UseParentDirectoryAsNamespace>
+    <AssemblyName>Banshee.Gio</AssemblyName>
+    <SchemaVersion>2.0</SchemaVersion>
+    <TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
+    <Optimize>true</Optimize>
+    <OutputPath>..\..\..\bin</OutputPath>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <CheckForOverflowUnderflow>true</CheckForOverflowUnderflow>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <AssemblyKeyFile>.</AssemblyKeyFile>
+    <CustomCommands>
+      <CustomCommands>
+        <Command type="Build" command="make" workingdir="${SolutionDir}" />
+        <Command type="Execute" command="make run" workingdir="${SolutionDir}" />
+      </CustomCommands>
+    </CustomCommands>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Windows|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <AssemblyKeyFile>.</AssemblyKeyFile>
+  </PropertyGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\Core\Banshee.Core\Banshee.Core.csproj">
+      <Project>{2ADB831A-A050-47D0-B6B9-9C19D60233BB}</Project>
+      <Name>Banshee.Core</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\Core\Banshee.Services\Banshee.Services.csproj">
+      <Project>{B28354F0-BA87-44E8-989F-B864A3C7C09F}</Project>
+      <Name>Banshee.Services</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\Libraries\Hyena\Hyena.csproj">
+      <Project>{95374549-9553-4C1E-9D89-667755F90E12}</Project>
+      <Name>Hyena</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\Libraries\Hyena.Gui\Hyena.Gui.csproj">
+      <Project>{C856EFD8-E812-4E61-8B76-E3583D94C233}</Project>
+      <Name>Hyena.Gui</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\Core\Banshee.ThickClient\Banshee.ThickClient.csproj">
+      <Project>{AC839523-7BDF-4AB6-8115-E17921B96EC6}</Project>
+      <Name>Banshee.ThickClient</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\Extensions\Banshee.NowPlaying\Banshee.NowPlaying.csproj">
+      <Project>{16FB0D3A-53FA-4B8E-B02B-4AF66E87829A}</Project>
+      <Name>Banshee.NowPlaying</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="gtk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" />
+    <Reference Include="gnome-sharp, Version=2.24.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Banshee.IO.Gio\DemuxVfs.cs" />
+    <Compile Include="Banshee.IO.Gio\Directory.cs" />
+    <Compile Include="Banshee.IO.Gio\File.cs" />
+    <Compile Include="Banshee.IO.Gio\Provider.cs" />
+    <Compile Include="Banshee.IO.Gio\Tests.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <EmbeddedResource Include="Banshee.Gio.addin.xml" />
+  </ItemGroup>
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+  <ProjectExtensions>
+    <MonoDevelop>
+      <Properties>
+        <MonoDevelop.Autotools.MakefileInfo IntegrationEnabled="true" RelativeMakefileName="Makefile.am">
+          <BuildFilesVar Sync="true" Name="SOURCES" />
+          <DeployFilesVar />
+          <ResourcesVar Sync="true" Name="RESOURCES" />
+          <OthersVar />
+          <GacRefVar />
+          <AsmRefVar />
+          <ProjectRefVar />
+        </MonoDevelop.Autotools.MakefileInfo>
+      </Properties>
+    </MonoDevelop>
+  </ProjectExtensions>
+</Project>
diff --git a/src/Backends/Banshee.Gio/Banshee.IO.Gio/DemuxVfs.cs b/src/Backends/Banshee.Gio/Banshee.IO.Gio/DemuxVfs.cs
new file mode 100644
index 0000000..2d27927
--- /dev/null
+++ b/src/Backends/Banshee.Gio/Banshee.IO.Gio/DemuxVfs.cs
@@ -0,0 +1,72 @@
+//
+// DemuxVfs.cs
+//
+// Author:
+//   Gabriel Burt <gburt novell com>
+//
+// 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 GLib;
+
+using Banshee.Base;
+
+namespace Banshee.IO.Gio
+{
+    public class DemuxVfs : IDemuxVfs
+    {
+        private GLib.File file;
+        private GLib.FileInfo file_info;
+
+        public DemuxVfs (string path)
+        {
+            file = FileFactory.NewForPath (path);
+            file_info = file.QueryInfo ("access::can-read,access::can-write", FileQueryInfoFlags.None, null);
+        }
+
+        public void CloseStream (System.IO.Stream stream)
+        {
+            stream.Close ();
+        }
+
+        public string Name {
+            get { return file.ParsedName; }
+        }
+
+        public System.IO.Stream ReadStream {
+            get { return new GioStream (file.Read (null)); }
+        }
+
+        public System.IO.Stream WriteStream {
+            get { return new GioStream (file.Create (FileCreateFlags.None, null)); }
+        }
+
+        public bool IsReadable {
+            get { return file_info.GetAttributeBoolean ("access::can-read"); }
+        }
+
+        public bool IsWritable {
+            get { return file_info.GetAttributeBoolean ("access::can-write"); }
+        }
+    }
+}
diff --git a/src/Backends/Banshee.Gio/Banshee.IO.Gio/Directory.cs b/src/Backends/Banshee.Gio/Banshee.IO.Gio/Directory.cs
new file mode 100644
index 0000000..43ccbcd
--- /dev/null
+++ b/src/Backends/Banshee.Gio/Banshee.IO.Gio/Directory.cs
@@ -0,0 +1,152 @@
+//
+// Directory.cs
+//
+// Author:
+//   Gabriel Burt <gburt novell com>
+//
+// 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 GLib;
+
+using Hyena;
+using Banshee.Base;
+
+namespace Banshee.IO.Gio
+{
+    public class Directory : IDirectory
+    {
+        public void Create (string directory)
+        {
+            var file = FileFactory.NewForPath (directory);
+            file.MakeDirectoryWithParents (null);
+        }
+
+        public void Delete (string directory)
+        {
+            Delete (directory, false);
+        }
+
+        public void Delete (string directory, bool recursive)
+        {
+            Delete (directory, recursive, false);
+        }
+
+        internal static bool DisableNativeOptimizations = false;
+
+        private void Delete (string directory, bool recursive, bool directoryIsUri)
+        {
+            var dir = GetDir (directory, directoryIsUri);
+
+            if (!dir.Exists) {
+                Console.WriteLine ("{0} doesn't exist", directory);
+                return;
+            }
+
+            if ((dir.QueryFileType (FileQueryInfoFlags.None, null) & FileType.Directory) == 0) {
+                Console.WriteLine ("{0} isn't directory", directory);
+                return;
+            }
+
+            // If native, use the System.IO recursive delete
+            if (dir.IsNative && !DisableNativeOptimizations) {
+                System.IO.Directory.Delete (directory, recursive);
+                return;
+            }
+
+            if (recursive) {
+                foreach (string child in GetFiles (dir, false)) {
+                    FileFactory.NewForUri (child).Delete ();
+                }
+
+                foreach (string child in GetDirectories (dir, false)) {
+                    Delete (child, true, true);
+                }
+            }
+
+            dir.Delete ();
+        }
+
+        private GLib.File GetDir (string directory, bool directoryIsUri)
+        {
+            return directoryIsUri ? FileFactory.NewForUri (directory) : FileFactory.NewForPath (directory);
+        }
+
+        public bool Exists (string directory)
+        {
+            var file = FileFactory.NewForPath (directory);
+            if (!file.QueryExists (null))
+                return false;
+
+            var type = file.QueryFileType (FileQueryInfoFlags.None, null);
+            return (type & FileType.Directory) != 0;
+        }
+
+        public IEnumerable<string> GetFiles (string directory)
+        {
+            return GetFiles (directory, true, false);
+        }
+
+        private IEnumerable<string> GetFiles (string directory, bool followSymlinks, bool directoryIsUri)
+        {
+            return GetFiles (GetDir (directory, directoryIsUri), followSymlinks);
+        }
+
+        private IEnumerable<string> GetFiles (GLib.File dir, bool followSymlinks)
+        {
+            foreach (FileInfo file in dir.EnumerateChildren ("standard::type,standard::name", followSymlinks ? FileQueryInfoFlags.None : FileQueryInfoFlags.NofollowSymlinks, null)) {
+                if ((file.FileType & FileType.Regular) != 0) {
+                    yield return System.IO.Path.Combine (dir.Uri.AbsoluteUri, file.Name);
+                }
+            }
+        }
+
+        public IEnumerable<string> GetDirectories (string directory)
+        {
+            return GetDirectories (directory, true, false);
+        }
+
+        private IEnumerable<string> GetDirectories (string directory, bool followSymlinks, bool directoryIsUri)
+        {
+            return GetDirectories (GetDir (directory, directoryIsUri), followSymlinks);
+        }
+
+        private IEnumerable<string> GetDirectories (GLib.File dir, bool followSymlinks)
+        {
+            foreach (FileInfo file in dir.EnumerateChildren ("standard::type,standard::name", followSymlinks ? FileQueryInfoFlags.None : FileQueryInfoFlags.NofollowSymlinks, null)) {
+                if ((file.FileType & FileType.Directory) != 0) {
+                    yield return System.IO.Path.Combine (dir.Uri.AbsoluteUri, file.Name);
+                }
+            }
+        }
+
+        public void Move (SafeUri from, SafeUri to)
+        {
+            var dir = FileFactory.NewForUri (from.AbsoluteUri);
+            dir.Move (FileFactory.NewForUri (to.AbsoluteUri), FileCopyFlags.None, null, null);
+        }
+    }
+}
diff --git a/src/Backends/Banshee.Gio/Banshee.IO.Gio/File.cs b/src/Backends/Banshee.Gio/Banshee.IO.Gio/File.cs
new file mode 100644
index 0000000..74eb3de
--- /dev/null
+++ b/src/Backends/Banshee.Gio/Banshee.IO.Gio/File.cs
@@ -0,0 +1,97 @@
+//
+// File.cs
+//
+// Author:
+//   Gabriel Burt <gburt novell com>
+//
+// 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 GLib;
+
+using Banshee.Base;
+
+namespace Banshee.IO.Gio
+{
+    public class File : IFile
+    {
+        public void Delete (SafeUri uri)
+        {
+            FileFactory.NewForUri (uri.AbsoluteUri).Delete ();
+        }
+
+        public bool Exists (SafeUri uri)
+        {
+            var file = FileFactory.NewForUri (uri.AbsoluteUri);
+
+            if (!file.Exists) {
+                return false;
+            }
+
+            var type = file.QueryFileType (FileQueryInfoFlags.None, null);
+            return (type & FileType.Regular) != 0 && (type & FileType.Directory) == 0;
+        }
+
+        public void Move (SafeUri from, SafeUri to)
+        {
+            FileFactory.NewForUri (from.AbsoluteUri).Move (FileFactory.NewForUri (to.AbsoluteUri), FileCopyFlags.None, null, null);
+        }
+
+        public void Copy (SafeUri from, SafeUri to, bool overwrite)
+        {
+            FileFactory.NewForUri (from.AbsoluteUri).Move (FileFactory.NewForUri (to.AbsoluteUri), overwrite ? FileCopyFlags.Overwrite : FileCopyFlags.None, null, null);
+        }
+
+        public System.IO.Stream OpenRead (SafeUri uri)
+        {
+            var file = FileFactory.NewForUri (uri.AbsoluteUri);
+            return new GioStream (file.Read (null));
+        }
+
+        public System.IO.Stream OpenWrite (SafeUri uri, bool overwrite)
+        {
+            var file = FileFactory.NewForUri (uri.AbsoluteUri);
+            return new GioStream (overwrite
+                ? file.Replace (null, false, FileCreateFlags.None, null)
+                : file.Create (FileCreateFlags.None, null));
+        }
+
+        public long GetSize (SafeUri uri)
+        {
+            try {
+                var file = FileFactory.NewForUri (uri.AbsoluteUri);
+                var file_info = file.QueryInfo ("standard::size", FileQueryInfoFlags.None, null);
+                return file_info.Size;
+            } catch {
+                return -1;
+            }
+        }
+
+        public long GetModifiedTime (SafeUri uri)
+        {
+            var file = FileFactory.NewForUri (uri.AbsoluteUri);
+            var file_info = file.QueryInfo ("time::modified", FileQueryInfoFlags.None, null);
+            return (long) file_info.GetAttributeULong ("time::modified");
+        }
+    }
+}
diff --git a/src/Backends/Banshee.Gio/Banshee.IO.Gio/Provider.cs b/src/Backends/Banshee.Gio/Banshee.IO.Gio/Provider.cs
new file mode 100644
index 0000000..c6420d2
--- /dev/null
+++ b/src/Backends/Banshee.Gio/Banshee.IO.Gio/Provider.cs
@@ -0,0 +1,49 @@
+//
+// Provider.cs
+//
+// Author:
+//   Gabriel Burt <gburt novell com>
+//
+// 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 Banshee.IO.Gio
+{
+    public class Provider : Banshee.IO.IProvider
+    {
+        public Type FileProvider {
+            get { return typeof (File); }
+        }
+
+        public Type DirectoryProvider {
+            get { return typeof (Directory); }
+        }
+
+        public Type DemuxVfsProvider {
+            get { return typeof (DemuxVfs); }
+        }
+
+        public bool LocalOnly { get { return false; } }
+    }
+}
diff --git a/src/Backends/Banshee.Gio/Banshee.IO.Gio/Tests.cs b/src/Backends/Banshee.Gio/Banshee.IO.Gio/Tests.cs
new file mode 100644
index 0000000..4ef9c85
--- /dev/null
+++ b/src/Backends/Banshee.Gio/Banshee.IO.Gio/Tests.cs
@@ -0,0 +1,189 @@
+//
+// Tests.cs
+//
+// Author:
+//   Gabriel Burt <gburt novell com>
+//
+// 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 NUnit.Framework;
+using GLib;
+
+using Banshee.Base;
+
+namespace Banshee.IO.Gio
+{
+    [TestFixture]
+    public class GioTests
+    {
+        private File file = new File ();
+        private Directory dir = new Directory ();
+        private string tmp_dir = System.IO.Path.Combine (System.Environment.CurrentDirectory, "tmp-gio");
+        private SafeUri foo, baz;
+        private string woo;
+
+        static GioTests ()
+        {
+            GLib.GType.Init ();
+        }
+
+        [SetUp]
+        public void Setup ()
+        {
+            foo = Uri  ("foo");
+            baz = Uri  ("baz");
+            woo = Path ("woo");
+
+            System.IO.Directory.CreateDirectory (tmp_dir);
+            System.IO.File.WriteAllText (Path ("foo"), "bar");
+            System.IO.File.WriteAllText (Path ("baz"), "oof");
+            System.IO.Directory.CreateDirectory (Path ("woo"));
+        }
+
+        [TearDown]
+        public void Teardown ()
+        {
+            try { System.IO.File.Delete (Path ("foo")); } catch {}
+            try { System.IO.File.Delete (Path ("baz")); } catch {}
+            try { System.IO.Directory.Delete (woo); } catch {}
+            try { System.IO.Directory.Delete (tmp_dir, true); } catch {}
+        }
+
+        [Test]
+        public void Exists ()
+        {
+            Assert.IsTrue (file.Exists (foo));
+            Assert.IsTrue (file.Exists (baz));
+            Assert.IsTrue ( dir.Exists (woo));
+        }
+
+        [Test]
+        public void DoesntExist ()
+        {
+            Assert.IsFalse ( dir.Exists (Path ("foo")));
+            Assert.IsFalse (file.Exists (Uri ("woo")));
+            Assert.IsFalse (file.Exists (Uri ("asd")));
+        }
+
+        [Test]
+        public void Move ()
+        {
+            file.Move (foo, Uri ("fooz"));
+            Assert.IsTrue  (file.Exists (Uri ("fooz")));
+            Assert.IsFalse (file.Exists (foo));
+
+            dir.Move (new SafeUri (woo), Uri ("wooz"));
+            Assert.IsTrue  (dir.Exists (Path ("wooz")));
+            Assert.IsFalse (dir.Exists (woo));
+        }
+
+        [Test]
+        public void Create ()
+        {
+            var newf = Uri ("newfile");
+            Assert.IsFalse (file.Exists (newf));
+            file.OpenWrite (newf, false).Close ();
+            Assert.IsTrue (file.Exists (newf));
+
+            try {
+                file.OpenWrite (newf, false).Close ();
+                Assert.Fail ("Should have thrown an exception creating already-exists file w/o overwrite");
+            } catch {}
+
+            try {
+                file.OpenWrite (newf, true).Close ();
+            } catch {
+                Assert.Fail ("Should not have thrown an exception creating already-exists file w/ overwrite");
+            }
+
+            var newd = Path ("newdir");
+            Assert.IsFalse (dir.Exists (newd));
+            dir.Create (newd);
+            Assert.IsTrue (dir.Exists (newd));
+        }
+
+        [Test]
+        public void GetFileProperties ()
+        {
+            Assert.AreEqual (3, file.GetSize (foo));
+            Assert.IsTrue (file.GetModifiedTime (foo) > 0);
+        }
+
+        [Test]
+        public void Delete ()
+        {
+            Assert.IsTrue (file.Exists (foo));
+            file.Delete (foo);
+            Assert.IsFalse (file.Exists (foo));
+
+            Assert.IsTrue (dir.Exists (woo));
+            dir.Delete (woo);
+            Assert.IsFalse (dir.Exists (woo));
+        }
+
+        [Test]
+        public void DeleteRecursive ()
+        {
+            dir.Delete (tmp_dir, true);
+        }
+
+        [Test]
+        public void DeleteRecursiveWithoutNativeOptimization ()
+        {
+            Directory.DisableNativeOptimizations = true;
+            dir.Delete (tmp_dir, true);
+            Directory.DisableNativeOptimizations = false;
+        }
+
+        [Test]
+        public void GetChildFiles ()
+        {
+            var files = dir.GetFiles (tmp_dir).ToArray ();
+            Assert.AreEqual (files, new string [] { foo.AbsoluteUri, baz.AbsoluteUri });
+        }
+
+        [Test]
+        public void GetChildDirs ()
+        {
+            var dirs = dir.GetDirectories (tmp_dir).ToArray ();
+            Assert.AreEqual (dirs, new string [] { new SafeUri (woo).AbsoluteUri });
+        }
+
+        private SafeUri Uri (string filename)
+        {
+            return new SafeUri (Path (filename));
+        }
+
+        private string Path (string filename)
+        {
+            return System.IO.Path.Combine (tmp_dir, filename);
+        }
+    }
+}
+
+#endif
diff --git a/src/Backends/Banshee.Gio/Makefile.am b/src/Backends/Banshee.Gio/Makefile.am
new file mode 100644
index 0000000..2ad5dc6
--- /dev/null
+++ b/src/Backends/Banshee.Gio/Makefile.am
@@ -0,0 +1,21 @@
+ASSEMBLY = Banshee.Gio
+TARGET = library
+LINK = $(REF_BACKEND_GIO)
+INSTALL_DIR = $(BACKENDS_INSTALL_DIR)
+
+SOURCES =  \
+	Banshee.IO.Gio/DemuxVfs.cs \
+	Banshee.IO.Gio/Directory.cs \
+	Banshee.IO.Gio/File.cs \
+	Banshee.IO.Gio/Provider.cs \
+	Banshee.IO.Gio/Tests.cs
+
+RESOURCES =  \
+	Banshee.Gio.addin.xml
+
+if ENABLE_GIO
+include $(top_srcdir)/build/build.mk
+else
+EXTRA_DIST = $(SOURCES) $(RESOURCES)
+endif
+
diff --git a/src/Backends/Banshee.Unix/Banshee.IO.Unix/Provider.cs b/src/Backends/Banshee.Unix/Banshee.IO.Unix/Provider.cs
index 1671663..09b7d47 100644
--- a/src/Backends/Banshee.Unix/Banshee.IO.Unix/Provider.cs
+++ b/src/Backends/Banshee.Unix/Banshee.IO.Unix/Provider.cs
@@ -43,5 +43,7 @@ namespace Banshee.IO.Unix
     	public Type DemuxVfsProvider {
     	    get { return typeof (DemuxVfs); }
     	}
+
+        public bool LocalOnly { get { return true; } }
     }
 }
diff --git a/src/Backends/Makefile.am b/src/Backends/Makefile.am
index 0cc38e8..c7859a3 100644
--- a/src/Backends/Makefile.am
+++ b/src/Backends/Makefile.am
@@ -1,5 +1,6 @@
 SUBDIRS = \
 	Banshee.Hal \
+	Banshee.Gio \
 	Banshee.Gnome \
 	Banshee.GStreamer \
 	Banshee.Unix \
diff --git a/src/Core/Banshee.Core/Banshee.IO.SystemIO/Provider.cs b/src/Core/Banshee.Core/Banshee.IO.SystemIO/Provider.cs
index 409e3e1..26b2c8a 100644
--- a/src/Core/Banshee.Core/Banshee.IO.SystemIO/Provider.cs
+++ b/src/Core/Banshee.Core/Banshee.IO.SystemIO/Provider.cs
@@ -43,5 +43,7 @@ namespace Banshee.IO.SystemIO
     	public Type DemuxVfsProvider {
     	    get { return typeof (DemuxVfs); }
     	}
+
+        public bool LocalOnly { get { return true; } }
     }
 }
diff --git a/src/Core/Banshee.Core/Banshee.IO/IProvider.cs b/src/Core/Banshee.Core/Banshee.IO/IProvider.cs
index 2010f19..4250b31 100644
--- a/src/Core/Banshee.Core/Banshee.IO/IProvider.cs
+++ b/src/Core/Banshee.Core/Banshee.IO/IProvider.cs
@@ -35,5 +35,6 @@ namespace Banshee.IO
         Type FileProvider { get; }
         Type DirectoryProvider { get; }
         Type DemuxVfsProvider { get; }
+        bool LocalOnly { get; }
     }
 }
diff --git a/src/Core/Banshee.Core/Banshee.IO/Provider.cs b/src/Core/Banshee.Core/Banshee.IO/Provider.cs
index f43caa5..f70172b 100644
--- a/src/Core/Banshee.Core/Banshee.IO/Provider.cs
+++ b/src/Core/Banshee.Core/Banshee.IO/Provider.cs
@@ -81,6 +81,10 @@ namespace Banshee.IO
         internal static IFile File {
             get { return file; }
         }
+
+        public static bool LocalOnly {
+            get { return provider == null ? true : provider.LocalOnly; }
+        }
         
         internal static IDemuxVfs CreateDemuxVfs (string file)
         {
@@ -89,9 +93,10 @@ namespace Banshee.IO
         
         internal static readonly SchemaEntry<string> ProviderSchema = new SchemaEntry<string> (
             "core", "io_provider",
-            "Banshee.IO.Unix.Provider",
+            "Banshee.IO.Gio.Provider",
             "Set the IO provider backend in Banshee",
             "Can be either \"Banshee.IO.SystemIO.Provider\" (.NET System.IO), " + 
+                "\"Banshee.IO.Gio.Provider\" (GIO), or " +
                 "\"Banshee.IO.Unix.Provider\" (Native Unix/POSIX), or " +
                 "\"Banshee.IO.GnomeVfs.Provider\" (GNOME VFS); " +
                 "takes effect on Banshee start (restart necessary)"
diff --git a/src/Core/Banshee.ThickClient/Banshee.Gui.Dialogs/FileChooserDialog.cs b/src/Core/Banshee.ThickClient/Banshee.Gui.Dialogs/FileChooserDialog.cs
index 043f781..415b674 100644
--- a/src/Core/Banshee.ThickClient/Banshee.Gui.Dialogs/FileChooserDialog.cs
+++ b/src/Core/Banshee.ThickClient/Banshee.Gui.Dialogs/FileChooserDialog.cs
@@ -66,6 +66,7 @@ namespace Banshee.Gui.Dialogs
         public FileChooserDialog (string title, Window parent, FileChooserAction action) : 
             base (title, parent, action)
         {
+            LocalOnly = Banshee.IO.Provider.LocalOnly;
             SetCurrentFolderUri (LastFileChooserUri.Get (Environment.GetFolderPath (Environment.SpecialFolder.Personal)));
             WindowPosition = WindowPosition.Center;
         }
diff --git a/tests/Makefile.am b/tests/Makefile.am
index b55433a..c0da6af 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -12,6 +12,7 @@ TEST_ASSEMBLIES = \
 	Migo.dll \
 	Mono.Media.dll \
 	Banshee.Core.dll \
+	Banshee.Gnome.dll \
 	Banshee.Services.dll \
 	Banshee.Dap.Mtp.dll
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]