Merge lp:~cszikszoy/docky/fixfileinfoleak into lp:docky

Proposed by Chris S.
Status: Merged
Merged at revision: not available
Proposed branch: lp:~cszikszoy/docky/fixfileinfoleak
Merge into: lp:docky
Diff against target: 1005 lines (+453/-253)
8 files modified
Docky.DBus/Docky.DBus/RemoteFileMenuEntry.cs (+5/-5)
Docky.Items/Docky.Items/ApplicationDockItem.cs (+1/-1)
Docky.Items/Docky.Items/FileDockItem.cs (+12/-16)
Docky.Services/Docky.Services/Extensions/GLibFileExtension.cs (+200/-158)
Docky.Services/Docky.Services/Helper.cs (+2/-2)
Docky.Services/Docky.Services/Logging/LogBase.cs (+2/-1)
Docky.Services/Docky.Services/NativeInterop.cs (+229/-68)
StandardPlugins/Trash/src/TrashDockItem.cs (+2/-2)
To merge this branch: bzr merge lp:~cszikszoy/docky/fixfileinfoleak
Reviewer Review Type Date Requested Status
Docky Core Pending
Review via email: mp+22921@code.launchpad.net
To post a comment you must log in.
lp:~cszikszoy/docky/fixfileinfoleak updated
1230. By Chris S.

