├── .gitignore ├── Compass.FilePicker.sln ├── Compass.FilePicker.userprefs ├── Compass.FilePicker ├── CancelEventHandler.cs ├── Compass.FilePicker.csproj ├── Compass.FilePicker.sln ├── Enums.cs ├── FileListAdapter.cs ├── FileListRowViewHolder.cs ├── FilePickerActivity.cs ├── FilePickerFileObserver.cs ├── FilePickerFragment.cs ├── FileSelectedEventHandler.cs ├── Helpers.cs ├── Properties │ └── AssemblyInfo.cs ├── README.html ├── README.min.html ├── Resources │ ├── AboutResources.txt │ ├── Drawable-hdpi │ │ ├── filepicker_file.png │ │ ├── filepicker_folder.png │ │ ├── filepicker_new_folder.png │ │ └── filepicker_previous.png │ ├── Drawable-ldpi │ │ ├── filepicker_file.png │ │ ├── filepicker_folder.png │ │ ├── filepicker_new_folder.png │ │ └── filepicker_previous.png │ ├── Drawable-xhdpi │ │ ├── filepicker_file.png │ │ ├── filepicker_folder.png │ │ ├── filepicker_new_folder.png │ │ └── filepicker_previous.png │ ├── Drawable │ │ ├── borderless_button.xml │ │ ├── filepicker_file.png │ │ ├── filepicker_folder.png │ │ ├── filepicker_new_folder.png │ │ └── filepicker_previous.png │ ├── Layout │ │ ├── filepicker_createfolder.axml │ │ ├── filepicker_fragment.axml │ │ ├── filepicker_listitem.axml │ │ └── filepicker_mainactivity.axml │ ├── Menu │ │ └── filepicker_menu.xml │ ├── Resource.Designer.cs │ └── Values │ │ ├── Colors.xml │ │ └── Strings.xml └── Settings.StyleCop ├── LICENSE ├── README.md └── SampleApplication ├── MainActivity.cs ├── Properties ├── AndroidManifest.xml └── AssemblyInfo.cs ├── Resources ├── Drawable │ └── Icon.png ├── Layout │ └── Main.axml ├── Resource.Designer.cs └── Values │ └── Strings.xml └── SampleApplication.csproj /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.sln.docstates 8 | 9 | # Build results 10 | [Dd]ebug/ 11 | [Dd]ebugPublic/ 12 | [Rr]elease/ 13 | [Rr]eleases/ 14 | x64/ 15 | x86/ 16 | build/ 17 | bld/ 18 | [Bb]in/ 19 | [Oo]bj/ 20 | 21 | # Roslyn cache directories 22 | *.ide/ 23 | 24 | # MSTest test Results 25 | [Tt]est[Rr]esult*/ 26 | [Bb]uild[Ll]og.* 27 | 28 | #NUNIT 29 | *.VisualState.xml 30 | TestResult.xml 31 | 32 | # Build Results of an ATL Project 33 | [Dd]ebugPS/ 34 | [Rr]eleasePS/ 35 | dlldata.c 36 | 37 | *_i.c 38 | *_p.c 39 | *_i.h 40 | *.ilk 41 | *.meta 42 | *.obj 43 | *.pch 44 | *.pdb 45 | *.pgc 46 | *.pgd 47 | *.rsp 48 | *.sbr 49 | *.tlb 50 | *.tli 51 | *.tlh 52 | *.tmp 53 | *.tmp_proj 54 | *.log 55 | *.vspscc 56 | *.vssscc 57 | .builds 58 | *.pidb 59 | *.svclog 60 | *.scc 61 | 62 | # Chutzpah Test files 63 | _Chutzpah* 64 | 65 | # Visual C++ cache files 66 | ipch/ 67 | *.aps 68 | *.ncb 69 | *.opensdf 70 | *.sdf 71 | *.cachefile 72 | 73 | # Visual Studio profiler 74 | *.psess 75 | *.vsp 76 | *.vspx 77 | 78 | # TFS 2012 Local Workspace 79 | $tf/ 80 | 81 | # Guidance Automation Toolkit 82 | *.gpState 83 | 84 | # ReSharper is a .NET coding add-in 85 | _ReSharper*/ 86 | *.[Rr]e[Ss]harper 87 | *.DotSettings.user 88 | 89 | # JustCode is a .NET coding addin-in 90 | .JustCode 91 | 92 | # TeamCity is a build add-in 93 | _TeamCity* 94 | 95 | # DotCover is a Code Coverage Tool 96 | *.dotCover 97 | 98 | # NCrunch 99 | _NCrunch_* 100 | .*crunch*.local.xml 101 | 102 | # MightyMoose 103 | *.mm.* 104 | AutoTest.Net/ 105 | 106 | # Web workbench (sass) 107 | .sass-cache/ 108 | 109 | # Installshield output folder 110 | [Ee]xpress/ 111 | 112 | # DocProject is a documentation generator add-in 113 | DocProject/buildhelp/ 114 | DocProject/Help/*.HxT 115 | DocProject/Help/*.HxC 116 | DocProject/Help/*.hhc 117 | DocProject/Help/*.hhk 118 | DocProject/Help/*.hhp 119 | DocProject/Help/Html2 120 | DocProject/Help/html 121 | 122 | # Click-Once directory 123 | publish/ 124 | 125 | # Publish Web Output 126 | *.[Pp]ublish.xml 127 | *.azurePubxml 128 | # TODO: Comment the next line if you want to checkin your web deploy settings 129 | # but database connection strings (with potential passwords) will be unencrypted 130 | *.pubxml 131 | *.publishproj 132 | 133 | # NuGet Packages 134 | *.nupkg 135 | # The packages folder can be ignored because of Package Restore 136 | **/packages/* 137 | # except build/, which is used as an MSBuild target. 138 | !**/packages/build/ 139 | # If using the old MSBuild-Integrated Package Restore, uncomment this: 140 | #!**/packages/repositories.config 141 | 142 | # Windows Azure Build Output 143 | csx/ 144 | *.build.csdef 145 | 146 | # Windows Store app package directory 147 | AppPackages/ 148 | 149 | # Others 150 | sql/ 151 | *.Cache 152 | ClientBin/ 153 | [Ss]tyle[Cc]op.* 154 | ~$* 155 | *~ 156 | *.dbmdl 157 | *.dbproj.schemaview 158 | *.pfx 159 | *.publishsettings 160 | node_modules/ 161 | 162 | # RIA/Silverlight projects 163 | Generated_Code/ 164 | 165 | # Backup & report files from converting an old project file 166 | # to a newer Visual Studio version. Backup files are not needed, 167 | # because we have git ;-) 168 | _UpgradeReport_Files/ 169 | Backup*/ 170 | UpgradeLog*.XML 171 | UpgradeLog*.htm 172 | 173 | # SQL Server files 174 | *.mdf 175 | *.ldf 176 | 177 | # Business Intelligence projects 178 | *.rdl.data 179 | *.bim.layout 180 | *.bim_*.settings 181 | 182 | # Microsoft Fakes 183 | FakesAssemblies/ 184 | -------------------------------------------------------------------------------- /Compass.FilePicker.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2012 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Compass.FilePicker", "Compass.FilePicker\Compass.FilePicker.csproj", "{605F69AA-93A8-4AEA-9BBD-BF3AE649506A}" 5 | EndProject 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SampleApplication", "SampleApplication\SampleApplication.csproj", "{5A266FE2-65AD-46A5-A8FC-DB224FD1CACA}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {5A266FE2-65AD-46A5-A8FC-DB224FD1CACA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {5A266FE2-65AD-46A5-A8FC-DB224FD1CACA}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {5A266FE2-65AD-46A5-A8FC-DB224FD1CACA}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {5A266FE2-65AD-46A5-A8FC-DB224FD1CACA}.Release|Any CPU.Build.0 = Release|Any CPU 18 | {605F69AA-93A8-4AEA-9BBD-BF3AE649506A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 19 | {605F69AA-93A8-4AEA-9BBD-BF3AE649506A}.Debug|Any CPU.Build.0 = Debug|Any CPU 20 | {605F69AA-93A8-4AEA-9BBD-BF3AE649506A}.Release|Any CPU.ActiveCfg = Release|Any CPU 21 | {605F69AA-93A8-4AEA-9BBD-BF3AE649506A}.Release|Any CPU.Build.0 = Release|Any CPU 22 | EndGlobalSection 23 | GlobalSection(MonoDevelopProperties) = preSolution 24 | StartupItem = SampleApplication\SampleApplication.csproj 25 | Policies = $0 26 | $0.DotNetNamingPolicy = $1 27 | $1.DirectoryNamespaceAssociation = None 28 | $1.ResourceNamePolicy = FileFormatDefault 29 | $0.StandardHeader = $2 30 | $2.Text = 31 | $2.IncludeInNewFiles = True 32 | $0.NameConventionPolicy = $3 33 | $3.Rules = $4 34 | $4.NamingRule = $5 35 | $5.Name = Namespaces 36 | $5.AffectedEntity = Namespace 37 | $5.VisibilityMask = VisibilityMask 38 | $5.NamingStyle = PascalCase 39 | $5.IncludeInstanceMembers = True 40 | $5.IncludeStaticEntities = True 41 | $4.NamingRule = $6 42 | $6.Name = Types 43 | $6.AffectedEntity = Class, Struct, Enum, Delegate 44 | $6.VisibilityMask = Public 45 | $6.NamingStyle = PascalCase 46 | $6.IncludeInstanceMembers = True 47 | $6.IncludeStaticEntities = True 48 | $4.NamingRule = $7 49 | $7.Name = Interfaces 50 | $7.RequiredPrefixes = $8 51 | $8.String = I 52 | $7.AffectedEntity = Interface 53 | $7.VisibilityMask = Public 54 | $7.NamingStyle = PascalCase 55 | $7.IncludeInstanceMembers = True 56 | $7.IncludeStaticEntities = True 57 | $4.NamingRule = $9 58 | $9.Name = Attributes 59 | $9.RequiredSuffixes = $10 60 | $10.String = Attribute 61 | $9.AffectedEntity = CustomAttributes 62 | $9.VisibilityMask = Public 63 | $9.NamingStyle = PascalCase 64 | $9.IncludeInstanceMembers = True 65 | $9.IncludeStaticEntities = True 66 | $4.NamingRule = $11 67 | $11.Name = Event Arguments 68 | $11.RequiredSuffixes = $12 69 | $12.String = EventArgs 70 | $11.AffectedEntity = CustomEventArgs 71 | $11.VisibilityMask = Public 72 | $11.NamingStyle = PascalCase 73 | $11.IncludeInstanceMembers = True 74 | $11.IncludeStaticEntities = True 75 | $4.NamingRule = $13 76 | $13.Name = Exceptions 77 | $13.RequiredSuffixes = $14 78 | $14.String = Exception 79 | $13.AffectedEntity = CustomExceptions 80 | $13.VisibilityMask = VisibilityMask 81 | $13.NamingStyle = PascalCase 82 | $13.IncludeInstanceMembers = True 83 | $13.IncludeStaticEntities = True 84 | $4.NamingRule = $15 85 | $15.Name = Methods 86 | $15.AffectedEntity = Methods 87 | $15.VisibilityMask = Protected, Public 88 | $15.NamingStyle = PascalCase 89 | $15.IncludeInstanceMembers = True 90 | $15.IncludeStaticEntities = True 91 | $4.NamingRule = $16 92 | $16.Name = Static Readonly Fields 93 | $16.AffectedEntity = ReadonlyField 94 | $16.VisibilityMask = Protected, Public 95 | $16.NamingStyle = PascalCase 96 | $16.IncludeInstanceMembers = False 97 | $16.IncludeStaticEntities = True 98 | $4.NamingRule = $17 99 | $17.Name = Fields 100 | $17.AffectedEntity = Field 101 | $17.VisibilityMask = Protected, Public 102 | $17.NamingStyle = PascalCase 103 | $17.IncludeInstanceMembers = True 104 | $17.IncludeStaticEntities = True 105 | $4.NamingRule = $18 106 | $18.Name = ReadOnly Fields 107 | $18.AffectedEntity = ReadonlyField 108 | $18.VisibilityMask = Protected, Public 109 | $18.NamingStyle = PascalCase 110 | $18.IncludeInstanceMembers = True 111 | $18.IncludeStaticEntities = False 112 | $4.NamingRule = $19 113 | $19.Name = Constant Fields 114 | $19.AffectedEntity = ConstantField 115 | $19.VisibilityMask = Protected, Public 116 | $19.NamingStyle = PascalCase 117 | $19.IncludeInstanceMembers = True 118 | $19.IncludeStaticEntities = True 119 | $4.NamingRule = $20 120 | $20.Name = Properties 121 | $20.AffectedEntity = Property 122 | $20.VisibilityMask = Protected, Public 123 | $20.NamingStyle = PascalCase 124 | $20.IncludeInstanceMembers = True 125 | $20.IncludeStaticEntities = True 126 | $4.NamingRule = $21 127 | $21.Name = Events 128 | $21.AffectedEntity = Event 129 | $21.VisibilityMask = Protected, Public 130 | $21.NamingStyle = PascalCase 131 | $21.IncludeInstanceMembers = True 132 | $21.IncludeStaticEntities = True 133 | $4.NamingRule = $22 134 | $22.Name = Enum Members 135 | $22.AffectedEntity = EnumMember 136 | $22.VisibilityMask = VisibilityMask 137 | $22.NamingStyle = PascalCase 138 | $22.IncludeInstanceMembers = True 139 | $22.IncludeStaticEntities = True 140 | $4.NamingRule = $23 141 | $23.Name = Parameters 142 | $23.AffectedEntity = Parameter 143 | $23.VisibilityMask = VisibilityMask 144 | $23.NamingStyle = CamelCase 145 | $23.IncludeInstanceMembers = True 146 | $23.IncludeStaticEntities = True 147 | $4.NamingRule = $24 148 | $24.Name = Type Parameters 149 | $24.RequiredPrefixes = $25 150 | $25.String = T 151 | $24.AffectedEntity = TypeParameter 152 | $24.VisibilityMask = VisibilityMask 153 | $24.NamingStyle = PascalCase 154 | $24.IncludeInstanceMembers = True 155 | $24.IncludeStaticEntities = True 156 | $0.VersionControlPolicy = $26 157 | $26.inheritsSet = Mono 158 | EndGlobalSection 159 | EndGlobal 160 | -------------------------------------------------------------------------------- /Compass.FilePicker.userprefs: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /Compass.FilePicker/CancelEventHandler.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Compass Informatics 2014, All Right Reserved, http://compass.ie/ 3 | // 4 | // This source is subject to the MIT License. 5 | // Please see the License file for more information. 6 | // All other rights reserved. 7 | // 8 | // THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY 9 | // KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 10 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 11 | // PARTICULAR PURPOSE. 12 | // 13 | // 14 | // Michele Scandura 15 | // mscandura@compass.ie 16 | // 30-04-2014 17 | // Contains a simple Point with floating coordinates. 18 | 19 | namespace Compass.FilePicker 20 | { 21 | /// 22 | /// Event handler for the Cancel event raised by FilePickerFragment 23 | /// 24 | /// The sender. 25 | public delegate void CancelEventHandler(object sender); 26 | } -------------------------------------------------------------------------------- /Compass.FilePicker/Compass.FilePicker.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | {605F69AA-93A8-4AEA-9BBD-BF3AE649506A} 7 | {EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 8 | Library 9 | Properties 10 | Compass.FilePicker 11 | Compass.FilePicker 12 | 512 13 | Resources\Resource.Designer.cs 14 | Off 15 | SAK 16 | SAK 17 | SAK 18 | SAK 19 | v4.0 20 | 21 | 22 | true 23 | full 24 | false 25 | bin\Debug\ 26 | DEBUG;TRACE 27 | prompt 28 | 4 29 | None 30 | 31 | 32 | pdbonly 33 | true 34 | bin\Release\ 35 | TRACE 36 | prompt 37 | 4 38 | false 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | AndroidResource 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | Designer 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | Designer 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 142 | -------------------------------------------------------------------------------- /Compass.FilePicker/Compass.FilePicker.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.30110.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Compass.FilePicker", "Compass.FilePicker.csproj", "{605F69AA-93A8-4AEA-9BBD-BF3AE649506A}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SampleApplication", "..\SampleApplication\SampleApplication.csproj", "{5A266FE2-65AD-46A5-A8FC-DB224FD1CACA}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|Any CPU = Debug|Any CPU 13 | Release|Any CPU = Release|Any CPU 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {605F69AA-93A8-4AEA-9BBD-BF3AE649506A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 17 | {605F69AA-93A8-4AEA-9BBD-BF3AE649506A}.Debug|Any CPU.Build.0 = Debug|Any CPU 18 | {605F69AA-93A8-4AEA-9BBD-BF3AE649506A}.Release|Any CPU.ActiveCfg = Release|Any CPU 19 | {605F69AA-93A8-4AEA-9BBD-BF3AE649506A}.Release|Any CPU.Build.0 = Release|Any CPU 20 | {5A266FE2-65AD-46A5-A8FC-DB224FD1CACA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 21 | {5A266FE2-65AD-46A5-A8FC-DB224FD1CACA}.Debug|Any CPU.Build.0 = Debug|Any CPU 22 | {5A266FE2-65AD-46A5-A8FC-DB224FD1CACA}.Debug|Any CPU.Deploy.0 = Debug|Any CPU 23 | {5A266FE2-65AD-46A5-A8FC-DB224FD1CACA}.Release|Any CPU.ActiveCfg = Release|Any CPU 24 | {5A266FE2-65AD-46A5-A8FC-DB224FD1CACA}.Release|Any CPU.Build.0 = Release|Any CPU 25 | {5A266FE2-65AD-46A5-A8FC-DB224FD1CACA}.Release|Any CPU.Deploy.0 = Release|Any CPU 26 | EndGlobalSection 27 | GlobalSection(SolutionProperties) = preSolution 28 | HideSolutionNode = FALSE 29 | EndGlobalSection 30 | EndGlobal 31 | -------------------------------------------------------------------------------- /Compass.FilePicker/Enums.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Compass Informatics 2014, All Right Reserved, http://compass.ie/ 3 | // 4 | // This source is subject to the MIT License. 5 | // Please see the License file for more information. 6 | // All other rights reserved. 7 | // 8 | // THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY 9 | // KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 10 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 11 | // PARTICULAR PURPOSE. 12 | // 13 | // 14 | // Michele Scandura 15 | // mscandura@compass.ie 16 | // 30-04-2014 17 | // Contains a simple Point with floating coordinates. 18 | 19 | namespace Compass.FilePicker 20 | { 21 | /// 22 | /// Used to set the Filepicker mode 23 | /// 24 | public enum FilePickerMode 25 | { 26 | /// 27 | /// The file 28 | /// 29 | File = 1, 30 | 31 | /// 32 | /// The directory 33 | /// 34 | Directory = 2 35 | } 36 | } -------------------------------------------------------------------------------- /Compass.FilePicker/FileListAdapter.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Compass Informatics 2014, All Right Reserved, http://compass.ie/ 3 | // 4 | // This source is subject to the MIT License. 5 | // Please see the License file for more information. 6 | // All other rights reserved. 7 | // 8 | // THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY 9 | // KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 10 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 11 | // PARTICULAR PURPOSE. 12 | // 13 | // 14 | // Michele Scandura 15 | // mscandura@compass.ie 16 | // 30-04-2014 17 | // Contains a simple Point with floating coordinates. 18 | 19 | using System.Collections.Generic; 20 | using System.IO; 21 | using System.Linq; 22 | 23 | using Android.Content; 24 | using Android.Views; 25 | using Android.Widget; 26 | 27 | namespace Compass.FilePicker 28 | { 29 | /// 30 | /// The file list adapter, used in the file picker 31 | /// 32 | public class FileListAdapter : ArrayAdapter 33 | { 34 | private readonly Context context; 35 | 36 | /// 37 | /// Initializes a new instance of the class. 38 | /// 39 | /// The context. 40 | /// The list of FileSystemInfo containing the directory contents. 41 | public FileListAdapter(Context context, IList fileSystemInfos) 42 | : base(context, Resource.Layout.filepicker_listitem, Android.Resource.Id.Text1, fileSystemInfos) 43 | { 44 | this.context = context; 45 | } 46 | 47 | /// 48 | /// We provide this method to get around some of the //todo fix this comment 49 | /// 50 | /// The directory contents. 51 | public void AddDirectoryContents(IEnumerable directoryContents) 52 | { 53 | Clear(); 54 | // Notify the adapter that things have changed or that there is nothing to display. 55 | var fileSystemInfos = directoryContents as IList ?? directoryContents.ToList(); 56 | if (fileSystemInfos.Any()) 57 | { 58 | AddAll(fileSystemInfos.ToArray()); 59 | NotifyDataSetChanged(); 60 | } 61 | else 62 | { 63 | NotifyDataSetInvalidated(); 64 | } 65 | } 66 | 67 | /// 68 | public override View GetView(int position, View convertView, ViewGroup parent) 69 | { 70 | var fileSystemEntry = GetItem(position); 71 | 72 | FileListRowViewHolder viewHolder; 73 | View row; 74 | if (convertView == null) 75 | { 76 | row = context.GetLayoutInflater().Inflate(Resource.Layout.filepicker_listitem, parent, false); 77 | viewHolder = new FileListRowViewHolder(row.FindViewById(Resource.Id.file_picker_text), row.FindViewById(Resource.Id.file_picker_image)); 78 | row.Tag = viewHolder; 79 | } 80 | else 81 | { 82 | row = convertView; 83 | viewHolder = (FileListRowViewHolder)row.Tag; 84 | } 85 | viewHolder.Update(fileSystemEntry.Name, fileSystemEntry.IsDirectory() ? Resource.Drawable.filepicker_folder : Resource.Drawable.filepicker_file); 86 | return row; 87 | } 88 | } 89 | } -------------------------------------------------------------------------------- /Compass.FilePicker/FileListRowViewHolder.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Compass Informatics 2014, All Right Reserved, http://compass.ie/ 3 | // 4 | // This source is subject to the MIT License. 5 | // Please see the License file for more information. 6 | // All other rights reserved. 7 | // 8 | // THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY 9 | // KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 10 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 11 | // PARTICULAR PURPOSE. 12 | // 13 | // 14 | // Michele Scandura 15 | // mscandura@compass.ie 16 | // 30-04-2014 17 | // Contains a simple Point with floating coordinates. 18 | 19 | using System.Diagnostics.CodeAnalysis; 20 | 21 | using Android.Widget; 22 | 23 | using Java.Lang; 24 | 25 | namespace Compass.FilePicker 26 | { 27 | /// 28 | /// This class is used to hold references to the views contained in a list row. 29 | /// 30 | /// 31 | /// This is an optimization so that we don't have to always look up the 32 | /// ImageView and the TextView for a given row in the ListView. 33 | /// 34 | [SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1121:UseBuiltInTypeAlias", Justification = "Using Java.Lang.Object")] 35 | public class FileListRowViewHolder : Object 36 | { 37 | /// 38 | /// Gets the image view to display the file/folder icon. 39 | /// 40 | /// 41 | /// The image view. 42 | /// 43 | public ImageView IconImageView { get; private set; } 44 | 45 | /// 46 | /// Gets the text view. 47 | /// 48 | /// 49 | /// The text view. 50 | /// 51 | public TextView NameTextView { get; private set; } 52 | 53 | /// 54 | /// Initializes a new instance of the class. 55 | /// 56 | /// The text view. 57 | /// The image view. 58 | public FileListRowViewHolder(TextView textView, ImageView imageView) 59 | { 60 | NameTextView = textView; 61 | IconImageView = imageView; 62 | } 63 | 64 | /// 65 | /// This method will update the TextView and the ImageView with the filename and the file/folder icon 66 | /// 67 | /// Name of the file. 68 | /// The file image resource identifier. 69 | public void Update(string fileName, int fileImageResourceId) 70 | { 71 | NameTextView.Text = fileName; 72 | IconImageView.SetImageResource(fileImageResourceId); 73 | } 74 | } 75 | } -------------------------------------------------------------------------------- /Compass.FilePicker/FilePickerActivity.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Compass Informatics 2014, All Right Reserved, http://compass.ie/ 3 | // 4 | // This source is subject to the MIT License. 5 | // Please see the License file for more information. 6 | // All other rights reserved. 7 | // 8 | // THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY 9 | // KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 10 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 11 | // PARTICULAR PURPOSE. 12 | // 13 | // 14 | // Michele Scandura 15 | // mscandura@compass.ie 16 | // 30-04-2014 17 | // Contains a simple Point with floating coordinates. 18 | 19 | using Android.App; 20 | using Android.Content; 21 | using Android.OS; 22 | using Android.Views; 23 | 24 | namespace Compass.FilePicker 25 | { 26 | /// 27 | /// The File picker activity 28 | /// 29 | [Activity(Label = "Pictures folder")] 30 | public class FilePickerActivity : Activity 31 | { 32 | /** 33 | * Extra to define the path of the directory that will be shown first. 34 | * If it is not sent or if path denotes a non readable/writable directory 35 | * or it is not a directory, it defaults to 36 | * {@link android.os.Environment#getExternalStorageDirectory()} 37 | */ 38 | 39 | /// 40 | /// The extra new dir name 41 | /// 42 | public const string ExtraNewDirName = "directory_name"; 43 | 44 | /// 45 | /// The extra initial directory 46 | /// 47 | public const string ExtraInitialDirectory = "initial_directory"; 48 | 49 | /// 50 | /// The file picker mode (File or Directory) 51 | /// 52 | public const string ExtraMode = "mode"; 53 | 54 | /// 55 | /// The result selected dir 56 | /// 57 | public const string ResultSelectedDir = "selected_dir"; 58 | 59 | /// 60 | /// The result code dir selected 61 | /// 62 | public const int ResultCodeDirSelected = 1; 63 | 64 | private FilePickerFragment fragment; 65 | 66 | /// 67 | protected override void OnCreate(Bundle bundle) 68 | { 69 | base.OnCreate(bundle); 70 | SetupActionBar(); 71 | SetContentView(Resource.Layout.filepicker_mainactivity); 72 | 73 | var newDirName = Intent.GetStringExtra(ExtraNewDirName); 74 | var initialDir = Intent.GetStringExtra(ExtraInitialDirectory); 75 | var filePickerMode = (FilePickerMode)Intent.GetIntExtra(ExtraMode, 1); 76 | 77 | if (bundle == null) 78 | { 79 | fragment = new FilePickerFragment(initialDir, newDirName, filePickerMode); 80 | fragment.Cancel += sender => 81 | { 82 | SetResult(Result.Canceled); 83 | Finish(); 84 | }; 85 | 86 | fragment.FileSelected += (sender, path) => 87 | { 88 | var intent = new Intent(); 89 | intent.PutExtra(ResultSelectedDir, path); 90 | SetResult(Result.Ok, intent); // should be firstuser? 91 | Finish(); 92 | }; 93 | FragmentManager.BeginTransaction().Add(Resource.Id.filepicker_main, fragment).Commit(); 94 | } 95 | } 96 | 97 | private void SetupActionBar() 98 | { 99 | // there might not be an ActionBar, for example when started in Theme.Holo.Dialog.NoActionBar theme 100 | var actionBar = ActionBar; 101 | if (actionBar != null) 102 | { 103 | actionBar.SetDisplayHomeAsUpEnabled(true); 104 | } 105 | } 106 | 107 | /// 108 | public override bool OnOptionsItemSelected(IMenuItem item) 109 | { 110 | var itemId = item.ItemId; 111 | if (itemId == Android.Resource.Id.Home) 112 | { 113 | SetResult(Result.Canceled); 114 | Finish(); 115 | return true; 116 | } 117 | return base.OnOptionsItemSelected(item); 118 | } 119 | } 120 | } -------------------------------------------------------------------------------- /Compass.FilePicker/FilePickerFileObserver.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Compass Informatics 2014, All Right Reserved, http://compass.ie/ 3 | // 4 | // This source is subject to the MIT License. 5 | // Please see the License file for more information. 6 | // All other rights reserved. 7 | // 8 | // THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY 9 | // KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 10 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 11 | // PARTICULAR PURPOSE. 12 | // 13 | // 14 | // Michele Scandura 15 | // mscandura@compass.ie 16 | // 30-04-2014 17 | // Contains a simple Point with floating coordinates. 18 | 19 | using System; 20 | 21 | using Android.OS; 22 | using Android.Runtime; 23 | 24 | namespace Compass.FilePicker 25 | { 26 | public delegate void OnFileEventHandler(FileObserverEvents e, string path); 27 | 28 | public class FilePickerFileObserver : FileObserver 29 | { 30 | /// 31 | public event OnFileEventHandler OnFileEvent; 32 | 33 | /// 34 | public FilePickerFileObserver(IntPtr javaReference, JniHandleOwnership transfer) 35 | : base(javaReference, transfer) 36 | { 37 | } 38 | 39 | /// 40 | public FilePickerFileObserver(string path) 41 | : base(path) 42 | { 43 | } 44 | 45 | /// 46 | public FilePickerFileObserver(string path, FileObserverEvents mask) 47 | : base(path, mask) 48 | { 49 | } 50 | 51 | /// 52 | public override void OnEvent(FileObserverEvents e, string path) 53 | { 54 | OnFileEvent(e, path); 55 | } 56 | } 57 | } -------------------------------------------------------------------------------- /Compass.FilePicker/FilePickerFragment.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Compass Informatics 2014, All Right Reserved, http://compass.ie/ 3 | // 4 | // This source is subject to the MIT License. 5 | // Please see the License file for more information. 6 | // All other rights reserved. 7 | // 8 | // THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY 9 | // KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 10 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 11 | // PARTICULAR PURPOSE. 12 | // 13 | // 14 | // Michele Scandura 15 | // mscandura@compass.ie 16 | // 30-04-2014 17 | // Contains a simple Point with floating coordinates. 18 | 19 | using System; 20 | using System.Collections.Generic; 21 | using System.IO; 22 | using System.Linq; 23 | 24 | using Android.App; 25 | using Android.OS; 26 | using Android.Util; 27 | using Android.Views; 28 | using Android.Widget; 29 | 30 | using Java.Lang; 31 | 32 | using Enum = System.Enum; 33 | using Environment = Android.OS.Environment; 34 | using Exception = System.Exception; 35 | using File = Java.IO.File; 36 | 37 | namespace Compass.FilePicker 38 | { 39 | /// 40 | /// A DialogFragment that will show the files and subdirectories of a given directory. 41 | /// 42 | public class FilePickerFragment : DialogFragment 43 | { 44 | private const string ArgInitialDir = "ArgInitialDirectory"; 45 | private const string ArgNewDirectoryName = "ArgNewDirectoryName"; 46 | private const string ArgMode = "ArgMode"; 47 | private const string LogTag = "Compass.FilePicker.FileListFragment"; 48 | private const string KeyCurrentDirectory = "KeyCurrentDirectory"; 49 | 50 | private Button btnCancel; 51 | private Button btnConfirm; 52 | private DirectoryInfo currentDirectory; 53 | private File selectedFile; 54 | private FileListAdapter adapter; 55 | private FilePickerMode filePickerMode; 56 | private ImageButton btnCreateFolder; 57 | private ImageButton btnLevelUp; 58 | private ListView listFiles; 59 | private FilePickerFileObserver fileObserver; 60 | private string initialDirectory; 61 | private string newDirectoryName; 62 | 63 | /// 64 | /// Occurs when the user press the Confirm button. 65 | /// 66 | public event FileSelectedEventHandler FileSelected; 67 | 68 | /// 69 | /// Occurs when the user press the Cancel button. 70 | /// 71 | public event CancelEventHandler Cancel; 72 | 73 | /// 74 | /// Initializes a new instance of the class. 75 | /// 76 | public FilePickerFragment() 77 | : this(null, null) 78 | { 79 | } 80 | 81 | /// 82 | /// Initializes a new instance of the class. 83 | /// 84 | /// The initial dirrectory. 85 | /// The filepicker mode. 86 | public FilePickerFragment(string initialDir, FilePickerMode mode = FilePickerMode.File) 87 | : this(initialDir, null, mode) 88 | { 89 | } 90 | 91 | /// 92 | /// Initializes a new instance of the class. 93 | /// 94 | /// The initial dirrectory. 95 | /// Default name for new folders. 96 | /// The filepicker mode. 97 | public FilePickerFragment(string initialDir, string newDirName, FilePickerMode mode = FilePickerMode.File) 98 | { 99 | var args = new Bundle(); 100 | args.PutString(ArgNewDirectoryName, newDirName ?? string.Empty); 101 | args.PutString(ArgInitialDir, initialDir ?? string.Empty); 102 | args.PutInt(ArgMode, (int)mode); 103 | Arguments = args; 104 | } 105 | 106 | /// 107 | public override void OnCreate(Bundle savedInstanceState) 108 | { 109 | base.OnCreate(savedInstanceState); 110 | if (Arguments == null) 111 | { 112 | throw new IllegalArgumentException("You must create DirectoryChooserFragment via the FileListFragment(string, string, FilePickerMode) constructor."); 113 | } 114 | 115 | newDirectoryName = Arguments.GetString(ArgNewDirectoryName); 116 | initialDirectory = Arguments.GetString(ArgInitialDir); 117 | filePickerMode = (FilePickerMode)Arguments.GetInt(ArgMode); 118 | 119 | if (savedInstanceState != null) 120 | { 121 | initialDirectory = savedInstanceState.GetString(KeyCurrentDirectory); 122 | } 123 | 124 | if (ShowsDialog) 125 | { 126 | SetStyle(DialogFragmentStyle.NoTitle, 0); 127 | } 128 | else 129 | { 130 | SetHasOptionsMenu(true); 131 | } 132 | } 133 | 134 | /// 135 | public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 136 | { 137 | System.Diagnostics.Debug.Assert(Activity != null, "Activity != null"); 138 | var view = inflater.Inflate(Resource.Layout.filepicker_fragment, container, false); 139 | 140 | btnConfirm = view.FindViewById