3
* GNOME Do is the legal property of its developers. Please refer to the
4
* COPYRIGHT file distributed with this
7
* This program is free software: you can redistribute it and/or modify
8
* it under the terms of the GNU General Public License as published by
9
* the Free Software Foundation, either version 3 of the License, or
10
* (at your option) any later version.
12
* This program is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
* GNU General Public License for more details.
17
* You should have received a copy of the GNU General Public License
18
* along with this program. If not, see <http://www.gnu.org/licenses/>.
23
using System.Collections.Generic;
27
namespace Do.Universe {
30
/// Indexes files recursively starting in a specific directory.
32
public class FileItemSource : IItemSource {
36
IEnumerable<DirectoryLevelPair> dirs;
38
struct DirectoryLevelPair {
39
public string Directory;
42
public DirectoryLevelPair (string dir, int levels)
44
Directory = dir.Replace ("~", Paths.UserHome);
49
static string ConfigFile {
51
return Paths.Combine (Paths.ApplicationData,
52
"FileItemSource.config");
56
static DirectoryLevelPair [] DefaultDirectories {
58
return new DirectoryLevelPair [] {
59
new DirectoryLevelPair ("/home", 1),
60
new DirectoryLevelPair (Paths.UserHome, 1),
61
new DirectoryLevelPair (Desktop, 1),
62
new DirectoryLevelPair (Documents, 3),
67
static IEnumerable<IItem> GtkBookmarkItems {
71
List<IItem> bookmarks;
74
bookmarks = new List<IItem> ();
76
reader = File.OpenText (
77
Path.Combine (Paths.UserHome, ".gtk-bookmarks"));
82
while (null != (line = reader.ReadLine ())) {
83
if (!line.StartsWith ("file://")) continue;
84
line = line.Substring ("file://".Length);
85
if (File.Exists (line) || Directory.Exists (line))
86
bookmarks.Add (new FileItem (line));
92
public FileItemSource ()
94
dirs = Deserialize ();
95
items = new List<IItem> ();
96
include_hidden = false;
101
static IEnumerable<DirectoryLevelPair> Deserialize ()
103
List<DirectoryLevelPair> dirs;
105
if (!File.Exists (ConfigFile)) {
106
Serialize (DefaultDirectories);
107
return DefaultDirectories;
110
dirs = new List<DirectoryLevelPair> ();
111
if (File.Exists (ConfigFile)) {
113
foreach (string line in File.ReadAllLines (ConfigFile)) {
115
if (line.Trim ().StartsWith ("#")) continue;
116
parts = line.Trim ().Split (':');
117
if (parts.Length != 2) continue;
118
dirs.Add (new DirectoryLevelPair (parts [0].Trim (),
119
int.Parse (parts [1].Trim ())));
121
} catch (Exception e) {
122
Console.Error.WriteLine (
123
"Error reading FileItemSource config file {0}: {1}",
124
ConfigFile, e.Message);
130
static void Serialize (IEnumerable<DirectoryLevelPair> dirs)
132
string configDir = Path.GetDirectoryName (ConfigFile);
134
if (!Directory.Exists (configDir))
135
Directory.CreateDirectory (configDir);
136
foreach (DirectoryLevelPair pair in dirs) {
137
File.AppendAllText (ConfigFile,
138
string.Format ("{0}: {1}\n", pair.Directory,
141
} catch (Exception e) {
142
Console.Error.WriteLine (
143
"Error saving FileItemSource config file {0}: {1}",
144
ConfigFile, e.Message);
148
public Type [] SupportedItemTypes {
158
get { return "File Indexer"; }
161
public string Description {
163
return string.Format ("Frequently used files and folders.");
168
get { return "folder"; }
171
public ICollection<IItem> Items {
172
get { return items; }
175
public ICollection<IItem> ChildrenOfItem (IItem item)
178
List<IItem> children;
180
if (item is ITextItem) {
181
string path = (item as ITextItem).Text;
182
path = path.Replace ("~", Paths.UserHome);
183
if (!Directory.Exists (path)) return null;
184
fi = new FileItem (path);
186
fi = item as IFileItem;
188
children = new List<IItem> ();
189
if (FileItem.IsDirectory (fi)) {
190
foreach (string path in
191
Directory.GetFileSystemEntries (fi.Path)) {
192
children.Add (new FileItem (path));
198
public void UpdateItems ()
201
items.AddRange (GtkBookmarkItems);
202
foreach (DirectoryLevelPair dir in dirs) {
203
ReadItems (dir.Directory, dir.Levels);
208
/// Create items for files found in a given directory. Recurses a
209
/// given number of levels deep into nested directories.
211
/// <param name="dir">
212
/// A <see cref="System.String"/> containing the absolute path
213
/// to the directory to read FileItems from.
215
/// <param name="levels">
216
/// A <see cref="System.Int32"/> specifying the number of levels
217
/// of nested directories to explore.
219
protected virtual void ReadItems (string dir, int levels)
223
string [] directories;
225
if (levels == 0) return;
228
files = Directory.GetFiles (dir);
229
directories = Directory.GetDirectories (dir);
233
foreach (string file in files) {
234
// Ignore system/hidden files.
235
if (!include_hidden && FileItem.IsHidden (file)) continue;
237
item = new FileItem (file);
240
foreach (string directory in directories) {
241
if (!include_hidden && FileItem.IsHidden (directory)) continue;
243
item = new FileItem (directory);
245
ReadItems (directory, levels - 1);
249
static string Music {
251
return Paths.ReadXdgUserDir ("XDG_MUSIC_DIR", "Music");
255
static string Pictures {
257
return Paths.ReadXdgUserDir ("XDG_PICTURES_DIR", "Pictures");
261
static string Videos {
263
return Paths.ReadXdgUserDir ("XDG_VIDEOS_DIR", "Videos");
267
static string Desktop {
269
return Paths.ReadXdgUserDir ("XDG_DESKTOP_DIR", "Desktop");
273
static string Downloads {
275
return Paths.ReadXdgUserDir ("XDG_DOWNLOAD_DIR", "Downloads");
279
static string Documents {
281
return Paths.ReadXdgUserDir ("XDG_DOCUMENTS_DIR", "Documents");