fix emblems

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'Docky.DBus/Docky.DBus/RemoteFileMenuEntry.cs'
--- Docky.DBus/Docky.DBus/RemoteFileMenuEntry.cs 2009-12-14 20:14:43 +0000
+++ Docky.DBus/Docky.DBus/RemoteFileMenuEntry.cs 2010-04-07 03:54:28 +0000
@@ -28,7 +28,7 @@
28 public class RemoteFileMenuEntry : RemoteMenuEntry28 public class RemoteFileMenuEntry : RemoteMenuEntry
29 {29 {
3030
31 public RemoteFileMenuEntry (uint id, GLib.File file, string groupTitle) : base (id, file.Basename, "", groupTitle)31 public RemoteFileMenuEntry (uint id, GLib.File file, string groupTitle) : base(id, file.Basename, "", groupTitle)
32 {32 {
33 Clicked += delegate {33 Clicked += delegate {
34 DockServices.System.Open (file);34 DockServices.System.Open (file);
@@ -36,11 +36,11 @@
36 36
37 // only check the icon if it's mounted (ie: .Path != null)37 // only check the icon if it's mounted (ie: .Path != null)
38 if (!string.IsNullOrEmpty (file.Path)) {38 if (!string.IsNullOrEmpty (file.Path)) {
39 string thumbnailPath = file.QueryStringAttr ("thumbnail::path");39 string thumbnailPath = file.QueryInfo<string> ("thumbnail::path");
40 if (string.IsNullOrEmpty (thumbnailPath))40 if (!string.IsNullOrEmpty (thumbnailPath))
41 Icon = DockServices.Drawing.IconFromGIcon (file.Icon ());41 Icon = thumbnailPath;
42 else42 else
43 Icon = thumbnailPath;43 Icon = file.Icon ();
44 }44 }
45 45
46 if (string.IsNullOrEmpty (Icon))46 if (string.IsNullOrEmpty (Icon))
4747
=== modified file 'Docky.Items/Docky.Items/ApplicationDockItem.cs'
--- Docky.Items/Docky.Items/ApplicationDockItem.cs 2010-04-06 05:37:09 +0000
+++ Docky.Items/Docky.Items/ApplicationDockItem.cs 2010-04-07 03:54:28 +0000
@@ -159,7 +159,7 @@
159 return false;159 return false;
160 160
161 foreach (string uri in uris) {161 foreach (string uri in uris) {
162 string mime = GLib.FileFactory.NewForUri (uri).QueryStringAttr ("standard::content-type");162 string mime = GLib.FileFactory.NewForUri (uri).QueryInfo<string> ("standard::content-type");
163 if (mimes.Any (m => GLib.Content.TypeIsA (mime, m) || GLib.Content.TypeEquals (mime, m)))163 if (mimes.Any (m => GLib.Content.TypeIsA (mime, m) || GLib.Content.TypeEquals (mime, m)))
164 return true;164 return true;
165 }165 }
166166
=== modified file 'Docky.Items/Docky.Items/FileDockItem.cs'
--- Docky.Items/Docky.Items/FileDockItem.cs 2010-01-06 05:14:55 +0000
+++ Docky.Items/Docky.Items/FileDockItem.cs 2010-04-07 03:54:28 +0000
@@ -97,10 +97,9 @@
97 97
98 // only check the icon if it's mounted (ie: .Path != null)98 // only check the icon if it's mounted (ie: .Path != null)
99 if (!string.IsNullOrEmpty (OwnedFile.Path)) {99 if (!string.IsNullOrEmpty (OwnedFile.Path)) {
100 string customIconPath = OwnedFile.QueryStringAttr (CustomIconKey);100 string customIconPath = OwnedFile.QueryInfo<string> (CustomIconKey);
101 string thumbnailPath = OwnedFile.QueryStringAttr (ThumbnailPathKey);101 string thumbnailPath = OwnedFile.QueryInfo<string> (ThumbnailPathKey);
102 // emblems are returned as [ e1, e2, e3 ], get those into a nice trimmed string array102 string[] emblems = OwnedFile.QueryInfo<string[]> (EmblemsKey);
103 string rawEmblems = OwnedFile.QueryStringAttr (EmblemsKey);
104 103
105 // if the icon lives inside the folder (or one of its subdirs) then this104 // if the icon lives inside the folder (or one of its subdirs) then this
106 // is actually a relative path... not a file uri.105 // is actually a relative path... not a file uri.
@@ -114,16 +113,13 @@
114 else if (!string.IsNullOrEmpty (thumbnailPath))113 else if (!string.IsNullOrEmpty (thumbnailPath))
115 Icon = thumbnailPath;114 Icon = thumbnailPath;
116 else115 else
117 SetIconFromGIcon (OwnedFile.Icon ());116 Icon = OwnedFile.Icon ();
118 117
119 if (!string.IsNullOrEmpty (rawEmblems)) {118 // process the emblems
120 rawEmblems = rawEmblems.Replace ("[", "").Replace ("]", "");119 if (emblems.Length != 0) {
121
122 int [] emblemPositions = { 2, 1, 0, 3};120 int [] emblemPositions = { 2, 1, 0, 3};
123 int i=0;121 int i=0;
124 rawEmblems.Split (new [] {','})122 emblems.Reverse ()
125 .Select (e => e.Trim ())
126 .Reverse ()
127 .Take (4)123 .Take (4)
128 .ToList ()124 .ToList ()
129 .ForEach (e => {125 .ForEach (e => {
@@ -162,7 +158,7 @@
162 bool can_write;158 bool can_write;
163 // this could fail if we try to call it on an unmounted location159 // this could fail if we try to call it on an unmounted location
164 try {160 try {
165 can_write = OwnedFile.QueryBoolAttr ("access::can-write");161 can_write = OwnedFile.QueryInfo<bool> ("access::can-write");
166 } catch {162 } catch {
167 can_write = false;163 can_write = false;
168 }164 }
@@ -181,12 +177,12 @@
181 177
182 // gather some information first178 // gather some information first
183 long fileSize = file.GetSize ();179 long fileSize = file.GetSize ();
184 ulong freeSpace = OwnedFile.QueryULongAttr (FilesystemFreeKey);180 ulong freeSpace = OwnedFile.QueryInfo<ulong> (FilesystemFreeKey);
185 if ((ulong) fileSize > freeSpace)181 if ((ulong) fileSize > freeSpace)
186 throw new Exception (Catalog.GetString ("Not enough free space on destination."));182 throw new Exception (Catalog.GetString ("Not enough free space on destination."));
187 183
188 string ownedFSID = OwnedFile.QueryStringAttr (FilesystemIDKey);184 string ownedFSID = OwnedFile.QueryInfo<string> (FilesystemIDKey);
189 string destFSID = file.QueryStringAttr (FilesystemIDKey);185 string destFSID = file.QueryInfo<string> (FilesystemIDKey);
190 186
191 string nameAfterMove = file.NewFileName (OwnedFile);187 string nameAfterMove = file.NewFileName (OwnedFile);
192 188
@@ -195,7 +191,7 @@
195 bool performing = true;191 bool performing = true;
196 long cur = 0, tot = 10;192 long cur = 0, tot = 10;
197 193
198 note = Docky.Services.Log.Notify ("", DockServices.Drawing.IconFromGIcon (file.Icon ()), "{0}% " + Catalog.GetString ("Complete") + "...", cur / tot);194 note = Docky.Services.Log.Notify ("", file.Icon (), "{0}% " + Catalog.GetString ("Complete") + "...", cur / tot);
199 GLib.Timeout.Add (250, () => {195 GLib.Timeout.Add (250, () => {
200 note.Body = string.Format ("{0}% ", string.Format ("{0:00.0}", ((float) Math.Min (cur, tot) / tot) * 100)) + Catalog.GetString ("Complete") + "...";196 note.Body = string.Format ("{0}% ", string.Format ("{0:00.0}", ((float) Math.Min (cur, tot) / tot) * 100)) + Catalog.GetString ("Complete") + "...";
201 return performing;197 return performing;
202198
=== modified file 'Docky.Services/Docky.Services/Extensions/GLibFileExtension.cs'
--- Docky.Services/Docky.Services/Extensions/GLibFileExtension.cs 2010-01-21 03:43:55 +0000
+++ Docky.Services/Docky.Services/Extensions/GLibFileExtension.cs 2010-04-07 03:54:28 +0000
@@ -15,6 +15,7 @@
15// along with this program. If not, see <http://www.gnu.org/licenses/>.15// along with this program. If not, see <http://www.gnu.org/licenses/>.
16// 16//
17using System;17using System;
18using IO = System.IO;
18using System.Linq;19using System.Linq;
19using System.Collections.Generic;20using System.Collections.Generic;
2021
@@ -30,7 +31,6 @@
30 return file.Path == other.Path;31 return file.Path == other.Path;
31 }32 }
3233
33
34 public int GetHashCode (File file)34 public int GetHashCode (File file)
35 {35 {
36 return file.Path.GetHashCode ();36 return file.Path.GetHashCode ();
@@ -52,44 +52,77 @@
52 return NativeInterop.StrUri (file);52 return NativeInterop.StrUri (file);
53 }53 }
54 54
55 public static FileInfo QueryInfoSimple (this GLib.File file, string attribute)55 public static T QueryInfo<T> (this GLib.File file, string attribute)
56 {56 {
57 FileInfo info;57 IntPtr info = NativeInterop.GFileQueryInfo (file, attribute, FileQueryInfoFlags.None, null);
58 if (attribute.StartsWith ("filesystem::"))58
59 info = file.QueryFilesystemInfo (attribute, null);59 Type returnType = typeof(T);
60 else60 object ret;
61 info = file.QueryInfo (attribute, FileQueryInfoFlags.None, null);61
62 return info;62 if (returnType == typeof(bool)) {
63 }63 ret = QueryBoolAttr (info, attribute);
64 64 } else if (returnType == typeof(string)) {
65 public static GLib.Icon Icon (this GLib.File file)65 ret = QueryStringAttr (info, attribute);
66 {66 } else if (returnType == typeof(string[])) {
67 return file.QueryInfoSimple ("standard::icon").Icon;67 ret = QueryStringVAttr (info, attribute);
68 }68 } else if (returnType == typeof(uint)) {
69 69 ret = QueryUIntAttr (info, attribute);
70 public static string QueryStringAttr (this GLib.File file, string attribute)70 } else if (returnType == typeof(ulong)) {
71 {71 ret = QueryULongAttr (info, attribute);
72 return file.QueryInfoSimple (attribute).GetAttributeAsString (attribute);72 } else {
73 }73 ret = default(T);
74 74 }
75 public static uint QueryUintAttr (this GLib.File file, string attribute)75
76 {76 NativeInterop.GObjectUnref (info);
77 return file.QueryInfoSimple (attribute).GetAttributeUInt (attribute);77
78 } 78 return (T) ret;
79 79 }
80 public static bool QueryBoolAttr (this GLib.File file, string attribute)80
81 {81 public static string Icon (this GLib.File file)
82 return file.QueryInfoSimple (attribute).GetAttributeBoolean (attribute);82 {
83 }83 IntPtr info = NativeInterop.GFileQueryInfo (file, "standard::icon", FileQueryInfoFlags.None, null);
84 84 GLib.Icon icon = NativeInterop.GFileInfoIcon (info);
85 public static ulong QueryULongAttr (this GLib.File file, string attribute)85 string iconName = DockServices.Drawing.IconFromGIcon (icon);
86 {86 NativeInterop.GObjectUnref (info);
87 return file.QueryInfoSimple (attribute).GetAttributeULong (attribute);87 return iconName;
88 }
89
90 static long Size (this GLib.File file)
91 {
92 IntPtr info = NativeInterop.GFileQueryInfo (file, "standard::size", FileQueryInfoFlags.None, null);
93 long size = NativeInterop.GFileInfoSize (info);
94 NativeInterop.GObjectUnref (info);
95 return size;
96 }
97
98 static string QueryStringAttr (IntPtr info, string attribute)
99 {
100 return NativeInterop.GFileInfoQueryString (info, attribute);
101 }
102
103 static string[] QueryStringVAttr (IntPtr info, string Attribute)
104 {
105 return NativeInterop.GFileInfoQueryStringV (info, Attribute);
106 }
107
108 static uint QueryUIntAttr (IntPtr info, string attribute)
109 {
110 return NativeInterop.GFileInfoQueryUInt (info, attribute);
111 }
112
113 static bool QueryBoolAttr (IntPtr info, string attribute)
114 {
115 return NativeInterop.GFileInfoQueryBool (info, attribute);
116 }
117
118 static ulong QueryULongAttr (IntPtr info, string attribute)
119 {
120 return NativeInterop.GFileInfoQueryULong (info, attribute);
88 }121 }
89122
90 public static FileType QueryFileType (this GLib.File file)123 public static FileType QueryFileType (this GLib.File file)
91 {124 {
92 return file.QueryInfoSimple ("standard::type").FileType;125 return file.QueryFileType (0, null);
93 }126 }
94 127
95 // Recursively list all of the subdirs for a given directory128 // Recursively list all of the subdirs for a given directory
@@ -101,28 +134,11 @@
101 // list all of the subdirs for a given directory134 // list all of the subdirs for a given directory
102 public static IEnumerable<GLib.File> SubDirs (this GLib.File file, bool recurse)135 public static IEnumerable<GLib.File> SubDirs (this GLib.File file, bool recurse)
103 {136 {
104 FileEnumerator enumerator = file.EnumerateChildren ("standard::type,standard::name,access::can-read", FileQueryInfoFlags.NofollowSymlinks, null);137 if (!IO.Directory.Exists (file.Path))
105
106 if (enumerator == null)
107 return Enumerable.Empty<GLib.File> ();138 return Enumerable.Empty<GLib.File> ();
108 139
109 FileInfo info;140 return IO.Directory.GetDirectories (file.Path, "*", recurse == false ? IO.SearchOption.TopDirectoryOnly : IO.SearchOption.AllDirectories)
110 List<GLib.File> dirs = new List<GLib.File> ();141 .Select (subdir => GLib.FileFactory.NewForPath (subdir));
111
112 while ((info = enumerator.NextFile ()) != null) {
113 File child = file.GetChild (info.Name);
114
115 if (info.FileType == FileType.Directory && info.GetAttributeBoolean ("access::can-read")) {
116 dirs.Add (child);
117 if (recurse)
118 dirs = dirs.Union (child.SubDirs ()).ToList ();
119 }
120 }
121
122 if (info != null)
123 info.Dispose ();
124 enumerator.Close (null);
125 return dirs.AsEnumerable ();
126 }142 }
127 143
128 public static IEnumerable<GLib.File> GetFiles (this GLib.File file)144 public static IEnumerable<GLib.File> GetFiles (this GLib.File file)
@@ -133,67 +149,76 @@
133 // gets all files under the given GLib.File (directory) with the extension of extension 149 // gets all files under the given GLib.File (directory) with the extension of extension
134 public static IEnumerable<GLib.File> GetFiles (this GLib.File file, string extension)150 public static IEnumerable<GLib.File> GetFiles (this GLib.File file, string extension)
135 {151 {
136 FileEnumerator enumerator = file.EnumerateChildren ("standard::type,standard::name", FileQueryInfoFlags.NofollowSymlinks, null);152 if (!IO.Directory.Exists (file.Path))
137
138 if (enumerator == null)
139 return Enumerable.Empty<GLib.File> ();153 return Enumerable.Empty<GLib.File> ();
140 154
141 FileInfo info;155 return IO.Directory.GetFiles (file.Path, string.Format ("*{0}", extension))
142 List<GLib.File> files = new List<GLib.File> ();156 .Select (f => GLib.FileFactory.NewForPath (f));
143
144 while ((info = enumerator.NextFile ()) != null) {
145 File child = file.GetChild (info.Name);
146
147 if (info.FileType == FileType.Directory)
148 continue;
149
150 if (child.Basename.EndsWith (extension))
151 files.Add (child);
152 }
153
154 if (info != null)
155 info.Dispose ();
156 enumerator.Close (null);
157 return files.AsEnumerable ();
158 }157 }
159 158
160 // This is the recursive equivalent to GLib.File.Delete ()159 /// <summary>
160 /// Recursive equivalent to GLib.File.Delete () when called on a directory.
161 /// Functionally equivalent to GLib.File.Delete when called on files.
162 /// </summary>
163 /// <param name="file">
164 /// A <see cref="GLib.File"/>
165 /// </param>
161 public static void Delete_Recurse (this GLib.File file)166 public static void Delete_Recurse (this GLib.File file)
162 {167 {
163 FileEnumerator enumerator = file.EnumerateChildren ("standard::type,standard::name,access::can-delete", FileQueryInfoFlags.NofollowSymlinks, null);168 if (IO.File.Exists (file.Path)) {
164 169 file.Delete ();
165 if (enumerator == null)
166 return;170 return;
167 171 }
168 FileInfo info;172
169 173 IEnumerable<GLib.File> files = IO.Directory.GetFiles (file.Path, "*", IO.SearchOption.AllDirectories)
170 while ((info = enumerator.NextFile ()) != null) {174 .Select (f => FileFactory.NewForPath (f));
171 File child = file.GetChild (info.Name);175
172 176 foreach (File f in files) {
173 if (info.FileType == FileType.Directory)177 if (f.QueryInfo<bool> ("access::can-delete"))
174 Delete_Recurse (child);178 f.Delete ();
175 179 }
176 if (info.GetAttributeBoolean ("access::can-delete"))
177 child.Delete (null);
178 }
179
180 if (info != null)
181 info.Dispose ();
182 enumerator.Close (null);
183 }180 }
184 181
185 // This is the recursive equivalent of GLib.File.Copy ()182 // This is the recursive equivalent of GLib.File.Copy ()
183 /// <summary>
184 /// Recursive equivalent to GLib.File.Copy () when called on a directory.
185 /// Functionally equivalent to GLib.File.Copy () when called on files.
186 /// </summary>
187 /// <param name="source">
188 /// A <see cref="GLib.File"/>
189 /// </param>
190 /// <param name="dest">
191 /// A <see cref="GLib.File"/>
192 /// </param>
193 /// <param name="flags">
194 /// A <see cref="FileCopyFlags"/>
195 /// </param>
196 /// <param name="progress_cb">
197 /// A <see cref="FileProgressCallback"/>
198 /// </param>
186 public static void Copy_Recurse (this GLib.File source, GLib.File dest, FileCopyFlags flags, FileProgressCallback progress_cb)199 public static void Copy_Recurse (this GLib.File source, GLib.File dest, FileCopyFlags flags, FileProgressCallback progress_cb)
187 {200 {
188 long totalBytes = source.GetSize ();201 long totalBytes = source.GetSize ();
189 long copiedBytes = 0;202 long copiedBytes = 0;
190 203
191 Recursive_Copy (source, dest, ref copiedBytes, totalBytes, progress_cb);204 Recursive_Copy (source, dest, flags, ref copiedBytes, totalBytes, progress_cb);
192 }205 }
193 206
207 /// <summary>
208 /// Indicates whether or not a directory has files.
209 /// </summary>
210 /// <remarks>
211 /// Will return false if called on a file.
212 /// </remarks>
213 /// <param name="file">
214 /// A <see cref="GLib.File"/>
215 /// </param>
216 /// <returns>
217 /// A <see cref="System.Boolean"/>
218 /// </returns>
194 public static bool DirectoryHasFiles (this GLib.File file)219 public static bool DirectoryHasFiles (this GLib.File file)
195 {220 {
196 System.IO.DirectoryInfo dir = new System.IO.DirectoryInfo (file.Path);221 IO.DirectoryInfo dir = new IO.DirectoryInfo (file.Path);
197 222
198 if (dir.GetFiles ().Count () > 0 || dir.GetDirectories ().Count () > 0)223 if (dir.GetFiles ().Count () > 0 || dir.GetDirectories ().Count () > 0)
199 return true;224 return true;
@@ -222,79 +247,66 @@
222 }247 }
223 }248 }
224 249
225 static void Recursive_Copy (GLib.File source, GLib.File dest, ref long copiedBytes, long totalBytes, FileProgressCallback progress_cb)250 static void Recursive_Copy (GLib.File source, GLib.File dest, FileCopyFlags flags, ref long copiedBytes, long totalBytes, FileProgressCallback progress_cb)
226 {251 {
227 if (source.QueryFileType () != FileType.Directory) {252 if (IO.File.Exists (source.Path)) {
228 source.Copy (dest, FileCopyFlags.AllMetadata | FileCopyFlags.NofollowSymlinks, null, (current, total) => {253 source.Copy (dest, flags, null, (current, total) => {
229 progress_cb.Invoke (current, totalBytes);254 progress_cb.Invoke (current, totalBytes);
230 });255 });
231 return;256 return;
232 }257 }
233 258
234 FileEnumerator enumerator = source.EnumerateChildren ("standard::type,standard::name,standard::size", FileQueryInfoFlags.NofollowSymlinks, null);259 foreach (GLib.File subdir in source.SubDirs ()) {
235 260 dest.GetChild (subdir.Basename).MakeDirectoryWithParents (null);
236 if (enumerator == null)261 // if it's a directory, continue the recursion
237 return;262 Recursive_Copy (subdir, dest.GetChild (subdir.Basename), flags, ref copiedBytes, totalBytes, progress_cb);
238 263 }
239 FileInfo info;264
240 265 foreach (File child in source.GetFiles ()) {
241 while ((info = enumerator.NextFile ()) != null) {266 long copied = copiedBytes;
242 File child = source.GetChild (info.Name);
243 267
244 if (info.FileType == FileType.Directory) {268 child.Copy (dest.GetChild (child.Basename), flags, null, (current, total) => {
245 // copy all of the children269 progress_cb.Invoke (copied + current, totalBytes);
246 Recursive_Copy (child, dest.GetChild (info.Name), ref copiedBytes, totalBytes, progress_cb);270 });
247 } else {271 copiedBytes += child.GetSize ();
248 // first create the directory at the destination if it doesn't exist
249 if (!dest.Exists)
250 dest.MakeDirectoryWithParents (null);
251 // this looks crazy making variables here, assigning in the delegate, then reassigning to
252 // copiedBytes, but c# won't let me use out or ref vars in a delegate func.
253 long copied = copiedBytes;
254 // copy
255 child.Copy (dest.GetChild (info.Name), FileCopyFlags.AllMetadata | FileCopyFlags.NofollowSymlinks, null, (current, total) => {
256 progress_cb.Invoke (copied + current, totalBytes);
257 });
258 copiedBytes += info.Size;
259 }
260 }272 }
261
262 if (info != null)
263 info.Dispose ();
264 enumerator.Close (null);
265 }273 }
266 274
267 // will recurse and get the total size in bytes275 // will recurse and get the total size in bytes
276 /// <summary>
277 /// Returns the size in bytes of this file. If called on a directory will return the size
278 /// of all subsequent files recursively.
279 /// </summary>
280 /// <param name="file">
281 /// A <see cref="GLib.File"/>
282 /// </param>
283 /// <returns>
284 /// A <see cref="System.Int64"/>
285 /// </returns>
268 public static long GetSize (this GLib.File file)286 public static long GetSize (this GLib.File file)
269 {287 {
270 FileInfo fileInfo = file.QueryInfo ("standard::type,standard::size", FileQueryInfoFlags.NofollowSymlinks, null);288 // if file is a regular file (not a directory), return the size
271 289 if (IO.File.Exists (file.Path))
272 if (fileInfo.FileType != FileType.Directory)290 return file.Size ();
273 return fileInfo.Size;291
274 292 // otherwise treat it as a directory, and aggregate the size of all files in all subdirs (recursive)
275 long size = 0;293 long size = 0;
276 FileEnumerator enumerator = file.EnumerateChildren ("standard::type,standard::name,standard::size", FileQueryInfoFlags.NofollowSymlinks, null);294 IEnumerable<GLib.File> files = IO.Directory.GetFiles (file.Path, "*", IO.SearchOption.AllDirectories)
277 295 .Select (f => FileFactory.NewForPath (f));
278 if (enumerator == null)296 foreach (File f in files)
279 return 0;297 size += f.GetSize ();
280
281 FileInfo info;
282
283 while ((info = enumerator.NextFile ()) != null) {
284 File child = file.GetChild (info.Name);
285
286 if (info.FileType == FileType.Directory)
287 size += GetSize (child);
288 else
289 size += info.Size;
290 }
291
292 if (info != null)
293 info.Dispose ();
294 enumerator.Close (null);
295 return size;298 return size;
296 }299 }
297 300
301 /// <summary>
302 /// The newline string for a particular input stream.
303 /// </summary>
304 /// <param name="stream">
305 /// A <see cref="GLib.DataInputStream"/>
306 /// </param>
307 /// <returns>
308 /// A <see cref="System.String"/>
309 /// </returns>
298 public static string NewLineString (this GLib.DataInputStream stream)310 public static string NewLineString (this GLib.DataInputStream stream)
299 {311 {
300 switch (stream.NewlineType) {312 switch (stream.NewlineType) {
@@ -310,6 +322,18 @@
310 }322 }
311 }323 }
312 324
325 /// <summary>
326 /// Tries to mount a file with success and failure action callbacks.
327 /// </summary>
328 /// <param name="file">
329 /// A <see cref="GLib.File"/>
330 /// </param>
331 /// <param name="success">
332 /// A <see cref="Action"/> invoked when the mount was successful.
333 /// </param>
334 /// <param name="failed">
335 /// A <see cref="Action"/> invoked when the mount failed.
336 /// </param>
313 public static void MountWithActionAndFallback (this GLib.File file, Action success, Action failed)337 public static void MountWithActionAndFallback (this GLib.File file, Action success, Action failed)
314 {338 {
315 // In rare instances creating a Gtk.MountOperation can fail so let's try to create it first339 // In rare instances creating a Gtk.MountOperation can fail so let's try to create it first
@@ -347,6 +371,15 @@
347 });371 });
348 }372 }
349 373
374 /// <summary>
375 /// Add an action that gets invoked when a file gets mounted.
376 /// </summary>
377 /// <param name="file">
378 /// A <see cref="GLib.File"/>
379 /// </param>
380 /// <param name="action">
381 /// A <see cref="Action"/>
382 /// </param>
350 public static void AddMountAction (this GLib.File file, Action action)383 public static void AddMountAction (this GLib.File file, Action action)
351 {384 {
352 if (!MountActions.ContainsKey (file))385 if (!MountActions.ContainsKey (file))
@@ -354,6 +387,15 @@
354 MountActions [file].Add (action);387 MountActions [file].Add (action);
355 }388 }
356 389
390 /// <summary>
391 /// Removes an action from the mount actions list for this file.
392 /// </summary>
393 /// <param name="file">
394 /// A <see cref="GLib.File"/>
395 /// </param>
396 /// <param name="action">
397 /// A <see cref="Action"/>
398 /// </param>
357 public static void RemoveAction (this GLib.File file, Action action)399 public static void RemoveAction (this GLib.File file, Action action)
358 {400 {
359 if (MountActions.ContainsKey (file) && MountActions [file].Contains (action))401 if (MountActions.ContainsKey (file) && MountActions [file].Contains (action))
360402
=== modified file 'Docky.Services/Docky.Services/Helper.cs'
--- Docky.Services/Docky.Services/Helper.cs 2010-04-05 06:17:47 +0000
+++ Docky.Services/Docky.Services/Helper.cs 2010-04-07 03:54:28 +0000
@@ -101,9 +101,9 @@
101 void Start ()101 void Start ()
102 { 102 {
103 // if the execute bits aren't set, try to set103 // if the execute bits aren't set, try to set
104 if (!File.QueryBoolAttr ("access::can-execute")) {104 if (!File.QueryInfo<bool> ("access::can-execute")) {
105 Log<Helper>.Debug ("Execute permissions are not currently set for '{0}', attempting to set them.", File.Path);105 Log<Helper>.Debug ("Execute permissions are not currently set for '{0}', attempting to set them.", File.Path);
106 uint currentPerm = File.QueryUintAttr ("unix::mode");106 uint currentPerm = File.QueryInfo<uint> ("unix::mode");
107 try {107 try {
108 File.SetAttributeUint32 ("unix::mode", currentPerm | X_PERM, 0, null);108 File.SetAttributeUint32 ("unix::mode", currentPerm | X_PERM, 0, null);
109 // if we can't log the error, and disable this script109 // if we can't log the error, and disable this script
110110
=== modified file 'Docky.Services/Docky.Services/Logging/LogBase.cs'
--- Docky.Services/Docky.Services/Logging/LogBase.cs 2010-01-19 05:25:59 +0000
+++ Docky.Services/Docky.Services/Logging/LogBase.cs 2010-04-07 03:54:28 +0000
@@ -50,7 +50,8 @@
50 "GLib",50 "GLib",
51 "GLib-GObject",51 "GLib-GObject",
52 "Pango",52 "Pango",
53 "GdkPixbuf"53 "GdkPixbuf",
54 "GLib-GIO",
54 };55 };
5556
56 static LogBase ()57 static LogBase ()
5758
=== modified file 'Docky.Services/Docky.Services/NativeInterop.cs'
--- Docky.Services/Docky.Services/NativeInterop.cs 2010-03-25 17:34:22 +0000
+++ Docky.Services/Docky.Services/NativeInterop.cs 2010-04-07 03:54:28 +0000
@@ -16,14 +16,17 @@
16// 16//
1717
18using System;18using System;
19using System.Linq;
19using System.Runtime.InteropServices;20using System.Runtime.InteropServices;
2021
21using GLib;22using GLib;
2223
24using Mono.Unix;
25
23namespace Docky.Services26namespace Docky.Services
24{27{
25 28
26 public class NativeInterop29 internal class NativeInterop
27 { 30 {
28 [DllImport ("gio-2.0")]31 [DllImport ("gio-2.0")]
29 private static extern IntPtr g_file_get_uri (IntPtr fileHandle);32 private static extern IntPtr g_file_get_uri (IntPtr fileHandle);
@@ -51,128 +54,286 @@
51 [DllImport("libgtk-x11-2.0", CallingConvention = CallingConvention.Cdecl)]54 [DllImport("libgtk-x11-2.0", CallingConvention = CallingConvention.Cdecl)]
52 private static extern IntPtr gtk_icon_theme_lookup_by_gicon (IntPtr icon_theme, IntPtr icon, int size, int flags);55 private static extern IntPtr gtk_icon_theme_lookup_by_gicon (IntPtr icon_theme, IntPtr icon, int size, int flags);
5356
57 #region Workaround for GLib.FileInfo leaks...
58
59 // some attributes must be looked up as bytestrings, not strings
60 static readonly string [] BYTE_STRING_VALS = new string [] {
61 "thumbnail::path",
62 "standard::name",
63 "standard::symlink-target",
64 };
65
66 [DllImport("libgio-2.0")]
67 static extern int g_file_info_get_attribute_type(IntPtr raw, string attribute);
68
69 [DllImport("libgobject-2.0")]
70 private static extern IntPtr g_object_ref (IntPtr @object);
71
72 [DllImport("libgobject-2.0")]
73 private static extern void g_object_unref (IntPtr @object);
74
75 [DllImport("libgobject-2.0")]
76 private static extern IntPtr g_file_info_get_name (IntPtr info);
77
78 [DllImport("gio-2.0")]
79 private static extern IntPtr g_file_query_info (IntPtr file, string attributes, int flags, IntPtr cancellable, out IntPtr error);
80
81 [DllImport("gio-2.0")]
82 private static extern IntPtr g_file_query_filesystem_info(IntPtr file, string attributes, IntPtr cancellable, out IntPtr error);
83
84 [DllImport("gio-2.0")]
85 private static extern IntPtr g_file_info_get_attribute_string (IntPtr info, string attribute);
86
87 [DllImport("gio-2.0")]
88 private static extern IntPtr g_file_info_get_attribute_stringv (IntPtr info, string attribute);
89
90 [DllImport("gio-2.0")]
91 private static extern IntPtr g_file_info_get_attribute_byte_string (IntPtr info, string attribute);
92
93 [DllImport("gio-2.0")]
94 static extern uint g_file_info_get_attribute_uint32 (IntPtr info, string attribute);
95
96 [DllImport("gio-2.0")]
97 static extern ulong g_file_info_get_attribute_uint64 (IntPtr info, string attribute);
98
99 [DllImport("gio-2.0")]
100 static extern bool g_file_info_get_attribute_boolean (IntPtr info, string attribute);
101
102 [DllImport("gio-2.0")]
103 static extern long g_file_info_get_size (IntPtr info);
104
105 [DllImport("gio-2.0")]
106 static extern IntPtr g_file_info_get_icon (IntPtr info);
107
108 #endregion
109
110 static readonly string GIO_NOT_FOUND = Catalog.GetString ("Could not find gio-2.0, please report immediately.");
111 static readonly string GOBJECT_NOT_FOUND = Catalog.GetString ("Could not find gobject-2.0, please report immediately.");
112 static readonly string GTK_NOT_FOUND = Catalog.GetString ("Could not find gtk-2.0, please report immediately.");
113
54 public static string StrUri (File file)114 public static string StrUri (File file)
55 {115 {
56 try {116 return NativeHelper<string> (() => {
57 return GLib.Marshaller.PtrToStringGFree (g_file_get_uri (file.Handle));117 return GLib.Marshaller.PtrToStringGFree (g_file_get_uri (file.Handle));
58 } catch (DllNotFoundException e) {118 }, GIO_NOT_FOUND,
59 Log<NativeInterop>.Fatal ("Could not find gio-2.0, please report immediately.");119 string.Format ("Failed to retrieve uri for file '{0}': ", file.Path) + "{0}");
60 Log<NativeInterop>.Info (e.StackTrace);
61 return "";
62 } catch (Exception e) {
63 Log<NativeInterop>.Error ("Failed to retrieve uri for file '{0}': {1}", file.Basename, e.Message);
64 Log<NativeInterop>.Info (e.StackTrace);
65 return "";
66 }
67 }120 }
68121
69 public static int prctl (int option, string arg2)122 public static int prctl (int option, string arg2)
70 {123 {
71 try {124 return NativeHelper<int> (() => {
72 return prctl (option, System.Text.Encoding.ASCII.GetBytes (arg2 + "\0"), IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);125 return prctl (option, System.Text.Encoding.ASCII.GetBytes (arg2 + "\0"), IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
73 } catch (DllNotFoundException e) {126 }, -1, "Could not find libc, please report immediately.",
74 Log<NativeInterop>.Fatal ("Could not find libc, please report immediately.");127 "Failed to set process name: {0}");
75 Log<NativeInterop>.Info (e.StackTrace);
76 return -1;
77 } catch (Exception e) {
78 Log<NativeInterop>.Error ("Failed to set process name: {0}", e.Message);
79 Log<NativeInterop>.Info (e.StackTrace);
80 return -1;
81 }
82 }128 }
83 129
84 public static void UnmountWithOperation (Mount mount, MountUnmountFlags flags, MountOperation op, 130 public static void UnmountWithOperation (Mount mount, MountUnmountFlags flags, MountOperation op,
85 Cancellable cancellable, AsyncReadyCallback cb)131 Cancellable cancellable, AsyncReadyCallback cb)
86 {132 {
87 try {133 NativeHelper (() =>
134 {
88 GLibSharp.AsyncReadyCallbackWrapper cb_wrapper = new GLibSharp.AsyncReadyCallbackWrapper (cb);135 GLibSharp.AsyncReadyCallbackWrapper cb_wrapper = new GLibSharp.AsyncReadyCallbackWrapper (cb);
89 g_mount_unmount_with_operation (mount.Handle, (int) flags, op == null ? IntPtr.Zero : op.Handle, 136 g_mount_unmount_with_operation (mount.Handle, (int) flags, op == null ? IntPtr.Zero : op.Handle,
90 cancellable == null ? IntPtr.Zero : cancellable.Handle, cb_wrapper.NativeDelegate, IntPtr.Zero);137 cancellable == null ? IntPtr.Zero : cancellable.Handle, cb_wrapper.NativeDelegate, IntPtr.Zero);
91 } catch (DllNotFoundException e) {138 }, GIO_NOT_FOUND,
92 Log<NativeInterop>.Fatal ("Could not find gio-2.0, please report immediately.");139 "Failed to unmount with operation: {0}");
93 Log<NativeInterop>.Info (e.StackTrace);
94 return;
95 } catch (Exception e) {
96 Log<NativeInterop>.Error ("Failed to unmount with operation name: {0}", e.Message);
97 Log<NativeInterop>.Info (e.StackTrace);
98 return;
99 }
100 }140 }
101 141
102 public static void EjectWithOperation (Mount mount, MountUnmountFlags flags, MountOperation op, 142 public static void EjectWithOperation (Mount mount, MountUnmountFlags flags, MountOperation op,
103 Cancellable cancellable, AsyncReadyCallback cb)143 Cancellable cancellable, AsyncReadyCallback cb)
104 {144 {
105 try {145 NativeHelper (() =>
146 {
106 GLibSharp.AsyncReadyCallbackWrapper cb_wrapper = new GLibSharp.AsyncReadyCallbackWrapper (cb);147 GLibSharp.AsyncReadyCallbackWrapper cb_wrapper = new GLibSharp.AsyncReadyCallbackWrapper (cb);
107 g_mount_eject_with_operation (mount.Handle, (int) flags, op == null ? IntPtr.Zero : op.Handle, 148 g_mount_eject_with_operation (mount.Handle, (int) flags, op == null ? IntPtr.Zero : op.Handle,
108 cancellable == null ? IntPtr.Zero : cancellable.Handle, cb_wrapper.NativeDelegate, IntPtr.Zero);149 cancellable == null ? IntPtr.Zero : cancellable.Handle, cb_wrapper.NativeDelegate, IntPtr.Zero);
109 } catch (DllNotFoundException e) {150 }, GIO_NOT_FOUND,
110 Log<NativeInterop>.Fatal ("Could not find gio-2.0, please report immediately.");151 "Failed to eject with operation name: {0}");
111 Log<NativeInterop>.Info (e.StackTrace);
112 return;
113 } catch (Exception e) {
114 Log<NativeInterop>.Error ("Failed to eject with operation name: {0}", e.Message);
115 Log<NativeInterop>.Info (e.StackTrace);
116 return;
117 }
118 }152 }
119 153
120 public static bool EjectWithOperationFinish (Mount mount, AsyncResult result)154 public static bool EjectWithOperationFinish (Mount mount, AsyncResult result)
121 {155 {
122 try {156 return NativeHelper<bool> (() =>
157 {
123 IntPtr error = IntPtr.Zero;158 IntPtr error = IntPtr.Zero;
124 bool success = g_mount_eject_with_operation_finish (mount.Handle, result == null ? IntPtr.Zero : 159 bool success = g_mount_eject_with_operation_finish (mount.Handle, result == null ? IntPtr.Zero :
125 ((result is GLib.Object) ? (result as GLib.Object).Handle : (result as GLib.AsyncResultAdapter).Handle), out error);160 ((result is GLib.Object) ? (result as GLib.Object).Handle : (result as GLib.AsyncResultAdapter).Handle), out error);
126 if (error != IntPtr.Zero)161 if (error != IntPtr.Zero)
127 throw new GLib.GException (error);162 throw new GLib.GException (error);
128 return success;163 return success;
129 } catch (DllNotFoundException e) {164 }, false, GIO_NOT_FOUND,
130 Log<NativeInterop>.Fatal ("Could not find gio-2.0, please report immediately.");165 "Failed to eject with operation finish name: {0}");
131 Log<NativeInterop>.Info (e.StackTrace);
132 return false;
133 } catch (Exception e) {
134 Log<NativeInterop>.Error ("Failed to eject with operation finish name: {0}", e.Message);
135 Log<NativeInterop>.Info (e.StackTrace);
136 return false;
137 }
138 }166 }
139 167
140 public static bool UnmountWithOperation (Mount mount, AsyncResult result)168 public static bool UnmountWithOperation (Mount mount, AsyncResult result)
141 {169 {
142 try {170 return NativeHelper<bool> (() =>
171 {
143 IntPtr error = IntPtr.Zero;172 IntPtr error = IntPtr.Zero;
144 bool success = g_mount_unmount_with_operation_finish (mount.Handle, result == null ? IntPtr.Zero : ((result is GLib.Object) ? (result as GLib.Object).Handle : (result as GLib.AsyncResultAdapter).Handle), out error);173 bool success = g_mount_unmount_with_operation_finish (mount.Handle, result == null ? IntPtr.Zero : ((result is GLib.Object) ? (result as GLib.Object).Handle : (result as GLib.AsyncResultAdapter).Handle), out error);
145 if (error != IntPtr.Zero)174 if (error != IntPtr.Zero)
146 throw new GLib.GException (error);175 throw new GLib.GException (error);
147 return success;176 return success;
148 } catch (DllNotFoundException e) {177 }, false, GIO_NOT_FOUND,
149 Log<NativeInterop>.Fatal ("Could not find gio-2.0, please report immediately.");178 "Failed to unmount with operation finish name: {0}");
150 Log<NativeInterop>.Info (e.StackTrace);
151 return false;
152 } catch (Exception e) {
153 Log<NativeInterop>.Error ("Failed to unmount with operation finish name: {0}", e.Message);
154 Log<NativeInterop>.Info (e.StackTrace);
155 return false;
156 }
157 }179 }
158 180
159 public static Gtk.IconInfo IconThemeLookUpByGIcon (Gtk.IconTheme theme, GLib.Icon icon, int size, int flags)181 public static Gtk.IconInfo IconThemeLookUpByGIcon (Gtk.IconTheme theme, GLib.Icon icon, int size, int flags)
160 {182 {
161 try {183 return NativeHelper<Gtk.IconInfo> (() =>
162 IntPtr raw_ret = gtk_icon_theme_lookup_by_gicon(theme.Handle, 184 {
185 IntPtr raw_ret = gtk_icon_theme_lookup_by_gicon (theme.Handle,
163 icon == null ? IntPtr.Zero : ((icon is GLib.Object) ? (icon as GLib.Object).Handle : (icon as GLib.IconAdapter).Handle),186 icon == null ? IntPtr.Zero : ((icon is GLib.Object) ? (icon as GLib.Object).Handle : (icon as GLib.IconAdapter).Handle),
164 size, (int) flags);187 size, (int) flags);
165 Gtk.IconInfo ret = raw_ret == IntPtr.Zero ? null : (Gtk.IconInfo) GLib.Opaque.GetOpaque (raw_ret, typeof (Gtk.IconInfo), true);188 Gtk.IconInfo ret = raw_ret == IntPtr.Zero ? null : (Gtk.IconInfo) GLib.Opaque.GetOpaque (raw_ret, typeof(Gtk.IconInfo), true);
189 return ret;
190 }, null, GTK_NOT_FOUND,
191 "Failed to lookup by GIcon: {0}");
192 }
193
194 #region Workaround for GLib.FileInfo leaks...
195
196 public static IntPtr GFileQueryInfo (GLib.File file, string attributes, FileQueryInfoFlags flags, Cancellable cancellable)
197 {
198 return NativeHelper<IntPtr> (() =>
199 {
200 IntPtr error;
201 IntPtr info;
202 if (attributes.StartsWith ("filesystem::"))
203 info = g_file_query_filesystem_info (file.Handle, attributes,
204 cancellable == null ? IntPtr.Zero : cancellable.Handle, out error);
205 else
206 info = g_file_query_info (file.Handle, attributes, (int) flags,
207 cancellable == null ? IntPtr.Zero : cancellable.Handle, out error);
208
209 if (error != IntPtr.Zero)
210 throw new GException (error);
211 return info;
212 }, IntPtr.Zero, GIO_NOT_FOUND,
213 string.Format ("Failed to query info for '{0}': ", file.Path) + "{0}");
214 }
215
216 public static int GFileInfoQueryAttributeType (IntPtr info, string attribute)
217 {
218 return NativeHelper<int> (() =>
219 {
220 int type = g_file_info_get_attribute_type (info, attribute);
221 return type;
222 }, GIO_NOT_FOUND,
223 string.Format ("Failed to query attribute type '{0}': ", attribute) + "{0}");
224 }
225
226 public static string GFileInfoQueryString (IntPtr info, string attribute)
227 {
228 return NativeHelper<string> (() =>
229 {
230 IntPtr str;
231 if (BYTE_STRING_VALS.Any (s => attribute.StartsWith (s)))
232 str = g_file_info_get_attribute_byte_string (info, attribute);
233 else
234 str = g_file_info_get_attribute_string (info, attribute);
235 return GLib.Marshaller.Utf8PtrToString (str);
236 }, GIO_NOT_FOUND,
237 string.Format ("Failed to query string '{0}': ", attribute) + "{0}");
238 }
239
240 public static string[] GFileInfoQueryStringV (IntPtr info, string attribute)
241 {
242 return NativeHelper<string[]> (() =>
243 {
244 IntPtr strv;
245 strv = g_file_info_get_attribute_stringv (info, attribute);
246 return GLib.Marshaller.NullTermPtrToStringArray (strv, false);
247 }, GIO_NOT_FOUND,
248 string.Format ("Failed to query stringv '{0}': ", attribute) + "{0}");
249 }
250
251 public static uint GFileInfoQueryUInt (IntPtr info, string attribute)
252 {
253 return NativeHelper<uint> (() =>
254 {
255 return g_file_info_get_attribute_uint32 (info, attribute);
256 }, GIO_NOT_FOUND,
257 string.Format ("Failed to query uint '{0}': ", attribute) + "{0}");
258 }
259
260 public static ulong GFileInfoQueryULong (IntPtr info, string attribute)
261 {
262 return NativeHelper<ulong> (() =>
263 {
264 return g_file_info_get_attribute_uint64 (info, attribute);
265 }, GIO_NOT_FOUND,
266 string.Format ("Failed to query uint '{0}': ", attribute) + "{0}");
267 }
268
269 public static bool GFileInfoQueryBool (IntPtr info, string attribute)
270 {
271 return NativeHelper<bool> (() =>
272 {
273 return g_file_info_get_attribute_boolean (info, attribute);
274 }, GIO_NOT_FOUND,
275 string.Format ("Failed to query bool '{0}': ", attribute) + "{0}");
276 }
277
278 public static Icon GFileInfoIcon (IntPtr info)
279 {
280 return NativeHelper<Icon> (() =>
281 {
282 IntPtr icon = g_file_info_get_icon (info);
283 return IconAdapter.GetObject (g_object_ref (icon), false);
284 }, GIO_NOT_FOUND,
285 "Failed to query icon {0}");
286 }
287
288 public static long GFileInfoSize (IntPtr info)
289 {
290 return NativeHelper<long> (() =>
291 {
292 return g_file_info_get_size (info);
293 }, GIO_NOT_FOUND,
294 "Failed to query icon {0}");
295 }
296
297 public static void GObjectUnref (IntPtr objectHandle)
298 {
299 NativeHelper (() =>
300 {
301 if (objectHandle == IntPtr.Zero)
302 return;
303 g_object_unref (objectHandle);
304 }, GOBJECT_NOT_FOUND,
305 "Could not unref object: {0}");
306 }
307
308 #endregion
309
310 static T NativeHelper<T> (Func<T> act, T errorReturn, string notFound, string error)
311 {
312 try {
313 T ret = act.Invoke ();
166 return ret;314 return ret;
167 } catch (DllNotFoundException e) {315 } catch (DllNotFoundException e) {
168 Log<NativeInterop>.Fatal ("Could not find gtk-2.0, please report immediately.");316 Log<NativeInterop>.Fatal (notFound);
169 Log<NativeInterop>.Info (e.StackTrace);317 Log<NativeInterop>.Info (e.StackTrace);
170 return null;318 return errorReturn;
171 } catch (Exception e) {319 } catch (Exception e) {
172 Log<NativeInterop>.Error ("Failed to lookup by GIcon: {0}", e.Message);320 Log<NativeInterop>.Error (error, e.Message);
173 Log<NativeInterop>.Info (e.StackTrace);321 Log<NativeInterop>.Info (e.StackTrace);
174 return null;322 return errorReturn;
175 }323 }
176 }324 }
325
326 static void NativeHelper (Action act, string notFound, string error)
327 {
328 NativeHelper<int> (() => {
329 act.Invoke ();
330 return -1;
331 }, notFound, error);
332 }
333
334 static T NativeHelper<T> (Func<T> act, string notFound, string error)
335 {
336 return NativeHelper<T> (act, default(T), notFound, error);
337 }
177 }338 }
178}339}
179340
=== modified file 'StandardPlugins/Trash/src/TrashDockItem.cs'
--- StandardPlugins/Trash/src/TrashDockItem.cs 2010-03-31 04:28:28 +0000
+++ StandardPlugins/Trash/src/TrashDockItem.cs 2010-04-07 03:54:28 +0000
@@ -36,7 +36,7 @@
36 {36 {
37 uint ItemsInTrash {37 uint ItemsInTrash {
38 get {38 get {
39 return OwnedFile.QueryUintAttr ("trash::item-count");39 return OwnedFile.QueryInfo<uint> ("trash::item-count");
40 }40 }
41 }41 }
42 42
@@ -74,7 +74,7 @@
74 else74 else
75 HoverText = string.Format (Catalog.GetPluralString ("{0} item in Trash", "{0} items in Trash", (int) itemsInTrash), itemsInTrash);75 HoverText = string.Format (Catalog.GetPluralString ("{0} item in Trash", "{0} items in Trash", (int) itemsInTrash), itemsInTrash);
76 76
77 SetIconFromGIcon (OwnedFile.Icon ());77 Icon = OwnedFile.Icon ();
78 }78 }
79 79
80 public override string UniqueID ()80 public override string UniqueID ()

Subscribers

People subscribed via source and target branches

to status/vote changes: