From c626cdfcce2921c2ee6b5fa9ee931a97cea59471 Mon Sep 17 00:00:00 2001 From: Hylke Bons Date: Wed, 5 May 2010 01:17:08 +0100 Subject: [PATCH] rename stuff and add separate bubble class --- SparkleShare/Main.cs | 100 ++++ SparkleShare/Repository.cs | 460 ++++++++++++++++++ SparkleShare/SparkleBubble.cs | 31 ++ SparkleShare/SparkleShare.csproj | 42 ++ ...hareStatusIcon.cs => SparkleStatusIcon.cs} | 4 +- SparkleShare/SparkleUI.cs | 116 +++++ ...SparkleShareWindow.cs => SparkleWindow.cs} | 25 +- 7 files changed, 762 insertions(+), 16 deletions(-) create mode 100644 SparkleShare/Main.cs create mode 100644 SparkleShare/Repository.cs create mode 100644 SparkleShare/SparkleBubble.cs create mode 100644 SparkleShare/SparkleShare.csproj rename SparkleShare/{SparkleShareStatusIcon.cs => SparkleStatusIcon.cs} (92%) create mode 100644 SparkleShare/SparkleUI.cs rename SparkleShare/{SparkleShareWindow.cs => SparkleWindow.cs} (96%) diff --git a/SparkleShare/Main.cs b/SparkleShare/Main.cs new file mode 100644 index 00000000..6ae1b363 --- /dev/null +++ b/SparkleShare/Main.cs @@ -0,0 +1,100 @@ +// SparkleShare, an instant update workflow to Git. +// Copyright (C) 2010 Hylke Bons +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using Gtk; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Net; +using System.Security.Cryptography; +using System.Text; +using System.Text.RegularExpressions; +using System.Timers; + +namespace SparkleShare { + + // This is SparkleShare! + public class SparkleShare { + + public static SparkleUI SparkleUI; + + public static void Main (string [] args) { + + // Check if git is installed + Process Process = new Process(); + Process.StartInfo.RedirectStandardOutput = true; + Process.StartInfo.UseShellExecute = false; + Process.StartInfo.FileName = "git"; + Process.Start(); + if (Process.StandardOutput.ReadToEnd().IndexOf ("version") == -1) { + Console.WriteLine ("Git wasn't found."); + Console.WriteLine ("You can get it from http://git-scm.com/."); + Environment.Exit (0); + } + + // Don't allow running as root + Process.StartInfo.FileName = "whoami"; + Process.Start(); + if (Process.StandardOutput.ReadToEnd().Trim ().Equals ("root")) { + Console.WriteLine ("Sorry, you can't run SparkleShare as root."); + Console.WriteLine ("Things will go utterly wrong."); + Environment.Exit (0); + } + + // Parse the command line arguments + bool HideUI = false; + if (args.Length > 0) { + foreach (string Argument in args) { + if (Argument.Equals ("--disable-gui") || Argument.Equals ("-d")) + HideUI = true; + if (Argument.Equals ("--help") || Argument.Equals ("-h")) { + ShowHelp (); + } + } + } + + Gtk.Application.Init (); + + SparkleUI = new SparkleUI (HideUI); + SparkleUI.StartMonitoring (); + + Gtk.Application.Run (); + + } + + public static void ShowHelp () { + Console.WriteLine ("SparkleShare Copyright (C) 2010 Hylke Bons"); + Console.WriteLine (""); + Console.WriteLine ("This program comes with ABSOLUTELY NO WARRANTY."); + Console.WriteLine ("This is free software, and you are welcome to redistribute it "); + Console.WriteLine ("under certain conditions. Please read the GNU GPLv3 for details."); + Console.WriteLine (""); + Console.WriteLine ("SparkleShare syncs the ~/SparkleShare folder with remote repositories."); + Console.WriteLine (""); + Console.WriteLine ("Usage: sparkleshare [start|stop|restart] [OPTION]..."); + Console.WriteLine ("Sync SparkleShare folder with remote repositories."); + Console.WriteLine (""); + Console.WriteLine ("Arguments:"); + Console.WriteLine ("\t -d, --disable-gui\tDon't show the notification icon."); + Console.WriteLine ("\t -h, --help\t\tDisplay this help text."); + Console.WriteLine (""); + Environment.Exit (0); + } + + } + +} diff --git a/SparkleShare/Repository.cs b/SparkleShare/Repository.cs new file mode 100644 index 00000000..15a423d4 --- /dev/null +++ b/SparkleShare/Repository.cs @@ -0,0 +1,460 @@ +// SparkleShare, an instant update workflow to Git. +// Copyright (C) 2010 Hylke Bons +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using Gtk; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Net; +using System.Security.Cryptography; +using System.Text; +using System.Text.RegularExpressions; +using System.Timers; + +namespace SparkleShare { + + // Repository class holds repository information and timers + public class Repository { + + private Process Process; + private Timer FetchTimer; + private Timer BufferTimer; + private FileSystemWatcher Watcher; + + public string Name; + public string Domain; + public string LocalPath; + public string RemoteOriginUrl; + public string CurrentHash; + + public string UserEmail; + public string UserName; + public bool MonitorOnly; + + public Repository (string Path) { + + MonitorOnly = false; + + Process = new Process(); + Process.EnableRaisingEvents = false; + Process.StartInfo.RedirectStandardOutput = true; + Process.StartInfo.UseShellExecute = false; + + // Get the repository's path, example: "/home/user/SparkleShare/repo/" + LocalPath = Path; + Process.StartInfo.WorkingDirectory = LocalPath + "/"; + + // Get user.name, example: "User Name" + UserName = "Anonymous"; + Process.StartInfo.FileName = "git"; + Process.StartInfo.Arguments = "config --get user.name"; + Process.Start(); + UserName = Process.StandardOutput.ReadToEnd().Trim (); + + // Get user.email, example: "user@github.com" + UserEmail = "not.set@git-scm.com"; + Process.StartInfo.FileName = "git"; + Process.StartInfo.Arguments = "config --get user.email"; + Process.Start(); + UserEmail = Process.StandardOutput.ReadToEnd().Trim (); + + // Get remote.origin.url, example: "ssh://git@github.com/user/repo" + Process.StartInfo.FileName = "git"; + Process.StartInfo.Arguments = "config --get remote.origin.url"; + Process.Start(); + RemoteOriginUrl = Process.StandardOutput.ReadToEnd().Trim (); + + // Get the repository name, example: "Project" + + string s = LocalPath.TrimEnd ( "/".ToCharArray ()); + Name = LocalPath.Substring (s.LastIndexOf ("/") + 1); + + // Get the domain, example: "github.com" + Domain = RemoteOriginUrl; + Domain = Domain.Substring (Domain.IndexOf ("@") + 1); + if (Domain.IndexOf (":") > -1) + Domain = Domain.Substring (0, Domain.IndexOf (":")); + else + Domain = Domain.Substring (0, Domain.IndexOf ("/")); + + // Get hash of the current commit + Process.StartInfo.FileName = "git"; + Process.StartInfo.Arguments = "rev-list --max-count=1 HEAD"; + Process.Start(); + CurrentHash = Process.StandardOutput.ReadToEnd().Trim (); + + // Watch the repository's folder + Watcher = new FileSystemWatcher (LocalPath); + Watcher.IncludeSubdirectories = true; + Watcher.EnableRaisingEvents = true; + Watcher.Filter = "*"; + Watcher.Changed += new FileSystemEventHandler(OnFileActivity); + Watcher.Created += new FileSystemEventHandler(OnFileActivity); + Watcher.Deleted += new FileSystemEventHandler(OnFileActivity); + + // Fetch remote changes every 20 seconds + FetchTimer = new Timer (); + FetchTimer.Interval = 20000; + FetchTimer.Elapsed += delegate { + Fetch (); + + }; + + FetchTimer.Start(); + BufferTimer = new Timer (); + + // Add everything that changed + // since SparkleShare was stopped + Add (); + + + } + + // Starts a time buffer when something changes + public void OnFileActivity (object o, FileSystemEventArgs args) { + WatcherChangeTypes wct = args.ChangeType; + if (!ShouldIgnore (args.Name) && !MonitorOnly) { + Console.WriteLine("[Event][" + Name + "] " + wct.ToString() + + " '" + args.Name + "'"); + StartBufferTimer (); + } + } + + // A buffer that will fetch changes after + // file activity has settles down + public void StartBufferTimer () { + + int Interval = 2000; + if (!BufferTimer.Enabled) { + + // Delay for a few seconds to see if more files change + BufferTimer.Interval = Interval; + BufferTimer.Elapsed += delegate (object o, ElapsedEventArgs args) { + Console.WriteLine ("[Buffer][" + Name + "] Done waiting."); + Add (); + }; + Console.WriteLine ("[Buffer][" + Name + "] " + + "Waiting for more changes..."); + + BufferTimer.Start(); + } else { + + // Extend the delay when something changes + BufferTimer.Close (); + BufferTimer = new Timer (); + BufferTimer.Interval = Interval; + BufferTimer.Elapsed += delegate (object o, ElapsedEventArgs args) { + Console.WriteLine ("[Buffer][" + Name + "] Done waiting."); + Add (); + }; + + BufferTimer.Start(); + Console.WriteLine ("[Buffer][" + Name + "] " + + "Waiting for more changes..."); + + } + + } + + // Clones a remote repo + public void Clone () { + Process.StartInfo.Arguments = "clone " + RemoteOriginUrl; + Process.Start(); + + // Add a gitignore file + TextWriter Writer = new StreamWriter(LocalPath + ".gitignore"); + Writer.WriteLine("*~"); // Ignore gedit swap files + Writer.WriteLine(".*.sw?"); // Ignore vi swap files + Writer.Close(); + } + + // Stages the made changes + public void Add () { + BufferTimer.Stop (); + Console.WriteLine ("[Git][" + Name + "] Staging changes..."); + Process.StartInfo.Arguments = "add --all"; + Process.Start(); + + string Message = FormatCommitMessage (); + if (!Message.Equals ("")) { + Commit (Message); + Push (); + Fetch (); + // Push again in case of a conflict + Push (); + } + } + + // Commits the made changes + public void Commit (string Message) { + Console.WriteLine ("[Commit][" + Name + "] " + Message); + Console.WriteLine ("[Git][" + Name + "] Commiting changes..."); + Process.StartInfo.Arguments = "commit -m \"" + Message + "\""; + Process.Start(); + ShowEventBubble (UserName + " " + Message, + GetAvatarFileName (UserEmail, 48), true); + } + + // Fetches changes from the remote repo + public void Fetch () { + // TODO: change status icon to sync + FetchTimer.Stop (); + Console.WriteLine ("[Git][" + Name + "] Fetching changes..."); + Process.StartInfo.Arguments = "fetch"; + Process.Start(); + Process.WaitForExit (); + Merge (); + FetchTimer.Start (); + } + + // Merges the fetched changes + public void Merge () { + Watcher.EnableRaisingEvents = false; + + Console.WriteLine ("[Git][" + Name + "] Merging fetched changes..."); + + Process.StartInfo.Arguments = "merge origin/master"; + Process.Start(); + Process.WaitForExit (); + string Output = Process.StandardOutput.ReadToEnd().Trim (); + + // Show notification if there are updates + if (!Output.Equals ("Already up-to-date.")) { + + // Get the last commit message + Process.StartInfo.Arguments = "log --format=\"%ae\" -1"; + Process.Start(); + string LastCommitEmail = Process.StandardOutput.ReadToEnd().Trim (); + + // Get the last commit message + Process.StartInfo.Arguments = "log --format=\"%s\" -1"; + Process.Start(); + string LastCommitMessage = Process.StandardOutput.ReadToEnd().Trim (); + + // Get the last commiter + Process.StartInfo.Arguments = "log --format=\"%an\" -1"; + Process.Start(); + string LastCommitUserName = Process.StandardOutput.ReadToEnd().Trim (); + + ShowEventBubble (LastCommitUserName + " " + LastCommitMessage, + GetAvatarFileName (LastCommitEmail, 48), true); + + } + + Watcher.EnableRaisingEvents = true; + // TODO: change status icon to normal + } + + // Pushes the changes to the remote repo + public void Push () { + // TODO: What happens when network disconnects during a push + Console.WriteLine ("[Git][" + Name + "] Pushing changes..."); + Process.StartInfo.Arguments = "push"; + Process.Start(); + Process.WaitForExit (); + } + + // Ignores Repos, dotfiles, swap files and the like. + public bool ShouldIgnore (string FileName) { + if (FileName.Substring (0, 1).Equals (".") || + FileName.Contains (".lock") || + FileName.Contains (".git") || + FileName.Contains ("/.") || + Directory.Exists (LocalPath + FileName)) + return true; // Yes, ignore it. + else if (FileName.Length > 3 && + FileName.Substring (FileName.Length - 4).Equals (".swp")) + return true; + else return false; + } + + // Creates a pretty commit message based on what has changed + public string FormatCommitMessage () { + + bool DoneAddCommit = false; + bool DoneEditCommit = false; + bool DoneRenameCommit = false; + bool DoneDeleteCommit = false; + int FilesAdded = 0; + int FilesEdited = 0; + int FilesRenamed = 0; + int FilesDeleted = 0; + + Process.StartInfo.Arguments = "status"; + Process.Start(); + string Output = Process.StandardOutput.ReadToEnd(); + + foreach (string Line in Regex.Split (Output, "\n")) { + if (Line.IndexOf ("new file:") > -1) + FilesAdded++; + if (Line.IndexOf ("modified:") > -1) + FilesEdited++; + if (Line.IndexOf ("renamed:") > -1) + FilesRenamed++; + if (Line.IndexOf ("deleted:") > -1) + FilesDeleted++; + } + + foreach (string Line in Regex.Split (Output, "\n")) { + + // Format message for when files are added, + // example: "added 'file' and 3 more." + if (Line.IndexOf ("new file:") > -1 && !DoneAddCommit) { + DoneAddCommit = true; + if (FilesAdded > 1) + return "added ‘" + + Line.Replace ("#\tnew file:", "").Trim () + + "’ and " + (FilesAdded - 1) + " more."; + else + return "added ‘" + + Line.Replace ("#\tnew file:", "").Trim () + "’."; + } + + // Format message for when files are edited, + // example: "edited 'file'." + if (Line.IndexOf ("modified:") > -1 && !DoneEditCommit) { + DoneEditCommit = true; + if (FilesEdited > 1) + return "edited ‘" + + Line.Replace ("#\tmodified:", "").Trim () + + "’ and " + (FilesEdited - 1) + " more."; + else + return "edited ‘" + + Line.Replace ("#\tmodified:", "").Trim () + "’."; + } + + // Format message for when files are edited, + // example: "deleted 'file'." + if (Line.IndexOf ("deleted:") > -1 && !DoneDeleteCommit) { + DoneDeleteCommit = true; + if (FilesDeleted > 1) + return "deleted ‘" + + Line.Replace ("#\tdeleted:", "").Trim () + + "’ and " + (FilesDeleted - 1) + " more."; + else + return "deleted ‘" + + Line.Replace ("#\tdeleted:", "").Trim () + "’."; + } + + // Format message for when files are renamed, + // example: "renamed 'file' to 'new name'." + if (Line.IndexOf ("renamed:") > -1 && !DoneRenameCommit) { + DoneDeleteCommit = true; + if (FilesRenamed > 1) + return "renamed ‘" + + Line.Replace ("#\trenamed:", "").Trim ().Replace + (" -> ", "’ to ‘") + "’ and " + (FilesDeleted - 1) + + " more."; + else + return "renamed ‘" + + Line.Replace ("#\trenamed:", "").Trim ().Replace + (" -> ", "’ to ‘") + "’."; + } + + } + + // Nothing happened: + return ""; + + } + + // Shows a notification with text and image + public void ShowEventBubble (string Title, + string IconFileName, + bool ShowButtons) { + + SparkleBubble StuffChangedBubble = new SparkleBubble (Title, ""); + StuffChangedBubble.Icon = new Gdk.Pixbuf (IconFileName); + + // Add a button to open the folder where the changed file is + if (ShowButtons) + StuffChangedBubble.AddAction ("", "Open Folder", + delegate { + Process.StartInfo.FileName = "xdg-open"; + Process.StartInfo.Arguments = LocalPath; + Process.Start(); + Process.StartInfo.FileName = "git"; + } ); + } + + + + public static string GetAvatarFileName (string Email, int Size) { + + string AvatarPath = Environment.GetEnvironmentVariable("HOME") + + "/.config/sparkleshare/avatars/" + + Size + "x" + Size + "/"; + + if (!Directory.Exists (AvatarPath)) { + Directory.CreateDirectory (AvatarPath); + Console.WriteLine ("[Config] Created '" + AvatarPath + "'"); + + } + string AvatarFile = AvatarPath + Email; + + if (File.Exists (AvatarFile)) + return AvatarFile; + + else { + + // Let's try to get the person's gravatar for next time + + WebClient WebClient = new WebClient (); + Uri GravatarUri = new Uri ("http://www.gravatar.com/avatar/" + + GetMD5 (Email) + ".jpg?s=" + Size + "&d=404"); + + string TmpFile = "/tmp/" + Email + Size; + + if (!File.Exists (TmpFile)) { + + WebClient.DownloadFileAsync (GravatarUri, TmpFile); + WebClient.DownloadFileCompleted += delegate { + File.Delete (AvatarPath + Email); + FileInfo TmpFileInfo = new FileInfo (TmpFile); + if (TmpFileInfo.Length > 255) + File.Move (TmpFile, AvatarPath + Email); + }; + + } + + string FallbackFileName = "/usr/share/icons/hicolor/" + + Size + "x" + Size + + "/status/avatar-default.png"; + + if (File.Exists (FallbackFileName)) + return FallbackFileName; + else + return "/usr/share/icons/hicolor/16x16/status/avatar-default.png"; + } + + } + + // Helper that creates an MD5 hash + public static string GetMD5 (string s) { + + MD5 md5 = new MD5CryptoServiceProvider (); + Byte[] Bytes = ASCIIEncoding.Default.GetBytes (s); + Byte[] EncodedBytes = md5.ComputeHash (Bytes); + + return BitConverter.ToString(EncodedBytes).ToLower ().Replace ("-", ""); + + } + + } + + +} diff --git a/SparkleShare/SparkleBubble.cs b/SparkleShare/SparkleBubble.cs new file mode 100644 index 00000000..9ed4d264 --- /dev/null +++ b/SparkleShare/SparkleBubble.cs @@ -0,0 +1,31 @@ +// SparkleShare, an instant update workflow to Git. +// Copyright (C) 2010 Hylke Bons +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using Notifications; + +namespace SparkleShare { + + public class SparkleBubble : Notification { + + public SparkleBubble (string Title, string Subtext) : base (Title, Subtext) { + Timeout = 4500; + Urgency = Urgency.Normal; + Show (); + } + + } + +} diff --git a/SparkleShare/SparkleShare.csproj b/SparkleShare/SparkleShare.csproj new file mode 100644 index 00000000..696a2313 --- /dev/null +++ b/SparkleShare/SparkleShare.csproj @@ -0,0 +1,42 @@ + + + + Debug + AnyCPU + 8.0.50727 + {728483AA-E34B-4441-BF2C-C8BC2901E4E0} + Exe + SparkleShare + 2.0 + + + true + full + false + bin\Debug + DEBUG + prompt + 4 + + + none + false + bin\Release + prompt + 4 + + + + + + + + + + + + + + + + diff --git a/SparkleShare/SparkleShareStatusIcon.cs b/SparkleShare/SparkleStatusIcon.cs similarity index 92% rename from SparkleShare/SparkleShareStatusIcon.cs rename to SparkleShare/SparkleStatusIcon.cs index 35016c90..ba520712 100644 --- a/SparkleShare/SparkleShareStatusIcon.cs +++ b/SparkleShare/SparkleStatusIcon.cs @@ -28,9 +28,9 @@ using System.Timers; namespace SparkleShare { - public class SparkleShareStatusIcon : StatusIcon { + public class SparkleStatusIcon : StatusIcon { - public SparkleShareStatusIcon () : base () { + public SparkleStatusIcon () : base () { IconName = "folder-sparkleshare"; diff --git a/SparkleShare/SparkleUI.cs b/SparkleShare/SparkleUI.cs new file mode 100644 index 00000000..e38e95b3 --- /dev/null +++ b/SparkleShare/SparkleUI.cs @@ -0,0 +1,116 @@ +// SparkleShare, an instant update workflow to Git. +// Copyright (C) 2010 Hylke Bons +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using Gtk; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Net; +using System.Security.Cryptography; +using System.Text; +using System.Text.RegularExpressions; +using System.Timers; + +namespace SparkleShare { + + // Holds the status icon, window and repository list + public class SparkleUI { + + public SparkleWindow SparkleWindow; + public SparkleStatusIcon SparkleStatusIcon; + public Repository [] Repositories; + + public SparkleUI (bool HideUI) { + + Process Process = new Process(); + Process.EnableRaisingEvents = false; + Process.StartInfo.RedirectStandardOutput = true; + Process.StartInfo.UseShellExecute = false; + + // Get home folder, example: "/home/user/" + string UserHome = Environment.GetEnvironmentVariable("HOME") + "/"; + + // Create 'SparkleShare' folder in the user's home folder + string ReposPath = UserHome + "SparkleShare"; + if (!Directory.Exists (ReposPath)) { + Directory.CreateDirectory (ReposPath); + Console.WriteLine ("[Config] Created '" + ReposPath + "'"); + + Process.StartInfo.FileName = "gvfs-set-attribute"; + Process.StartInfo.Arguments = ReposPath + " metadata::custom-icon " + + "file://usr/share/icons/hicolor/48x48/places/folder-sparkleshare"; + Process.Start(); + + } + + // Create place to store configuration user's home folder + string ConfigPath = UserHome + ".config/sparkleshare/"; + if (!Directory.Exists (ConfigPath)) { + + Directory.CreateDirectory (ConfigPath); + Console.WriteLine ("[Config] Created '" + ConfigPath + "'"); + + // Create a first run file to show the intro message + File.Create (ConfigPath + "firstrun"); + Console.WriteLine ("[Config] Created '" + ConfigPath + "firstrun'"); + + // Create a place to store the avatars + Directory.CreateDirectory (ConfigPath + "avatars/"); + Console.WriteLine ("[Config] Created '" + ConfigPath + "avatars'"); + + } + + // Get all the repos in ~/SparkleShare + string [] Repos = Directory.GetDirectories (ReposPath); + Repositories = new Repository [Repos.Length]; + + int i = 0; + foreach (string Folder in Repos) { + Repositories [i] = new Repository (Folder); + i++; + } + + // Don't create the window and status + // icon when --disable-gui was given + if (!HideUI) { + + // Create the window + SparkleWindow = new SparkleWindow (Repositories); + SparkleWindow.DeleteEvent += CloseSparkleWindow; + + // Create the status icon + SparkleStatusIcon = new SparkleStatusIcon (); + SparkleStatusIcon.Activate += delegate { + SparkleWindow.ToggleVisibility (); + }; + + } + + } + + // Closes the window + public void CloseSparkleWindow (object o, DeleteEventArgs args) { + SparkleWindow = new SparkleWindow (Repositories); + SparkleWindow.DeleteEvent += CloseSparkleWindow; + } + + public void StartMonitoring () { } + public void StopMonitoring () { } + + } + +} diff --git a/SparkleShare/SparkleShareWindow.cs b/SparkleShare/SparkleWindow.cs similarity index 96% rename from SparkleShare/SparkleShareWindow.cs rename to SparkleShare/SparkleWindow.cs index af6605f4..cafa6add 100644 --- a/SparkleShare/SparkleShareWindow.cs +++ b/SparkleShare/SparkleWindow.cs @@ -15,7 +15,6 @@ // along with this program. If not, see . using Gtk; -using Notifications; using SparkleShare; using System; using System.Collections.Generic; @@ -29,7 +28,7 @@ using System.Timers; namespace SparkleShare { - public class SparkleShareWindow : Window { + public class SparkleWindow : Window { private bool Visibility; private VBox LayoutVerticalLeft; @@ -40,23 +39,21 @@ namespace SparkleShare { private ListStore ReposStore; private Repository [] Repositories; - public SparkleShareWindow (Repository [] R) : base ("SparkleShare") { + public SparkleWindow (Repository [] R) : base ("SparkleShare") { Repositories = R; // Show a notification if there are no folders yet if (Repositories.Length == 0) { - Notification Notification; - Notification = new Notification ("Welcome to SparkleShare!", - "You don't have any folders " + - "configured yet."); - Notification.AddAction ("", "Add a Folder", - delegate { CreateAddDialog (); } ); + SparkleBubble NoFoldersBubble; + NoFoldersBubble = new SparkleBubble ("Welcome to SparkleShare!", + "You don't have any folders " + + "configured yet."); + + NoFoldersBubble.AddAction ("", "Add a Folder", + delegate { CreateAddDialog (); } ); - Notification.Urgency = Urgency.Normal; - Notification.Timeout = 7500; - Notification.Show (); } else { @@ -440,11 +437,11 @@ namespace SparkleShare { public void CreateAddDialog () { - Window AddDialog = new Window ("Add Folder"); + Window AddDialog = new Window (""); AddDialog.SetPosition (WindowPosition.Center); // AddDialog.SetSizeRequest (320, 200); AddDialog.BorderWidth = 6; - + AddDialog.IconName = "folder-sparkleshare"; Label NameLabel = new Label ("Folder Name: "); Entry NameEntry = new Entry ();