[gitg] Rework the dash view implementation
- From: Jesse van den Kieboom <jessevdk src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gitg] Rework the dash view implementation
- Date: Tue, 4 Aug 2015 15:36:09 +0000 (UTC)
commit 8786f4f068526ac8c62b5c164c15c95b58ace1eb
Author: Jesse van den Kieboom <jessevdk gnome org>
Date: Tue Aug 4 17:35:16 2015 +0200
Rework the dash view implementation
- Make the dash view more self contained
- Move the open and clone menu options in an action bar
- Add cloning authentication/credentials
gitg/gitg-dash-view.vala | 229 ++++++++++++++++++--
gitg/gitg-remote-manager.vala | 9 +-
gitg/gitg-window.vala | 66 +------
gitg/resources/gitg-resources.xml | 1 +
gitg/resources/ui/gitg-dash-view.ui | 63 ++++++
gitg/resources/ui/gitg-menus.ui | 10 -
gitg/resources/ui/gitg-window.ui | 19 +--
libgitg-ext/gitg-ext-application.vala | 2 +
libgitg/gitg-credentials-manager.vala | 100 ++++++----
libgitg/gitg-remote.vala | 9 -
libgitg/gitg-repository-list-box.vala | 147 +++----------
.../resources/ui/gitg-repository-list-box-row.ui | 1 +
po/POTFILES.in | 2 +
po/POTFILES.skip | 1 +
14 files changed, 394 insertions(+), 265 deletions(-)
---
diff --git a/gitg/gitg-dash-view.vala b/gitg/gitg-dash-view.vala
index 91d239c..07c8e1d 100644
--- a/gitg/gitg-dash-view.vala
+++ b/gitg/gitg-dash-view.vala
@@ -20,7 +20,8 @@
namespace Gitg
{
-class DashView : RepositoryListBox, GitgExt.UIElement, GitgExt.Activity, GitgExt.Selectable,
GitgExt.Searchable
+[GtkTemplate (ui = "/org/gnome/gitg/ui/gitg-dash-view.ui")]
+class DashView : Gtk.Grid, GitgExt.UIElement, GitgExt.Activity, GitgExt.Selectable, GitgExt.Searchable
{
private const string version = Config.VERSION;
@@ -29,11 +30,17 @@ class DashView : RepositoryListBox, GitgExt.UIElement, GitgExt.Activity, GitgExt
private bool d_search_enabled;
private bool d_setting_mode;
+ [GtkChild( name = "repository_list_box" )]
+ private RepositoryListBox d_repository_list_box;
+
+ [GtkChild( name = "action_bar" )]
+ private Gtk.ActionBar d_action_bar;
+
public GitgExt.SelectionMode selectable_mode
{
get
{
- switch (mode)
+ switch (d_repository_list_box.mode)
{
case Gitg.SelectionMode.NORMAL:
return GitgExt.SelectionMode.NORMAL;
@@ -56,10 +63,12 @@ class DashView : RepositoryListBox, GitgExt.UIElement, GitgExt.Activity, GitgExt
switch (value)
{
case GitgExt.SelectionMode.NORMAL:
- mode = Gitg.SelectionMode.NORMAL;
+ d_repository_list_box.mode = Gitg.SelectionMode.NORMAL;
+ d_action_bar.visible = true;
break;
case GitgExt.SelectionMode.SELECTION:
- mode = Gitg.SelectionMode.SELECTION;
+ d_repository_list_box.mode = Gitg.SelectionMode.SELECTION;
+ d_action_bar.visible = false;
break;
}
@@ -103,7 +112,7 @@ class DashView : RepositoryListBox, GitgExt.UIElement, GitgExt.Activity, GitgExt
if (d_search_text != value)
{
d_search_text = value;
- filter_text(d_search_text);
+ update_search_text();
}
}
@@ -125,15 +134,22 @@ class DashView : RepositoryListBox, GitgExt.UIElement, GitgExt.Activity, GitgExt
if (d_search_enabled != value)
{
d_search_enabled = value;
+ update_search_text();
+ }
+ }
+ }
- if (d_search_enabled)
- {
- filter_text(d_search_text);
- }
- else
- {
- filter_text(null);
- }
+ private void update_search_text()
+ {
+ if (d_repository_list_box != null)
+ {
+ if (d_search_enabled && d_search_text != "")
+ {
+ d_repository_list_box.filter_text(d_search_text);
+ }
+ else
+ {
+ d_repository_list_box.filter_text(null);
}
}
}
@@ -151,7 +167,7 @@ class DashView : RepositoryListBox, GitgExt.UIElement, GitgExt.Activity, GitgExt
del.show();
del.clicked.connect(() => {
- foreach (var sel in selection)
+ foreach (var sel in d_repository_list_box.selection)
{
sel.request_remove();
}
@@ -159,7 +175,7 @@ class DashView : RepositoryListBox, GitgExt.UIElement, GitgExt.Activity, GitgExt
selectable_mode = GitgExt.SelectionMode.NORMAL;
});
- bind_property("has-selection", del, "sensitive");
+ d_repository_list_box.bind_property("has-selection", del, "sensitive");
ab.pack_end(del);
@@ -170,12 +186,193 @@ class DashView : RepositoryListBox, GitgExt.UIElement, GitgExt.Activity, GitgExt
construct
{
- notify["mode"].connect(() => {
+ d_repository_list_box.notify["mode"].connect(() => {
if (!d_setting_mode)
{
+ d_action_bar.visible = (selectable_mode == GitgExt.SelectionMode.NORMAL);
notify_property("selectable-mode");
}
});
+
+ d_repository_list_box.repository_activated.connect((repository) => {
+ application.repository = repository;
+ });
+
+ d_repository_list_box.show_error.connect((primary_message, secondary_message) => {
+ application.show_infobar(primary_message, secondary_message, Gtk.MessageType.ERROR);
+ });
+ }
+
+ public RepositoryListBox.Row? add_repository(Repository repository)
+ {
+ return d_repository_list_box.add_repository(repository);
+ }
+
+ class CloneCallbacks : Ggit.RemoteCallbacks
+ {
+ private RepositoryListBox.Row d_row;
+ private CredentialsManager d_credentials;
+
+ public CloneCallbacks(GitgExt.Application application, Ggit.Config? config,
RepositoryListBox.Row row)
+ {
+ d_row = row;
+ d_credentials = new CredentialsManager(config, application as Gtk.Window, false);
+ }
+
+ protected override void transfer_progress(Ggit.TransferProgress stats)
+ {
+ var recvobj = stats.get_received_objects();
+ var indxobj = stats.get_indexed_objects();
+ var totaobj = stats.get_total_objects();
+
+ Idle.add(() => {
+ d_row.fraction = (recvobj + indxobj) / (double)(2 * totaobj);
+ return false;
+ });
+ }
+
+ protected override Ggit.Cred? credentials(string url, string? username_from_url,
Ggit.Credtype allowed_types) throws Error
+ {
+ return d_credentials.credentials(url, username_from_url, allowed_types);
+ }
+ }
+
+ private async Repository? clone(RepositoryListBox.Row row, string url, File location, bool is_bare)
throws Error
+ {
+ Repository? repository = null;
+
+ yield Async.thread(() => {
+ var clone_options = new Ggit.CloneOptions();
+ var fetch_options = new Ggit.FetchOptions();
+ Ggit.Config? config = null;
+
+ try
+ {
+ config = new Ggit.Config.default();
+ } catch {}
+
+ fetch_options.set_remote_callbacks(new CloneCallbacks(application, config, row));
+
+ clone_options.set_is_bare(is_bare);
+ clone_options.set_fetch_options(fetch_options);
+
+ repository = (Repository)Ggit.Repository.clone(url, location, clone_options);
+ });
+
+ return repository;
+ }
+
+ private void clone_repository(string url, File location, bool is_bare)
+ {
+ // create subfolder
+ var pos = url.last_index_of_char('/');
+
+ if (pos == -1)
+ {
+ pos = url.last_index_of_char(':');
+ }
+
+ var dot_git_suffix = ".git";
+ var subfolder_name = url.substring(pos + 1);
+ var has_dot_git = subfolder_name.has_suffix(dot_git_suffix);
+
+ if (has_dot_git && !is_bare)
+ {
+ subfolder_name = subfolder_name.slice(0, - dot_git_suffix.length);
+ }
+ else if (!has_dot_git && is_bare)
+ {
+ subfolder_name += dot_git_suffix;
+ }
+
+ var subfolder = location.resolve_relative_path(subfolder_name);
+
+ // Clone
+ var row = d_repository_list_box.begin_cloning(subfolder_name);
+
+ clone.begin(row, url, subfolder, is_bare, (obj, res) => {
+ Gitg.Repository? repository = null;
+
+ try
+ {
+ repository = clone.end(res);
+ }
+ catch (Error e)
+ {
+ application.show_infobar(_("Failed to clone repository"), e.message,
Gtk.MessageType.ERROR);
+ }
+
+ d_repository_list_box.end_cloning(row, repository);
+ });
+ }
+
+ [GtkCallback]
+ private void clone_repository_clicked()
+ {
+ var dlg = new CloneDialog(application as Gtk.Window);
+
+ dlg.response.connect((d, id) => {
+ if (id == Gtk.ResponseType.OK)
+ {
+ clone_repository(dlg.url, dlg.location, dlg.is_bare);
+ }
+
+ d.destroy();
+ });
+
+ dlg.show();
+ }
+
+ [GtkCallback]
+ private void open_repository_clicked()
+ {
+ var chooser = new Gtk.FileChooserDialog(_("Add Repository"),
+ application as Gtk.Window,
+ Gtk.FileChooserAction.SELECT_FOLDER,
+ _("_Cancel"), Gtk.ResponseType.CANCEL,
+ _("_Add"), Gtk.ResponseType.OK);
+
+ chooser.modal = true;
+ chooser.set_default_response(Gtk.ResponseType.OK);
+
+ chooser.response.connect((c, id) => {
+ if (id == Gtk.ResponseType.OK)
+ {
+ var file = chooser.get_file();
+
+ if (file == null)
+ {
+ file = chooser.get_current_folder_file();
+ }
+
+ Repository? repo = null;
+
+ try
+ {
+ repo = new Repository(file, null);
+ }
+ catch (Error err)
+ {
+ application.show_infobar(_("Failed to add repository"), err.message,
Gtk.MessageType.ERROR);
+ }
+
+ if (repo != null)
+ {
+ var row = add_repository(repo);
+
+ if (row != null)
+ {
+ row.grab_focus();
+ d_repository_list_box.grab_focus();
+ row.grab_focus();
+ }
+ }
+ }
+
+ c.destroy();
+ });
+
+ chooser.show();
}
}
diff --git a/gitg/gitg-remote-manager.vala b/gitg/gitg-remote-manager.vala
index 8e04ca1..0349361 100644
--- a/gitg/gitg-remote-manager.vala
+++ b/gitg/gitg-remote-manager.vala
@@ -28,7 +28,14 @@ class RemoteManager : Object, GitgExt.RemoteLookup
public UICredentialsProvider(Gitg.Remote remote, Gtk.Window window)
{
- d_credentials = new CredentialsManager(remote, window);
+ Ggit.Config? config = null;
+
+ try
+ {
+ config = remote.get_owner().get_config();
+ } catch {}
+
+ d_credentials = new CredentialsManager(config, window, true);
}
public Ggit.Cred? credentials(string url,
diff --git a/gitg/gitg-window.vala b/gitg/gitg-window.vala
index 61f313e..f775251 100644
--- a/gitg/gitg-window.vala
+++ b/gitg/gitg-window.vala
@@ -75,8 +75,6 @@ public class Window : Gtk.ApplicationWindow, GitgExt.Application, Initable
private Gtk.Stack d_main_stack;
[GtkChild]
- private Gtk.ScrolledWindow d_dash_scrolled_window;
- [GtkChild]
private DashView d_dash_view;
[GtkChild]
@@ -141,8 +139,6 @@ public class Window : Gtk.ApplicationWindow, GitgExt.Application, Initable
private static const ActionEntry[] win_entries = {
{"search", on_search_activated, null, "false", null},
{"gear-menu", on_gear_menu_activated, null, "false", null},
- {"open-repository", on_open_repository},
- {"clone-repository", on_clone_repository},
{"close", on_close_activated},
{"reload", on_reload_activated},
{"author-details-global", on_global_author_details_activated},
@@ -188,18 +184,6 @@ public class Window : Gtk.ApplicationWindow, GitgExt.Application, Initable
}
}
- [GtkCallback]
- private void dash_view_repository_activated(Repository r)
- {
- repository = r;
- }
-
- [GtkCallback]
- private void dash_view_show_error(string title, string message)
- {
- show_infobar(title, message, Gtk.MessageType.ERROR);
- }
-
construct
{
add_action_entries(win_entries, this);
@@ -234,6 +218,8 @@ public class Window : Gtk.ApplicationWindow, GitgExt.Application, Initable
menuname = "app-win-menu";
}
+ d_dash_view.application = this;
+
d_dash_model = Resource.load_object<MenuModel>("ui/gitg-menus.ui", menuname + "-dash");
d_activities_model = Resource.load_object<MenuModel>("ui/gitg-menus.ui", menuname + "-views");
@@ -426,7 +412,7 @@ public class Window : Gtk.ApplicationWindow, GitgExt.Application, Initable
d_mode = Mode.DASH;
d_main_stack.transition_type = Gtk.StackTransitionType.SLIDE_RIGHT;
- d_main_stack.set_visible_child(d_dash_scrolled_window);
+ d_main_stack.set_visible_child(d_dash_view);
d_activities_switcher.hide();
d_dash_button.hide();
d_gear_menu.menu_model = d_dash_model;
@@ -461,34 +447,6 @@ public class Window : Gtk.ApplicationWindow, GitgExt.Application, Initable
return base.configure_event(event);
}
- private void on_open_repository()
- {
- var chooser = new Gtk.FileChooserDialog (_("Open Repository"), this,
- Gtk.FileChooserAction.SELECT_FOLDER,
- _("_Cancel"), Gtk.ResponseType.CANCEL,
- _("_Open"), Gtk.ResponseType.OK);
-
- chooser.modal = true;
-
- chooser.response.connect((c, id) => {
- if (id == Gtk.ResponseType.OK)
- {
- var file = chooser.get_file();
-
- if (file == null)
- {
- file = chooser.get_current_folder_file();
- }
-
- open_repository(file);
- }
-
- c.destroy();
- });
-
- chooser.show();
- }
-
private void on_reload_activated()
{
try
@@ -504,22 +462,6 @@ public class Window : Gtk.ApplicationWindow, GitgExt.Application, Initable
catch {}
}
- private void on_clone_repository()
- {
- var dlg = new CloneDialog(this);
-
- dlg.response.connect((d, id) => {
- if (id == Gtk.ResponseType.OK)
- {
- d_dash_view.clone_repository(dlg.url, dlg.location, dlg.is_bare);
- }
-
- d.destroy();
- });
-
- dlg.show();
- }
-
private void on_global_author_details_activated()
{
Ggit.Config global_config = null;
@@ -742,7 +684,7 @@ public class Window : Gtk.ApplicationWindow, GitgExt.Application, Initable
}
}
- private void open_repository(File path)
+ public void open_repository(File path)
{
File repo;
Gitg.Repository? repository = null;
diff --git a/gitg/resources/gitg-resources.xml b/gitg/resources/gitg-resources.xml
index a20d66a..a3d9d97 100644
--- a/gitg/resources/gitg-resources.xml
+++ b/gitg/resources/gitg-resources.xml
@@ -20,6 +20,7 @@
<file compressed="true" preprocess="xml-stripblanks">ui/gitg-commit-dialog.ui</file>
<file compressed="true" preprocess="xml-stripblanks">ui/gitg-create-branch-dialog.ui</file>
<file compressed="true" preprocess="xml-stripblanks">ui/gitg-create-tag-dialog.ui</file>
+ <file compressed="true" preprocess="xml-stripblanks">ui/gitg-dash-view.ui</file>
<file compressed="true">ui/style.css</file>
</gresource>
</gresources>
diff --git a/gitg/resources/ui/gitg-dash-view.ui b/gitg/resources/ui/gitg-dash-view.ui
new file mode 100644
index 0000000..5d41e39
--- /dev/null
+++ b/gitg/resources/ui/gitg-dash-view.ui
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <!-- interface-requires gtk+ 3.0 -->
+ <template class="GitgDashView" parent="GtkGrid">
+ <child>
+ <object class="GtkScrolledWindow" id="scrolled_window">
+ <property name="visible">True</property>
+ <property name="vexpand">True</property>
+ <property name="hexpand">True</property>
+ <style>
+ <class name="view"/>
+ </style>
+ <child>
+ <object class="GitgRepositoryListBox" id="repository_list_box">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <style>
+ <class name="view"/>
+ </style>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkActionBar" id="action_bar">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkButton" id="open_repository">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Add repository</property>
+ <signal name="clicked" handler="open_repository_clicked" swapped="no"/>
+ </object>
+ <packing>
+ <property name="pack_type">end</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="clone_repository">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Clone repository</property>
+ <signal name="clicked" handler="clone_repository_clicked" swapped="no"/>
+ </object>
+ <packing>
+ <property name="pack_type">end</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ </template>
+</interface>
diff --git a/gitg/resources/ui/gitg-menus.ui b/gitg/resources/ui/gitg-menus.ui
index 097147e..7f5beeb 100644
--- a/gitg/resources/ui/gitg-menus.ui
+++ b/gitg/resources/ui/gitg-menus.ui
@@ -32,16 +32,6 @@
<menu id="win-menu-dash">
<section>
<item>
- <attribute name="label" translatable="yes">_Open Repository…</attribute>
- <attribute name="action">win.open-repository</attribute>
- </item>
- <item>
- <attribute name="label" translatable="yes">_Clone Repository…</attribute>
- <attribute name="action">win.clone-repository</attribute>
- </item>
- </section>
- <section>
- <item>
<attribute name="label" translatable="yes">_Author Details</attribute>
<attribute name="action">win.author-details-global</attribute>
</item>
diff --git a/gitg/resources/ui/gitg-window.ui b/gitg/resources/ui/gitg-window.ui
index 69b2afe..98e8ac0 100644
--- a/gitg/resources/ui/gitg-window.ui
+++ b/gitg/resources/ui/gitg-window.ui
@@ -234,24 +234,9 @@
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<child>
- <object class="GtkScrolledWindow" id="d_dash_scrolled_window">
+ <object class="GitgDashView" id="d_dash_view">
<property name="visible">True</property>
- <property name="vexpand">True</property>
- <property name="hexpand">True</property>
- <style>
- <class name="view"/>
- </style>
- <child>
- <object class="GitgDashView" id="d_dash_view">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <signal name="repository_activated" handler="dash_view_repository_activated"
swapped="no"/>
- <signal name="show_error" handler="dash_view_show_error" swapped="no"/>
- <style>
- <class name="view"/>
- </style>
- </object>
- </child>
+ <property name="can_focus">True</property>
</object>
</child>
<child>
diff --git a/libgitg-ext/gitg-ext-application.vala b/libgitg-ext/gitg-ext-application.vala
index 30e6027..8a3120d 100644
--- a/libgitg-ext/gitg-ext-application.vala
+++ b/libgitg-ext/gitg-ext-application.vala
@@ -76,6 +76,8 @@ public interface Application : Object
public abstract Application open_new(Ggit.Repository repository, string? hint = null);
public abstract RemoteLookup remote_lookup { owned get; }
+
+ public abstract void open_repository(File path);
}
}
diff --git a/libgitg/gitg-credentials-manager.vala b/libgitg/gitg-credentials-manager.vala
index d913bd6..67a26c4 100644
--- a/libgitg/gitg-credentials-manager.vala
+++ b/libgitg/gitg-credentials-manager.vala
@@ -27,9 +27,12 @@ public errordomain CredentialsError
public class CredentialsManager
{
- private weak Remote d_remote;
+ private Ggit.Config? d_config;
private Gtk.Window d_window;
private Gee.HashMap<string, string>? d_usermap;
+ private bool d_save_user_in_config;
+ private string d_last_user;
+ private Gee.HashMap<string, Ggit.Credtype> d_auth_tried;
private static Secret.Schema s_secret_schema;
static construct
@@ -41,9 +44,11 @@ public class CredentialsManager
"user", Secret.SchemaAttributeType.STRING);
}
- public CredentialsManager(Remote remote, Gtk.Window window)
+ public CredentialsManager(Ggit.Config? config, Gtk.Window window, bool save_user_in_config)
{
- d_remote = remote;
+ d_config = config;
+ d_save_user_in_config = save_user_in_config;
+ d_auth_tried = new Gee.HashMap<string, Ggit.Credtype>();
d_window = window;
}
@@ -53,19 +58,21 @@ public class CredentialsManager
{
d_usermap = new Gee.HashMap<string, string?>();
- try
+ if (d_config != null)
{
- var config = d_remote.get_owner().get_config().snapshot();
- var r = new Regex("credential\\.(.*)\\.username");
+ try
+ {
+ var r = new Regex("credential\\.(.*)\\.username");
- config.match_foreach(r, (info, value) => {
- d_usermap[info.fetch(1)] = value;
- return 0;
- });
- }
- catch (Error e)
- {
- stderr.printf("Could not get username from git config: %s\n", e.message);
+ d_config.snapshot().match_foreach(r, (info, value) => {
+ d_usermap[info.fetch(1)] = value;
+ return 0;
+ });
+ }
+ catch (Error e)
+ {
+ stderr.printf("Could not get username from git config: %s\n",
e.message);
+ }
}
}
@@ -86,7 +93,7 @@ public class CredentialsManager
AuthenticationLifeTime lifetime = AuthenticationLifeTime.FORGET;
Idle.add(() => {
- var d = new AuthenticationDialog(url, username, d_remote.authentication_error !=
null);
+ var d = new AuthenticationDialog(url, username, d_auth_tried[username] != 0);
d.set_transient_for(d_window);
response = (Gtk.ResponseType)d.run();
@@ -115,8 +122,10 @@ public class CredentialsManager
throw new CredentialsError.CANCELLED("cancelled by user");
}
+ d_last_user = newusername;
+
// Save username in config
- if (username == null || newusername != username)
+ if (username == null || newusername != username && d_config != null && d_save_user_in_config)
{
if (d_usermap == null)
{
@@ -125,12 +134,9 @@ public class CredentialsManager
try
{
- var repo = d_remote.get_owner();
- var config = repo.get_config();
var hid = @"$(scheme)://$(host)";
- config.set_string(@"credential.$(hid).username", newusername);
-
+ d_config.set_string(@"credential.$(hid).username", newusername);
d_usermap[hid] = newusername;
}
catch (Error e)
@@ -185,6 +191,7 @@ public class CredentialsManager
});
}
+ d_auth_tried[newusername] |= Ggit.Credtype.USERPASS_PLAINTEXT;
return new Ggit.CredPlaintext(newusername, password);
}
@@ -212,29 +219,40 @@ public class CredentialsManager
user = username;
}
- if (user != null && d_remote.authentication_error == null)
+ if (user != null)
{
- string? secret = null;
+ var tried = d_auth_tried[user];
- try
+ if ((tried & Ggit.Credtype.USERPASS_PLAINTEXT) == 0)
{
- secret = Secret.password_lookup_sync(s_secret_schema, null,
- "scheme", scheme,
- "host", host,
- "user", user);
- }
- catch {}
+ string? secret = null;
- if (secret == null)
- {
- return user_pass_dialog(url, scheme, host, user);
- }
+ try
+ {
+ secret = Secret.password_lookup_sync(s_secret_schema, null,
+ "scheme", scheme,
+ "host", host,
+ "user", user);
+ }
+ catch {}
- try
- {
- return new Ggit.CredPlaintext(user, secret);
+ if (secret == null)
+ {
+ return user_pass_dialog(url, scheme, host, user);
+ }
+
+ d_auth_tried[user] |= Ggit.Credtype.USERPASS_PLAINTEXT;
+
+ try
+ {
+ return new Ggit.CredPlaintext(user, secret);
+ }
+ catch (Error e)
+ {
+ return user_pass_dialog(url, scheme, host, user);
+ }
}
- catch (Error e)
+ else
{
return user_pass_dialog(url, scheme, host, user);
}
@@ -249,8 +267,14 @@ public class CredentialsManager
string? username,
Ggit.Credtype allowed_types) throws Error
{
- if (d_remote.authentication_error == null && (allowed_types & Ggit.Credtype.SSH_KEY) != 0)
+ var uslookup = username != null ? username : "";
+ var tried = d_auth_tried[uslookup];
+
+ var untried_allowed_types = allowed_types & ~tried;
+
+ if ((untried_allowed_types & Ggit.Credtype.SSH_KEY) != 0)
{
+ d_auth_tried[uslookup] = tried | Ggit.Credtype.SSH_KEY;
return new Ggit.CredSshKeyFromAgent(username);
}
else if ((allowed_types & Ggit.Credtype.USERPASS_PLAINTEXT) != 0)
diff --git a/libgitg/gitg-remote.vala b/libgitg/gitg-remote.vala
index 50e176e..991d4cf 100644
--- a/libgitg/gitg-remote.vala
+++ b/libgitg/gitg-remote.vala
@@ -118,7 +118,6 @@ public class Remote : Ggit.Remote
}
private RemoteState d_state;
- private Error? d_authentication_error;
private string[]? d_fetch_specs;
private string[]? d_push_specs;
private uint d_reset_transfer_progress_timeout;
@@ -142,11 +141,6 @@ public class Remote : Ggit.Remote
get { return d_transfer_progress; }
}
- public Error authentication_error
- {
- get { return d_authentication_error; }
- }
-
public RemoteState state
{
get { return d_state; }
@@ -218,7 +212,6 @@ public class Remote : Ggit.Remote
else
{
state = RemoteState.CONNECTED;
- d_authentication_error = null;
}
}
else
@@ -265,7 +258,6 @@ public class Remote : Ggit.Remote
if (e.message == "Unexpected HTTP status code: 401" ||
e.message == "error authenticating: Username/PublicKey combination
invalid")
{
- d_authentication_error = e;
continue;
}
else
@@ -275,7 +267,6 @@ public class Remote : Ggit.Remote
}
}
- d_authentication_error = null;
break;
}
diff --git a/libgitg/gitg-repository-list-box.vala b/libgitg/gitg-repository-list-box.vala
index 7da7cb3..b5a9620 100644
--- a/libgitg/gitg-repository-list-box.vala
+++ b/libgitg/gitg-repository-list-box.vala
@@ -365,14 +365,46 @@ namespace Gitg
{
var recent_manager = Gtk.RecentManager.get_default();
var item = Gtk.RecentData();
+
item.app_name = Environment.get_application_name();
item.mime_type = "inode/directory";
item.app_exec = string.join(" ", Environment.get_prgname(), "%f");
item.groups = { "gitg", null };
+
recent_manager.add_full(uri, item);
}
- public void add_repository(Repository repository)
+ public void end_cloning(Row row, Repository? repository)
+ {
+ if (repository != null)
+ {
+ File? workdir = repository.get_workdir();
+ File? repo_file = repository.get_location();
+
+ var uri = (workdir != null) ? workdir.get_uri() : repo_file.get_uri();
+ add_repository_to_recent_manager(uri);
+
+ row.repository = repository;
+ row.loading = false;
+ }
+ else
+ {
+ remove(row);
+ }
+ }
+
+ public Row? begin_cloning(string name)
+ {
+ var row = new Row(name, _("Cloning..."), true);
+
+ row.loading = true;
+ row.show();
+
+ add(row);
+ return row;
+ }
+
+ public Row? add_repository(Repository repository)
{
Row? row = get_row_for_repository(repository);
@@ -451,6 +483,8 @@ namespace Gitg
{
add_repository_to_recent_manager(f.get_uri());
}
+
+ return row;
}
public Row[] selection
@@ -491,117 +525,6 @@ namespace Gitg
}
}
- class CloneProgress : Ggit.RemoteCallbacks
- {
- private Row d_row;
-
- public CloneProgress(Row row)
- {
- d_row = row;
- }
-
- protected override void transfer_progress(Ggit.TransferProgress stats)
- {
- var recvobj = stats.get_received_objects();
- var indxobj = stats.get_indexed_objects();
- var totaobj = stats.get_total_objects();
-
- Idle.add(() => {
- d_row.fraction = (recvobj + indxobj) / (double)(2 * totaobj);
- return false;
- });
- }
- }
-
- private async Repository? clone(Row row, string url, File location, bool is_bare)
- {
- SourceFunc callback = clone.callback;
- Repository? repository = null;
-
- ThreadFunc<void*> run = () => {
- try
- {
- var clone_options = new Ggit.CloneOptions();
- var fetch_options = new Ggit.FetchOptions();
-
- fetch_options.set_remote_callbacks(new CloneProgress(row));
-
- clone_options.set_is_bare(is_bare);
- clone_options.set_fetch_options(fetch_options);
-
- repository = (Repository)Ggit.Repository.clone(url, location,
clone_options);
- }
- catch (Ggit.Error e)
- {
- show_error("Gitg could not clone the git repository.", e.message);
- }
- catch (GLib.Error e)
- {
- show_error("Gitg could not clone the git repository.", e.message);
- }
-
- Idle.add((owned) callback);
- return null;
- };
-
- try
- {
- new Thread<void*>.try("gitg-clone-thread", (owned)run);
- yield;
- }
- catch {}
-
- return repository;
- }
-
- public void clone_repository(string url, File location, bool is_bare)
- {
- // create subfolder
- var subfolder_name = url.substring(url.last_index_of_char('/') + 1);
- if (subfolder_name.has_suffix(".git") && !is_bare)
- {
- subfolder_name = subfolder_name.slice(0, - ".git".length);
- }
- else if (is_bare)
- {
- subfolder_name += ".git";
- }
-
- var subfolder = location.resolve_relative_path(subfolder_name);
-
- try
- {
- subfolder.make_directory_with_parents(null);
- }
- catch (GLib.Error e)
- {
- show_error("Gitg could not clone the git repository.", e.message);
- return;
- }
-
- // Clone
- var row = new Row(subfolder_name, "Cloning...", true);
- row.loading = true;
- row.show();
- add(row);
-
- clone.begin(row, url, subfolder, is_bare, (obj, res) => {
- Gitg.Repository? repository = clone.end(res);
-
- // FIXME: show an error
- if (repository != null)
- {
- File? workdir = repository.get_workdir();
- File? repo_file = repository.get_location();
- var uri = (workdir != null) ? workdir.get_uri() : repo_file.get_uri();
- add_repository_to_recent_manager(uri);
- }
-
- row.repository = repository;
- row.loading = false;
- });
- }
-
public void filter_text(string? text)
{
d_filter_text = text;
diff --git a/libgitg/resources/ui/gitg-repository-list-box-row.ui
b/libgitg/resources/ui/gitg-repository-list-box-row.ui
index b9e15c7..4f06a5e 100644
--- a/libgitg/resources/ui/gitg-repository-list-box-row.ui
+++ b/libgitg/resources/ui/gitg-repository-list-box-row.ui
@@ -2,6 +2,7 @@
<interface>
<!-- interface-requires gtk+ 3.8 -->
<template class="GitgRepositoryListBoxRow" parent="GtkListBoxRow">
+ <property name="can_focus">True</property>
<child>
<object class="GitgProgressBin" id="d_progress_bin">
<property name="visible">True</property>
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 3e49ed9..0dd1925 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -27,6 +27,7 @@ gitg/preferences/gitg-preferences-interface.vala
libgitg/gitg-date.vala
libgitg/gitg-diff-view.vala
libgitg/gitg-remote-notification.vala
+libgitg/gitg-repository-list-box.vala
libgitg/gitg-stage.vala
plugins/diff/gitg-diff.vala
plugins/files/gitg-files.vala
@@ -39,6 +40,7 @@ plugins/files/gitg-files.vala
[type: gettext/glade]gitg/resources/ui/gitg-commit-submodule-info.ui
[type: gettext/glade]gitg/resources/ui/gitg-create-branch-dialog.ui
[type: gettext/glade]gitg/resources/ui/gitg-create-tag-dialog.ui
+[type: gettext/glade]gitg/resources/ui/gitg-dash-view.ui
[type: gettext/glade]gitg/resources/ui/gitg-history-paned.ui
[type: gettext/glade]gitg/resources/ui/gitg-menus.ui
[type: gettext/glade]gitg/resources/ui/gitg-preferences-commit.ui
diff --git a/po/POTFILES.skip b/po/POTFILES.skip
index 99368a3..5e3bc9d 100644
--- a/po/POTFILES.skip
+++ b/po/POTFILES.skip
@@ -27,6 +27,7 @@ libgitg/gitg-authentication-dialog.c
libgitg/gitg-date.c
libgitg/gitg-diff-view.c
libgitg/gitg-remote-notification.c
+libgitg/gitg-repository-list-box.c
libgitg/gitg-stage.c
plugins/diff/gitg-diff.c
plugins/files/gitg-files.c
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]