From 5a9b7d4ba6a0adfcbdb67095f56807059f3cdb94 Mon Sep 17 00:00:00 2001 From: Hylke Bons Date: Sat, 1 Oct 2011 23:15:46 +0200 Subject: [PATCH] new Add Project dialog, powered by plugins --- SparkleLib/Git/SparkleRepoGit.cs | 2 +- SparkleLib/SparkleConfig.cs | 2 +- SparkleShare/Makefile.am | 1 + SparkleShare/SparkleEntry.cs | 36 ++- SparkleShare/SparklePlugin.cs | 71 +++++ SparkleShare/SparkleSetup.cs | 264 ++++++++++------- SparkleShare/SparkleSetupController.cs | 23 ++ SparkleShare/SparkleSetupWindow.cs | 1 - SparkleShare/SparkleShare.csproj | 1 + data/plugins/Makefile.am | 14 + data/plugins/bitbucket.png | Bin 0 -> 1591 bytes data/plugins/bitbucket.xml | 20 ++ data/plugins/github.png | Bin 0 -> 1724 bytes data/plugins/github.xml | 20 ++ data/plugins/gitorious.png | Bin 0 -> 1359 bytes data/plugins/gitorious.xml | 20 ++ data/plugins/gnome.png | Bin 0 -> 1415 bytes data/plugins/gnome.xml | 20 ++ data/src/add-project-dialog.svg | 374 +++++++++++++++++++++++++ 19 files changed, 748 insertions(+), 121 deletions(-) create mode 100644 SparkleShare/SparklePlugin.cs create mode 100644 data/plugins/Makefile.am create mode 100644 data/plugins/bitbucket.png create mode 100644 data/plugins/bitbucket.xml create mode 100644 data/plugins/github.png create mode 100644 data/plugins/github.xml create mode 100644 data/plugins/gitorious.png create mode 100644 data/plugins/gitorious.xml create mode 100644 data/plugins/gnome.png create mode 100644 data/plugins/gnome.xml create mode 100644 data/src/add-project-dialog.svg diff --git a/SparkleLib/Git/SparkleRepoGit.cs b/SparkleLib/Git/SparkleRepoGit.cs index a3c02a4c..8d7229f7 100755 --- a/SparkleLib/Git/SparkleRepoGit.cs +++ b/SparkleLib/Git/SparkleRepoGit.cs @@ -357,7 +357,7 @@ namespace SparkleLib { // We need to specifically mention the file, so // we can't reuse the Add () method SparkleGit git_add = new SparkleGit (LocalPath, - "add " + conflicting_path); + "add \"" + conflicting_path + "\""); git_add.Start (); git_add.WaitForExit (); diff --git a/SparkleLib/SparkleConfig.cs b/SparkleLib/SparkleConfig.cs index 7e5acec3..27dcf7fa 100755 --- a/SparkleLib/SparkleConfig.cs +++ b/SparkleLib/SparkleConfig.cs @@ -79,7 +79,7 @@ namespace SparkleLib { if (file.Length == 0) { File.Delete (FullPath); - CreateInitialConfig (); + CreateInitialConfig (); } else { throw new XmlException (FullPath + " does not contain a valid config XML structure."); diff --git a/SparkleShare/Makefile.am b/SparkleShare/Makefile.am index 802cbdbd..122a90ac 100755 --- a/SparkleShare/Makefile.am +++ b/SparkleShare/Makefile.am @@ -23,6 +23,7 @@ SOURCES = \ SparkleEventLog.cs \ SparkleEventLogController.cs \ SparkleExtensions.cs \ + SparklePlugin.cs \ SparkleSetup.cs \ SparkleSetupController.cs \ SparkleSetupWindow.cs \ diff --git a/SparkleShare/SparkleEntry.cs b/SparkleShare/SparkleEntry.cs index 3d0f846c..304fe941 100755 --- a/SparkleShare/SparkleEntry.cs +++ b/SparkleShare/SparkleEntry.cs @@ -22,8 +22,9 @@ namespace SparkleShare { public class SparkleEntry : Entry { - public bool ExampleTextActive; - private string pExampleText; + + private string example_text; + private bool example_text_active; public SparkleEntry () @@ -32,7 +33,7 @@ namespace SparkleShare { FocusGrabbed += delegate { OnEntered (); }; ClipboardPasted += delegate { OnEntered (); }; - + FocusOutEvent += delegate { if (Text.Equals ("") || Text == null) ExampleTextActive = true; @@ -47,33 +48,46 @@ namespace SparkleShare { { if (ExampleTextActive) { ExampleTextActive = false; - Text = ""; + Text = ""; UseNormalTextColor (); } } + public bool ExampleTextActive { + get { + return this.example_text_active; + } + + set { + this.example_text_active = value; + + if (this.example_text_active) + UseSecondaryTextColor (); + else + UseNormalTextColor (); + } + } + + public string ExampleText { get { - return pExampleText; + return this.example_text; } set { - pExampleText = value; - - if (ExampleTextActive) { + this.example_text = value; + if (this.example_text_active) UseExampleText (); - - } } } private void UseExampleText () { - Text = pExampleText; + Text = this.example_text; UseSecondaryTextColor (); } diff --git a/SparkleShare/SparklePlugin.cs b/SparkleShare/SparklePlugin.cs new file mode 100644 index 00000000..e77fc15d --- /dev/null +++ b/SparkleShare/SparklePlugin.cs @@ -0,0 +1,71 @@ +// SparkleShare, a collaboration and sharing tool. +// Copyright (C) 2010 Hylke Bons (hylkebons@gmail.com) +// +// 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 (http://www.gnu.org/licenses/). + + +using System; +using System.IO; +using System.Xml; + +namespace SparkleShare { + + public class SparklePlugin { + + public string Name; + public string Description; + public string ImagePath; + public string Backend; + + public string Address; + public string AddressExample; + public string Path; + public string PathExample; + + + public SparklePlugin (string plugin_path) + { + string plugin_directory = System.IO.Path.GetDirectoryName (plugin_path); + + XmlDocument xml = new XmlDocument (); + xml.Load (plugin_path); + + XmlNode node; + + node = xml.SelectSingleNode ("/sparkleshare/plugin/info/name/text()"); + if (node != null) { Name = node.Value; } + + node = xml.SelectSingleNode ("/sparkleshare/plugin/info/description/text()"); + if (node != null) { Description = node.Value; } + + node = xml.SelectSingleNode ("/sparkleshare/plugin/info/icon/text()"); + if (node != null) { ImagePath = System.IO.Path.Combine (plugin_directory, node.Value); } + + node = xml.SelectSingleNode ("/sparkleshare/plugin/info/backend/text()"); + if (node != null) { Backend = node.Value; } + + node = xml.SelectSingleNode ("/sparkleshare/plugin/address/value/text()"); + if (node != null) { Address = node.Value; } + + node = xml.SelectSingleNode ("/sparkleshare/plugin/address/example/text()"); + if (node != null) { AddressExample = node.Value; } + + node = xml.SelectSingleNode ("/sparkleshare/plugin/path/value/text()"); + if (node != null) { Path = node.Value; } + + node = xml.SelectSingleNode ("/sparkleshare/plugin/path/example/text()"); + if (node != null) { PathExample = node.Value; } + } + } +} diff --git a/SparkleShare/SparkleSetup.cs b/SparkleShare/SparkleSetup.cs index 2ea766ad..c5628395 100755 --- a/SparkleShare/SparkleSetup.cs +++ b/SparkleShare/SparkleSetup.cs @@ -53,6 +53,15 @@ namespace SparkleShare { } + private void RenderServiceColumn (TreeViewColumn column, CellRenderer cell, + TreeModel model, TreeIter iter) + { + (cell as Gtk.CellRendererText).Markup = (string) model.GetValue (iter, 1); + // TODO: When the row is highlighted, the description text should be + // colored with a mix of the selected text color + the selected row color + } + + public SparkleSetup () : base () { SecondaryTextColor = SparkleUIHelpers.GdkColorToHex (Style.Foreground (StateType.Insensitive)); @@ -118,133 +127,184 @@ namespace SparkleShare { case PageType.Add: { - Header = _("Where is your project?"); + Header = _("Where's your project hosted?"); - Table = new Table (6, 2, false) { - RowSpacing = 0 + VBox layout_vertical = new VBox (false, 12); + HBox layout_fields = new HBox (true, 12); + VBox layout_address = new VBox (true, 0); + VBox layout_path = new VBox (true, 0); + + ListStore store = new ListStore (typeof (Gdk.Pixbuf), + typeof (string), typeof (SparklePlugin)); + + TreeView tree = new TreeView (store) { HeadersVisible = false }; + + // Icon column + tree.AppendColumn ("Icon", new Gtk.CellRendererPixbuf (), "pixbuf", 0); + tree.Columns [0].Cells [0].Xpad = 6; + + // Service column + TreeViewColumn service_column = new TreeViewColumn () { Title = "Service" }; + CellRendererText service_cell = new CellRendererText () { Ypad = 4 }; + service_column.PackStart (service_cell, true); + service_column.SetCellDataFunc (service_cell, new TreeCellDataFunc (RenderServiceColumn)); + + store.AppendValues (new Gdk.Pixbuf ("/usr/share/icons/gnome/24x24/places/network-server.png"), + "On my own server\n" + + "Everything under my control", + null); + + foreach (SparklePlugin plugin in Controller.Plugins) { + store.AppendValues ( + new Gdk.Pixbuf (plugin.ImagePath), + "" + plugin.Name + "\n" + + "" + plugin.Description + "", + plugin); + } + + tree.AppendColumn (service_column); + + // Select "On my own server" by default + TreeSelection default_selection = tree.Selection; + TreePath default_path = new TreePath ("0"); + default_selection.SelectPath (default_path); + + tree.Model.Foreach (new TreeModelForeachFunc (delegate (TreeModel model, + TreePath path, TreeIter iter) { + + string address; + + try { + address = (model.GetValue (iter, 2) as SparklePlugin).Address; + } catch (NullReferenceException) { + address = ""; + } + + if (!string.IsNullOrEmpty (address) && + address.Equals (Controller.PreviousServer)) { + + tree.SetCursor (path, service_column, false); + // TODO: Scroll to the selection + + return true; + } else { + return false; + } + })); + + // Update the address field text when the selection changes + tree.CursorChanged += delegate(object sender, EventArgs e) { + TreeIter iter; + TreeModel model; + + TreeSelection selection = (sender as TreeView).Selection; + selection.GetSelected (out model, out iter); + + SparklePlugin plugin = (SparklePlugin) model.GetValue (iter, 2); + + ServerEntry.Sensitive = true; + FolderEntry.Sensitive = true; + + if (plugin != null) { + if (plugin.Path != null) { + FolderEntry.Text = plugin.Path; + FolderEntry.Sensitive = false; + FolderEntry.ExampleTextActive = false; + + } else if (plugin.PathExample != null) { + FolderEntry.Text = ""; + FolderEntry.ExampleText = plugin.PathExample; + FolderEntry.ExampleTextActive = true; + } + + if (plugin.Address != null) { + ServerEntry.Text = plugin.Address; + ServerEntry.Sensitive = false; + ServerEntry.ExampleTextActive = false; + + } else if (plugin.AddressExample != null) { + ServerEntry.Text = ""; + ServerEntry.ExampleText = plugin.AddressExample; + ServerEntry.ExampleTextActive = true; + } + + } else { + ServerEntry.Text = ""; + ServerEntry.ExampleTextActive = true; + ServerEntry.ExampleText = _("domain name or IP address"); + FolderEntry.Text = ""; + FolderEntry.ExampleTextActive = true; + FolderEntry.ExampleText = _("/path/to/project"); + } + + // TODO: Scroll along with the selection }; - HBox layout_server = new HBox (true, 0); + ScrolledWindow scrolled_window = new ScrolledWindow (); + scrolled_window.AddWithViewport (tree); - // Own server radiobutton - RadioButton radio_button = new RadioButton ("" + _("On my own server:") + ""); - (radio_button.Child as Label).UseMarkup = true; - - radio_button.Toggled += delegate { - if (radio_button.Active) { - FolderEntry.ExampleText = _("Folder"); - ServerEntry.Sensitive = true; - CheckAddPage (); - } else { - ServerEntry.Sensitive = false; - CheckAddPage (); - } - - ShowAll (); - }; - - // Own server entry - ServerEntry = new SparkleEntry () { }; - ServerEntry.Completion = new EntryCompletion(); - - ListStore server_store = new ListStore (typeof (string)); + ServerEntry = new SparkleEntry (); + ServerEntry.Completion = new EntryCompletion(); + ListStore server_store = new ListStore (typeof (string)); foreach (string host in Program.Controller.PreviousHosts) server_store.AppendValues (host); - ServerEntry.Completion.Model = server_store; + ServerEntry.Completion.Model = server_store; ServerEntry.Completion.TextColumn = 0; if (!string.IsNullOrEmpty (Controller.PreviousServer)) { - ServerEntry.Text = Controller.PreviousServer; + ServerEntry.Text = Controller.PreviousServer; ServerEntry.ExampleTextActive = false; + } else { - ServerEntry.ExampleText = _("address-to-server.com"); + ServerEntry.ExampleText = _("domain name or IP address"); } ServerEntry.Changed += delegate { CheckAddPage (); }; - layout_server.Add (radio_button); - layout_server.Add (ServerEntry); + layout_address.PackStart (new Label () { + Markup = "" + _("Address") + "", + Xalign = 0 + }, true, true, 0); - Table.Attach (layout_server, 0, 2, 1, 2); + layout_address.PackStart (ServerEntry, true, true, 0); - // Github radiobutton - string github_text = "" + "Github" + ""; + FolderEntry = new SparkleEntry (); + FolderEntry.ExampleText = _("/path/to/project"); + FolderEntry.Completion = new EntryCompletion(); - RadioButton radio_button_github = new RadioButton (radio_button, github_text); - (radio_button_github.Child as Label).UseMarkup = true; - (radio_button_github.Child as Label).Wrap = true; + if (!string.IsNullOrEmpty (Controller.PreviousFolder)) { + FolderEntry.Text = Controller.PreviousFolder; + FolderEntry.ExampleTextActive = false; + } - radio_button_github.Toggled += delegate { - if (radio_button_github.Active) - FolderEntry.ExampleText = _("Username/Folder"); - }; + ListStore folder_store = new ListStore (typeof (string)); + //foreach (string host in Program.Controller.FolderPaths) + // folder_store.AppendValues (host); - // Gitorious radiobutton - string gitorious_text = "" + _("Gitorious") + ""; + FolderEntry.Completion.Model = folder_store; + FolderEntry.Completion.TextColumn = 0; - RadioButton radio_button_gitorious = new RadioButton (radio_button, gitorious_text); - (radio_button_gitorious.Child as Label).UseMarkup = true; - (radio_button_gitorious.Child as Label).Wrap = true; + FolderEntry.Changed += delegate { + CheckAddPage (); + }; - radio_button_gitorious.Toggled += delegate { - if (radio_button_gitorious.Active) - FolderEntry.ExampleText = _("Project/Folder"); - }; + layout_path.PackStart (new Label () { Markup = "" + _("Remote Path") + "", Xalign = 0 }, + true, true, 0); + layout_path.PackStart (FolderEntry, true, true, 0); + layout_fields.PackStart (layout_address); + layout_fields.PackStart (layout_path); - // GNOME radiobutton - string gnome_text = "" + _("The GNOME Project") + ""; + layout_vertical.PackStart (new Label (""), false, false, 0); + layout_vertical.PackStart (scrolled_window, true, true, 0); + layout_vertical.PackStart (layout_fields, false, false, 0); - RadioButton radio_button_gnome = new RadioButton (radio_button, gnome_text); - (radio_button_gnome.Child as Label).UseMarkup = true; - (radio_button_gnome.Child as Label).Wrap = true; - - radio_button_gnome.Toggled += delegate { - if (radio_button_gnome.Active) - FolderEntry.ExampleText = _("Project"); - }; - - Table.Attach (radio_button_github, 0, 2, 2, 3); - Table.Attach (radio_button_gitorious, 0, 2, 3, 4); - Table.Attach (radio_button_gnome, 0, 2, 4, 5); - - // Folder label and entry - HBox layout_folder = new HBox (true, 0); - - Label folder_label = new Label (_("Folder Name:")) { - UseMarkup = true, - Xalign = 1 - }; - - FolderEntry = new SparkleEntry (); - FolderEntry.ExampleText = _("Folder"); - FolderEntry.Completion = new EntryCompletion(); - - ListStore folder_store = new ListStore (typeof (string)); - - //foreach (string host in Program.Controller.FolderPaths) - // folder_store.AppendValues (host); - - FolderEntry.Completion.Model = folder_store; - FolderEntry.Completion.TextColumn = 0; - - FolderEntry.Changed += delegate { - CheckAddPage (); - }; - - layout_folder.PackStart (folder_label, true, true, 12); - layout_folder.PackStart (FolderEntry, true, true, 0); - - Table.Attach (layout_folder, 0, 2, 5, 6); - - VBox box = new VBox (false, 0); - box.PackStart (Table, false, false, 0); - Add (box); + Add (layout_vertical); // Cancel button Button cancel_button = new Button (_("Cancel")); @@ -253,7 +313,6 @@ namespace SparkleShare { Close (); }; - // Sync button SyncButton = new Button (_("Add")); @@ -261,15 +320,6 @@ namespace SparkleShare { string server = ServerEntry.Text; string folder_name = FolderEntry.Text; - if (radio_button_gitorious.Active) - server = "gitorious.org"; - - if (radio_button_github.Active) - server = "github.com"; - - if (radio_button_gnome.Active) - server = "gnome.org"; - Controller.AddPageCompleted (server, folder_name); }; diff --git a/SparkleShare/SparkleSetupController.cs b/SparkleShare/SparkleSetupController.cs index af0b141f..c2f7ff1f 100755 --- a/SparkleShare/SparkleSetupController.cs +++ b/SparkleShare/SparkleSetupController.cs @@ -16,8 +16,11 @@ using System; +using System.Collections.Generic; using System.IO; +using SparkleLib; + namespace SparkleShare { public enum PageType { @@ -38,6 +41,8 @@ namespace SparkleShare { public event UpdateProgressBarEventHandler UpdateProgressBarEvent; public delegate void UpdateProgressBarEventHandler (double percentage); + public readonly List Plugins = new List (); + public int TutorialPageNumber { get { @@ -101,6 +106,24 @@ namespace SparkleShare { public SparkleSetupController () { + string local_plugins_path = SparkleHelpers.CombineMore ( + Environment.GetFolderPath (Environment.SpecialFolder.ApplicationData), + "sparkleshare", "plugins"); + + string plugins_path = SparkleHelpers.CombineMore ( + Defines.DATAROOTDIR, "sparkleshare", "plugins"); + + try { + foreach (string xml_file_path in Directory.GetFiles (local_plugins_path, "*.xml")) + Plugins.Add (new SparklePlugin (xml_file_path)); + + foreach (string xml_file_path in Directory.GetFiles (plugins_path, "*.xml")) + Plugins.Add (new SparklePlugin (xml_file_path)); + + } catch (DirectoryNotFoundException e) { + Console.WriteLine ("Could not find any plugins: " + e.Message); + } + ChangePageEvent += delegate (PageType page) { this.previous_page = page; }; diff --git a/SparkleShare/SparkleSetupWindow.cs b/SparkleShare/SparkleSetupWindow.cs index 15ec845f..3ef464c8 100755 --- a/SparkleShare/SparkleSetupWindow.cs +++ b/SparkleShare/SparkleSetupWindow.cs @@ -24,7 +24,6 @@ using System.Timers; using Gtk; using Mono.Unix; -using SparkleLib; namespace SparkleShare { diff --git a/SparkleShare/SparkleShare.csproj b/SparkleShare/SparkleShare.csproj index 199f702d..74a4e64c 100755 --- a/SparkleShare/SparkleShare.csproj +++ b/SparkleShare/SparkleShare.csproj @@ -73,5 +73,6 @@ + diff --git a/data/plugins/Makefile.am b/data/plugins/Makefile.am new file mode 100644 index 00000000..646cf71b --- /dev/null +++ b/data/plugins/Makefile.am @@ -0,0 +1,14 @@ +dist_plugins_DATA = \ + github.xml \ + github.png \ + gitorious.xml \ + gitorious.png \ + bitbucket.xml \ + bitbucket.png \ + gnome.xml \ + gnome.png + +pluginsdir = $(pkgdatadir)/plugins/ + +MAINTAINERCLEANFILES = \ + Makefile.in diff --git a/data/plugins/bitbucket.png b/data/plugins/bitbucket.png new file mode 100644 index 0000000000000000000000000000000000000000..223d3fa1a0e6c8091a95511ee6f14411f222b736 GIT binary patch literal 1591 zcmV-72FUq|P)3NtJ!f})j~!o0W5+59N!&(NlZGm! zMNtF62tgpIMFJy*zX*8qJ|3ClvE;B-F&HvNP?F(lvTreuR0}o@UN0Np< zAq4%g5>2tDK2|uUq+&_3Lg1jWb6GDi2rRCp-p4&UU9Zzg3IQ8>!8{7YOeZqL* z^gwg{zIMlIOPfZWZICbxOv3;HT0;;;cz#T&7E*9SJz4OA3)jnW6vgA7;tLng9+PdbXl;kKkb_+&5t zp3EQo*+}tCVBZ}C8u68{AL%h)ef1T}l?usZl2j^5GMOZqOktYVrf8%P>q>%va=Fah z+$`ghw>b9k@$Vt!2Wc<@rP=pXDQ6M``bD$FeLe)56?vfk2~)qL45QNvG0; zQHWdf7`i&na?n7ju&CkSodok!*XLT6zQ3nQHeyT{DC?bM;ttkSH?HboO*~9RK8PC$ z3LX?a!I}@HP~b<G7-BFYg%QOhCDa=l(}1L95L8_nY%{ug{Xai?aNy9nEd&G26J9_I+8;sRdJX;F z`yeD@;3Q7}w=gr8=xj4l)d=Nk)V2aO4MD}Lu~2j`d0yqKBO}AFKllMJugtGr4x^z{G(f|X7lCjmrMZB zB!A$f8WVQ9X?=GPLPs0op#zBY=cz8f!AyMU-p2pSjj>0pfd$FeH?#o&que<-q?3Ves?loQ9H%x$r&WONXBiUDP+SX9)fnYQC@)6pkh*Z5x?q-Wa}jUl za(tg$SQRQrE~SpXkxf3(dOM5W${Zd|*4aj)>kMPH6=d2(CE&leZZfDkIJ3(p+hXx< z#wRPFK0n01!mrSF3a6uohK?OLM;4h?3VL&wDj--G^VejL2=;Xp|$!he4x;T5aRylev(_O`fZ(c31*{kOF*TRbT;m!-D*L(5o7*S z$e|xHm4kw{2S44%zm`k62l5wB_I9k?ID1})TL=IVd+v?j{pqc~r#^Gc?rUpeA&Mv% zikhjZNre(IrW6QMlG!mxsq=HBY?E5m<1g=A_UHWR8$++JWP$kX`3=y`7ziOGw!Nq8 ziKm};I(9$Z+taQ-ar8j4v#Uke(j*~Gq>{L$8pTzQwKbP)v81n0PIya&g5hUo{;)9g z>)#O7#(*WQwc1V~00(HXQjHyrhff_#clVx1q*8ran$23#5Nqv7L?E>;YaOq~HE-Ts zp8o6VJD2_$6_@is4p`M%`?s%U`>#R>VFC%jV7=`c8*^*JH4p;9#u&5Snqwf)TE|=P pKJ44Fp-gW0W(}(iBBehB;D3pw$rfB6XJY^W002ovPDHLkV1nGk_RatR literal 0 HcmV?d00001 diff --git a/data/plugins/bitbucket.xml b/data/plugins/bitbucket.xml new file mode 100644 index 00000000..c343abd6 --- /dev/null +++ b/data/plugins/bitbucket.xml @@ -0,0 +1,20 @@ + + + + + Bitbucket + Free code hosting for Mercurial + bitbucket.png + Mercurial + +
+ ssh://hg@bitbucket.org/ + +
+ + + /username/project + +
+
+ diff --git a/data/plugins/github.png b/data/plugins/github.png new file mode 100644 index 0000000000000000000000000000000000000000..ca5dda80840826ca616f8202c0c19942168e76d1 GIT binary patch literal 1724 zcmV;t21EIYP))YKcmk zv`sIfN<=h~0&NgM0m=mzAcUY5KY~g~h+6~~KwFyLKvmI@hzba8LPD#SIH^dLjh)8p z#OWIEuGjXi_vf5FXFe|04nYuZ7-^)L(Kp{a^M3F5A|i+g$>fd{pw{;P&rBwFq}J9- zL;&dS9j_=w4D>w6FMNw%+D$y8%mJ;#hk!H^tOKJ_P97m^jCayf>Xh$mSKIz)m9meE z1cM;BREt61BnW};)Ltu5X|Tf7sL!mU?mG)gR& zvW>-J2FtcdrG`{I(H{;)!ep-e(G=!07HgEO0+b@LzEq;Ui;j*?!XZtml%u0_oO&am z?gljKJ|co`TR0(2EMn8Ben7mvAHkx$yhN?CM5R34Eao#I0GqX;Oiocw1x=y6TqW6_ zAfLZQX~{!jgVKNk6dnM=vKX3P4$IOs>K^q*jlf?4#nf8bI{*svH%HgEC1Q^9jmymR zb->1WbD%5~8kAZEX#pUD5|8=Z`=mO%NW_Fnxr~w^cPFoikV*}8*rCYn{=RTqv6v_D zeUwrtwU!K`(HNfBM1WWC1 zCtg2?V_CSai*0KMrFY+I^p}bt8;d%V` z2MO=kL%eqYzmQ|)(m4`d9V-??D}`}gR%T|1eQYmI?*M*rjzgZu>9^nG!qqG$Xd*bB z0D85C<)$AHi16&;{e%ZcC`?Ur=I9aT-g}?$&^TWHLnzEZeg<#uCgH&?6ee$Q=I9aT zuVe^q9OIco`&$(I2A~3oebL2D+wzQXz+T zGei2=aT1${82`eT@n)w8H!DnBy~$rMPZRQ%TQSFkn9u9XxpI6Z>`_d+RR~jxi0ruHE4y>w0J(+s5$WCyBN>G&1jU>%!Zl#|9Ya zN%FzPNn)KzlIiUXANmZDh^8@hiPPub;*G1b*iKSC``p(*o~qaP{LAe6(npn;pM~v} z_}T9~Mc;-|0?}Anh&J*}PfT+CQWg;y*|mw$`^Tw;dkC(=B7$1)!m)`v?%lAwvgZT?Snfbk8In>hR*n1{_~&X!^H|`Gq-u}wae~`YcCtr zGo`}hi_-EDRR8+zCq-nRrS-Ju`d=*;uU+Ws-TIUg9v5T~)DX}E%2KMO>eageND)O= z39|@iip9hWA{U!?KR|W$jXq#0`%j}IgNf;EuIl;jqs4zry#vtQoBnPj9Q)$tksS-6 zP-F<9ebpi>P1nn2vsaRhdiB@E{Izf1>xV6?=uSTpZ;zhb`O(qX#6;$|w`Z>$?(R)L zF@SnKX59}7F67;Vh z`hBsOpBKO0);jZMEbXRzZ)MKbMwC*27LiA3mHbVChl6GnE0*v@yzBoH06>D;PYZ=y zL!=yP0l243b8${7w`o~$W9rgtBO|*CqP4y;wdHpsBRA$mVf#%J5^*Q)1@KSNJY+wO SG1grG0000 + + + + Github + Free public Git repositories with collaborator management + github.png + Git + +
+ ssh://git@github.com/ + +
+ + + /username/project + +
+
+ diff --git a/data/plugins/gitorious.png b/data/plugins/gitorious.png new file mode 100644 index 0000000000000000000000000000000000000000..0a9ddb5847391e87ddc00acef24511a4a3dc527e GIT binary patch literal 1359 zcmV-V1+e;wP)2GCjzMo}9z zF&afIf<9>+qQMt=@yQos!kdXWCE^eh6(y;PaY_&|F;19DtqLeYB;{%;<#rzKnf6{j zl)=(k^iOtHvaoZ^jhbN>Z{%A!730io|mYtb4`1+I6i*#n^XV)^H^)i`V!y**ty0PxO!fz-`AhC4s8W z^;q@wsEP`rt}cR4J{pg^e-adLnJ|92PNe&cK>I71MFxGpww5)pp=jV|r@Fpz=46M8a! z(KhBywf?o#_{LSYxvLtk^?c9gMDRVM(Fi$j4fX!*$w!OlHFY5VSB$B0w5cEvr6B)d^&1xw4HAY4~Ix}Oxm9APkMW? zd><>9o1GYH5O7Qav5C+s;hQ7xQyBUcfFPdWzSr|igu|?B+00#+KQL9Q}5IZ`zU|S9~*+x!|9XmbMX$HWWHxH+w0XLt= z$>*nRVoPWq-*Ub%HERWH3XYgZBn zNJ$d`mPsI-`3so_*G{3-be~G6=bqi^4onP@J}clkX>PpqUiwFS&aG?igy)1xkPyqM z5e53}Gj;70o34L$21m{CoCl?th*Ot5kxa0s_z;!eLKb*Sxxj11w=Mzf8N6B7hiJ^m zUzq+LbZ-GE^kOCrA&3(v@$b((zrB9N^2N?&&2{e5MFj@q_wb!@=6j3CSSvwVvAE!D zzHl5f-h)KPFr&vXCr`oz=t0d;=Mnn8-JcBn{F}s%b3kp_u)#j+?^+>VbVoX4Hi+0w zE0@*iYp$rtth%&{h1r-;4=@@GllvjdWTd&!y%{T)hD?gEXO#Xu2Pu61OE|LssGX#} zBLl|TdEC$J{A|gR{YpeoN-03Kwzk@ni+dK7%^$xt?X%H{TvuP6m77*qrH^{tW_%ml%}; Rm(TzJ002ovPDHLkV1i`*jdB10 literal 0 HcmV?d00001 diff --git a/data/plugins/gitorious.xml b/data/plugins/gitorious.xml new file mode 100644 index 00000000..2abc3ae8 --- /dev/null +++ b/data/plugins/gitorious.xml @@ -0,0 +1,20 @@ + + + + + Gitorious + Open source infrastructure for hosting open source projects + gitorious.png + Git + +
+ ssh://git@gitorious.org/ + +
+ + + /project/repository + +
+
+ diff --git a/data/plugins/gnome.png b/data/plugins/gnome.png new file mode 100644 index 0000000000000000000000000000000000000000..d596c2bfa995d56ab2b035cceda22726337914db GIT binary patch literal 1415 zcmZ`(Yd8}M7+&X;jmZ73MJU(VC0R@hV>7HxYcxm5+|yi^5l)7gC}*qisL;hc;R$n@ zPEk1vp*V*fQEM&R(I=R$UlpXBfIF3}xQ}dO2bZ39YkQfJ;1;#5{1>Ud{A$IZbjAmZ0c>v9f`K?2 z0N7dRjd3I6dR|fDe1jqkD$tBeux_-^jHOYrOdTtq9qN}A5BJOV-X~kF`LN*Z8Yue# z7a3@Z1l}yX;rj@dkK~?*y@X31cH3yGX^qhY%1Z8Vjxlt^xKdvBY4#_Vtwjs^0Fy90 zo8~b1z2&XY)h+;!?@KAdeX*$=98X-^i$aOaL0)%<$gzgQk0~6)+sOnJ@6gvc_sPFZ z%vQnJ-1M=D!Y-8~esX_AwO$z>VW;I&uMAqw>x^{?xp>>!$&6S;v>LU4zE-8uI7HSw zZEo7Nfx7&V?H%!y=G@#t2#~tn!92qIe~!L!x=>6tQnqYr)eb%wC$EI%eVi^>N;yi9 zXn0qRBZLfxeQ@zj)%;(sO)^(I)Ege$Py2*yfWyDGZjJS+@CtF=?2S6j3lu^~R@|!ukL!3{5ntTxBof8nA>uNQ zhZerO!})AnAkj@nG&Q3+Ld>_FhB4?N*{fa$6t++IqGOvdGvlZRk{CF%NwFxAW@G9f z+tzh^_4J_MNF-#bcKhi2G_&Ed;awgQIQ8Q_j*CmjA<@g2D>EVAfg7KWg<3E(lA6LU zM0O+5=&h-#siC0PlmO%XJRHm&w|jZ$qLAO(dOqss#F%|87JJI#_pEQ6XYqJWKj=eJ zZ$b3Cx*8dfqQ_>eDYB|g&~BZy69Bvvm3U#v}F&(zt|JTM)*8`mR{bO6^i{W z$#En2Qjf^Omq?^ib9?VcTp^?bxw{C=QJ$+P&n{&*{FEQgZ@d@f9@Bz;8XV9DtpBL2 zEf$ZIur^8lk>rulLn0c{-=EHT1dI; zLZ7u&JLse|H#pxq`rQ=Kbb?S@(7?%4iM}UuTKa~Ji#{7?Q&+cPUJ4l-R8`FY45%b? z8wUzN>?B8|YjA~5r&ug*&Wuu`TB@v69@AoncHTWzFWKiSyquOW0tJdRgFb9lSF?V# z4al#Gg1NYS|4f6<@vn?GdxtYkksy?$2u zyvH(qn%=!`G*6dS6)1wrlHnQ1poK9aoWqkM6a;`np-1dtFnc(H40CjLbaI9rv4z5% zq0rBc4SD}D#M5apk!k;L$cff>Ru~MoKb)XPGMHgW5dbEW35huummD6J5CNelMcw>_ QGE#^D-kt + + + + The GNOME Project + A free and easy interface for your computer + gnome.png + Git + +
+ ssh://git@gnome.org/ + +
+ + + /project + +
+
+ diff --git a/data/src/add-project-dialog.svg b/data/src/add-project-dialog.svg new file mode 100644 index 00000000..25c7ac79 --- /dev/null +++ b/data/src/add-project-dialog.svg @@ -0,0 +1,374 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + Address + + Remote Path + + On my own server + Github Free public repositories with collaborator management Where is your project? domain name or IP address /path/to/project + ? + ? + + Add Cancel Gitorious Open source infrastructure for hosting open source projects Everything under my control + G + + + + + +