/// <summary> /// The newline string for a particular input stream. /// </summary> /// <param name="stream"> /// A <see cref="GLib.DataInputStream"/> /// </param> /// <returns> /// A <see cref="System.String"/> /// </returns> public static string NewLineString(this GLib.DataInputStream stream) { switch (stream.NewlineType) { case DataStreamNewlineType.Cr: return("\r"); case DataStreamNewlineType.Lf: return("\n"); case DataStreamNewlineType.CrLf: return("\r\n"); // this is a safe default because \n is the common line ending on *nix default: return("\n"); } }
void DataRead (GLib.Object obj, GLib.AsyncResult res) { File file = FileAdapter.GetObject (obj); Regex keyValueRegex = new Regex ( @"(^(\s)*(?<Key>([^\=^\n]+))[\s^\n]*\=(\s)*(?<Value>([^\n]+(\n){0,1})))", RegexOptions.IgnorePatternWhitespace | RegexOptions.Compiled | RegexOptions.CultureInvariant ); using (DataInputStream stream = new DataInputStream (file.ReadFinish (res))) { ulong len; string line; while ((line = stream.ReadLine (out len, null)) != null) { line = line.Trim (); Match match = keyValueRegex.Match (line); if (match.Success) { string key = match.Groups["Key"].Value; string val = match.Groups["Value"].Value; if (key.Equals (NameTag)) { Name = val; } else if (key.Equals (DescTag)) { Description = val; } else if (key.Equals (AppUriTag)) { AppUri = val; } else if (key.Equals (IconTag)) { if (val.StartsWith ("./") && val.Length > 2) { IconFile = file.Parent.GetChild (val.Substring (2)); if (IconFile.Exists) Icon = DockServices.Drawing.LoadIcon (IconFile.Path + ";;extension"); } else { Icon = DockServices.Drawing.LoadIcon (val + ";;extension", 128); } } } } } OnDataReady (); }
void BuildExecStrings () { ItemsByExec = new Dictionary<string, List<DesktopItem>> (); foreach (DesktopItem item in DesktopItems) { if (item == null || item.Ignored || !item.HasAttribute ("Exec")) continue; string exec = item.GetString ("Exec").Trim (); string vexec = null; // for openoffice if (exec.Contains (' ') && (exec.StartsWith ("ooffice") || exec.StartsWith ("openoffice") || exec.StartsWith ("soffice") || exec.Contains ("/ooffice ") || exec.Contains ("/openoffice.org ") || exec.Contains ("/soffice "))) { vexec = "ooffice" + exec.Split (' ')[1]; vexec = vexec.Replace ("--", "-"); // for libreoffice } else if (exec.Contains (' ') && (exec.StartsWith ("libreoffice"))) { vexec = "libreoffice" + exec.Split (' ')[1]; vexec = vexec.Replace ("--", "-"); // for wine apps } else if ((exec.Contains ("env WINEPREFIX=") && exec.Contains (" wine ")) || exec.Contains ("wine ")) { int startIndex = exec.IndexOf ("wine ") + 5; // length of 'wine ' // CommandLineForPid already splits based on \\ and takes the last entry, so do the same here vexec = exec.Substring (startIndex).Split (new[] { @"\\" }, StringSplitOptions.RemoveEmptyEntries).Last (); // remove the trailing " and anything after it if (vexec.Contains ("\"")) vexec = vexec.Substring (0, vexec.IndexOf ("\"")); // for crossover apps } else if (exec.Contains (".cxoffice") || (item.HasAttribute ("X-Created-By") && item.GetString ("X-Created-By").Contains ("cxoffice"))) { // The exec is actually another file that uses exec to launch the actual app. exec = exec.Replace ("\"", ""); GLib.File launcher = GLib.FileFactory.NewForPath (exec); if (!launcher.Exists) { Log<DesktopItemService>.Warn ("Crossover launcher decoded as: {0}, but does not exist.", launcher.Path); continue; } string execLine = ""; using (GLib.DataInputStream stream = new GLib.DataInputStream (launcher.Read (null))) { ulong len; string line; try { while ((line = stream.ReadLine (out len, null)) != null) { if (line.StartsWith ("exec")) { execLine = line; break; } } } catch (Exception e) { Log<DesktopItemService>.Error ("Error reading crossover launher: {0}", e.Message); Log<DesktopItemService>.Error (e.StackTrace); continue; } } // if no exec line was found, bail if (string.IsNullOrEmpty (execLine)) continue; // get the relevant part from the execLine string[] parts = execLine.Split (new[] { '\"' }); // find the part that contains C:/path/to/app.lnk if (parts.Any (part => part.StartsWith ("C:"))) { vexec = parts.First (part => part.StartsWith ("C:")); // and take only app.lnk (this is what is exposed to ps -ef) vexec = ExecForPath (vexec); } else { continue; } // other apps } else { string[] parts = exec.Split (' '); vexec = parts .DefaultIfEmpty (null) .Select (part => ExecForPath (part)) .Where (part => !DockServices.WindowMatcher.PrefixFilters.Any (f => f.IsMatch (part))) .FirstOrDefault (); // for AIR apps if (vexec != null && vexec.Contains ('\'')) { vexec = vexec.Replace ("'", ""); } } if (vexec == null) continue; if (!ItemsByExec.ContainsKey (vexec)) ItemsByExec [vexec] = new List<DesktopItem> (); ItemsByExec [vexec].Add (item); foreach (Regex f in DockServices.WindowMatcher.SuffixFilters) { if (f.IsMatch (vexec)) { string vexecStripped = f.Replace (vexec, ""); if (!ItemsByExec.ContainsKey (vexecStripped)) ItemsByExec [vexecStripped] = new List<DesktopItem> (); ItemsByExec [vexecStripped].Add (item); } } } }
void BuildExecStrings() { ItemsByExec = new Dictionary <string, List <DesktopItem> > (); foreach (DesktopItem item in DesktopItems) { if (item == null || item.Ignored || !item.HasAttribute("Exec")) { continue; } string exec = item.GetString("Exec").Trim(); string vexec = null; // for openoffice if (exec.Contains(' ') && (exec.StartsWith("ooffice") || exec.StartsWith("openoffice") || exec.StartsWith("soffice") || exec.Contains("/ooffice ") || exec.Contains("/openoffice.org ") || exec.Contains("/soffice "))) { vexec = "ooffice" + exec.Split(' ')[1]; vexec = vexec.Replace("--", "-"); // for libreoffice } else if (exec.Contains(' ') && (exec.StartsWith("libreoffice"))) { vexec = "libreoffice" + exec.Split(' ')[1]; vexec = vexec.Replace("--", "-"); // for wine apps } else if ((exec.Contains("env WINEPREFIX=") && exec.Contains(" wine ")) || exec.Contains("wine ")) { int startIndex = exec.IndexOf("wine ") + 5; // length of 'wine ' // CommandLineForPid already splits based on \\ and takes the last entry, so do the same here vexec = exec.Substring(startIndex).Split(new[] { @"\\" }, StringSplitOptions.RemoveEmptyEntries).Last(); // remove the trailing " and anything after it if (vexec.Contains("\"")) { vexec = vexec.Substring(0, vexec.IndexOf("\"")); } // for crossover apps } else if (exec.Contains(".cxoffice") || (item.HasAttribute("X-Created-By") && item.GetString("X-Created-By").Contains("cxoffice"))) { // The exec is actually another file that uses exec to launch the actual app. exec = exec.Replace("\"", ""); GLib.File launcher = GLib.FileFactory.NewForPath(exec); if (!launcher.Exists) { Log <DesktopItemService> .Warn("Crossover launcher decoded as: {0}, but does not exist.", launcher.Path); continue; } string execLine = ""; using (GLib.DataInputStream stream = new GLib.DataInputStream(launcher.Read(null))) { ulong len; string line; try { while ((line = stream.ReadLine(out len, null)) != null) { if (line.StartsWith("exec")) { execLine = line; break; } } } catch (Exception e) { Log <DesktopItemService> .Error("Error reading crossover launher: {0}", e.Message); Log <DesktopItemService> .Error(e.StackTrace); continue; } } // if no exec line was found, bail if (string.IsNullOrEmpty(execLine)) { continue; } // get the relevant part from the execLine string[] parts = execLine.Split(new[] { '\"' }); // find the part that contains C:/path/to/app.lnk if (parts.Any(part => part.StartsWith("C:"))) { vexec = parts.First(part => part.StartsWith("C:")); // and take only app.lnk (this is what is exposed to ps -ef) vexec = ExecForPath(vexec); } else { continue; } // other apps } else { string[] parts = exec.Split(' '); vexec = parts .DefaultIfEmpty(null) .Select(part => ExecForPath(part)) .Where(part => !DockServices.WindowMatcher.PrefixFilters.Any(f => f.IsMatch(part))) .FirstOrDefault(); // for AIR apps if (vexec != null && vexec.Contains('\'')) { vexec = vexec.Replace("'", ""); } } if (vexec == null) { continue; } if (!ItemsByExec.ContainsKey(vexec)) { ItemsByExec [vexec] = new List <DesktopItem> (); } ItemsByExec [vexec].Add(item); foreach (Regex f in DockServices.WindowMatcher.SuffixFilters) { if (f.IsMatch(vexec)) { string vexecStripped = f.Replace(vexec, ""); if (!ItemsByExec.ContainsKey(vexecStripped)) { ItemsByExec [vexecStripped] = new List <DesktopItem> (); } ItemsByExec [vexecStripped].Add(item); } } } }
public override bool RemoveItem (AbstractDockItem item) { if (!ItemCanBeRemoved (item)) return false; FileDockItem bookmark = item as FileDockItem; if (!bookmark.OwnedFile.Exists) return false; File tempFile = FileFactory.NewForPath (System.IO.Path.GetTempFileName ()); using (DataInputStream reader = new DataInputStream (BookmarksFile.Read (null))) { using (DataOutputStream writer = new DataOutputStream (tempFile.AppendTo (FileCreateFlags.None, null))) { string line; ulong length; while ((line = reader.ReadLine (out length, null)) != null) { if (line.Split (' ')[0] != bookmark.Uri) { writer.PutString (string.Format ("{0}{1}", line, reader.NewLineString ()), null); } else { items.Remove (bookmark); Items = InnerItems; Log<BookmarksItemProvider>.Debug ("Removing '{0}'", bookmark.HoverText); } } } } if (tempFile.Exists) tempFile.Move (BookmarksFile, FileCopyFlags.Overwrite, null, null); return true; }
protected override AbstractDockItem OnAcceptDrop (string uri) { File tempFile = FileFactory.NewForPath (System.IO.Path.GetTempFileName ()); FileDockItem bookmark = FileDockItem.NewFromUri (uri); // make sure the bookmarked location actually exists if (!bookmark.OwnedFile.Exists) return null; using (DataInputStream reader = new DataInputStream (BookmarksFile.Read (null))) { using (DataOutputStream writer = new DataOutputStream (tempFile.AppendTo (FileCreateFlags.None, null))) { string line; ulong length; while ((line = reader.ReadLine (out length, null)) != null) writer.PutString (string.Format ("{0}{1}", line, reader.NewLineString ()), null); writer.PutString (string.Format ("{0}{1}", bookmark.Uri, reader.NewLineString ()), null); } } items.Add (bookmark); Items = InnerItems; if (tempFile.Exists) tempFile.Move (BookmarksFile, FileCopyFlags.Overwrite, null, null); return bookmark; }
void UpdateItems () { List<AbstractDockItem> old = items; items = new List<AbstractDockItem> (); Log<BookmarksItemProvider>.Debug ("Updating bookmarks."); if (!BookmarksFile.QueryExists (null)) { Log<BookmarksItemProvider>.Error ("File '{0} does not exist.", BookmarksFile); return; } using (DataInputStream stream = new DataInputStream (BookmarksFile.Read (null))) { ulong length; string line, name, uri; while ((line = stream.ReadLine (out length, null)) != null) { uri = line.Split (' ').First (); File bookmark = FileFactory.NewForUri (uri); name = line.Substring (uri.Length).Trim (); if (old.Cast<FileDockItem> ().Any (fdi => fdi.Uri == uri)) { FileDockItem item = old.Cast<FileDockItem> ().First (fdi => fdi.Uri == uri); old.Remove (item); items.Add (item); item.ForcedHoverText = name; } else if (bookmark.StringUri ().StartsWith ("file://") && !bookmark.Exists) { Log<BookmarksItemProvider>.Warn ("Bookmark path '{0}' does not exist, please fix the bookmarks file", bookmark.StringUri ()); continue; } else { FileDockItem item = FileDockItem.NewFromUri (bookmark.StringUri (), name, "folder"); if (item != null) items.Add (item); } } } Items = InnerItems; foreach (AbstractDockItem item in old) item.Dispose (); }