[gitg] Remote branches can be checked out using double-click.
- From: Alberto Fanjul <albfan src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gitg] Remote branches can be checked out using double-click.
- Date: Fri, 12 Jun 2020 10:00:24 +0000 (UTC)
commit 754cde5e822cf21d4f6f5719b7f7aab6c3074863
Author: Armandas Jarušauskas <jarusauskas gmail com>
Date: Tue Jun 9 20:50:31 2020 +0900
Remote branches can be checked out using double-click.
gitg/gitg-checkout-remote-branch-dialog.vala | 141 +++++++++++++++++++
gitg/gitg-ref-action-checkout.vala | 79 ++++++++++-
gitg/history/gitg-history.vala | 2 +-
gitg/meson.build | 2 +
gitg/resources/gitg-resources.xml.in | 1 +
.../ui/gitg-checkout-remote-branch-dialog.ui | 152 +++++++++++++++++++++
tests/gitg/checkout-remote-branch-dialog-mock.vala | 51 +++++++
tests/gitg/meson.build | 1 +
8 files changed, 424 insertions(+), 5 deletions(-)
---
diff --git a/gitg/gitg-checkout-remote-branch-dialog.vala b/gitg/gitg-checkout-remote-branch-dialog.vala
new file mode 100644
index 00000000..28195ae4
--- /dev/null
+++ b/gitg/gitg-checkout-remote-branch-dialog.vala
@@ -0,0 +1,141 @@
+/*
+ * This file is part of gitg
+ *
+ * Copyright (C) 2020 - Armandas Jarušauskas
+ *
+ * gitg 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * gitg 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 gitg. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+namespace Gitg
+{
+
+[GtkTemplate (ui = "/org/gnome/gitg/ui/gitg-checkout-remote-branch-dialog.ui")]
+class CheckoutRemoteBranchDialog : Gtk.Dialog
+{
+ [GtkChild]
+ private Gtk.Button d_button_create;
+
+ [GtkChild]
+ private Gtk.Entry d_branch_name;
+
+ [GtkChild]
+ private Gtk.ComboBoxText d_remote_branch_name;
+
+ [GtkChild]
+ private Gtk.CheckButton d_track_remote;
+
+ private Gitg.Repository d_repository;
+ private Gitg.Ref d_remote_reference;
+
+ construct
+ {
+ d_branch_name.changed.connect(() => {
+ d_button_create.sensitive = entries_valid();
+ });
+
+ d_remote_branch_name.changed.connect(() => {
+ d_button_create.sensitive = entries_valid();
+ });
+
+ set_default(d_button_create);
+ set_default_response(Gtk.ResponseType.OK);
+ }
+
+ public CheckoutRemoteBranchDialog(Gtk.Window? parent, Gitg.Repository? repository, Gitg.Ref reference)
+ {
+ Object(use_header_bar : 1);
+
+ if (parent != null)
+ {
+ set_transient_for(parent);
+ }
+
+ if (repository != null)
+ {
+ d_repository = repository;
+ }
+
+ if (reference.is_remote())
+ {
+ d_remote_reference = reference;
+ }
+ }
+
+ public string new_branch_name
+ {
+ owned get
+ {
+ return d_branch_name.text.strip();
+ }
+ }
+
+ public string remote_branch_name
+ {
+ owned get
+ {
+ return d_remote_branch_name.get_active_text();
+ }
+ }
+
+ public bool track_remote
+ {
+ get
+ {
+ return d_track_remote.active;
+ }
+ }
+
+ public override void show()
+ {
+ base.show();
+
+ update_entries();
+ }
+
+ private bool entries_valid()
+ {
+ return (new_branch_name.length != 0) && (d_remote_branch_name.get_active_text() != null);
+ }
+
+ private void update_entries()
+ {
+ d_branch_name.set_text(d_remote_reference.parsed_name.remote_branch);
+
+ try
+ {
+ d_repository.references_foreach_name((name) => {
+ Gitg.Ref? reference;
+ try
+ {
+ reference = d_repository.lookup_reference(name);
+ } catch { return 0; }
+
+ if (!reference.is_remote() || (reference.get_reference_type() ==
Ggit.RefType.SYMBOLIC))
+ {
+ return 0;
+ }
+
+ d_remote_branch_name.append(reference.parsed_name.shortname,
reference.parsed_name.shortname);
+
+ return 0;
+ });
+ } catch {}
+
+ d_remote_branch_name.set_active_id(d_remote_reference.parsed_name.shortname);
+ }
+}
+
+}
+
+// ex: ts=4 noet
diff --git a/gitg/gitg-ref-action-checkout.vala b/gitg/gitg-ref-action-checkout.vala
index 834b095c..8a691d83 100644
--- a/gitg/gitg-ref-action-checkout.vala
+++ b/gitg/gitg-ref-action-checkout.vala
@@ -59,7 +59,7 @@ class RefActionCheckout : GitgExt.UIElement, GitgExt.Action, GitgExt.RefAction,
{
try
{
- return reference.is_branch() && !((Ggit.Branch)reference).is_head();
+ return (reference.is_branch() && !((Ggit.Branch)reference).is_head()) ||
reference.is_remote();
} catch {}
return false;
@@ -127,9 +127,80 @@ class RefActionCheckout : GitgExt.UIElement, GitgExt.Action, GitgExt.RefAction,
public void activate()
{
- checkout.begin((obj, res) => {
- checkout.end(res);
- });
+ if (reference.is_branch())
+ {
+ checkout.begin();
+ }
+ else if (reference.is_remote())
+ {
+ var dlg = new CheckoutRemoteBranchDialog((Gtk.Window)application,
application.repository, reference);
+ dlg.response.connect((d, resp) => {
+ on_checkout_remote_branch_dialog_response(dlg, resp);
+ });
+
+ dlg.show();
+ }
+ }
+
+ private void on_checkout_remote_branch_dialog_response(Gitg.CheckoutRemoteBranchDialog dialog, int
response_id) {
+ if (response_id == Gtk.ResponseType.OK)
+ {
+ string? remote_branch_name = dialog.track_remote ? dialog.remote_branch_name : null;
+
+ create_branch.begin(reference, dialog.new_branch_name, remote_branch_name, (obj, res)
=> {
+ var branch_ref = create_branch.end(res) as Gitg.Ref;
+
+ if (branch_ref != null)
+ {
+ action_interface.add_ref(branch_ref);
+ reference = branch_ref;
+ checkout.begin();
+ }
+ });
+ }
+
+ dialog.destroy();
+ }
+
+ private async Ggit.Branch? create_branch(Ggit.Ref reference, string new_branch_name, string?
remote_branch_name)
+ {
+ Ggit.Branch? branch = null;
+
+ var repo = application.repository;
+
+ try
+ {
+ Gitg.Commit commit = reference.lookup() as Gitg.Commit;
+ branch = repo.create_branch(new_branch_name,
+ commit,
+ Ggit.CreateFlags.NONE);
+ }
+ catch (Error e)
+ {
+ application.show_infobar(_("Failed to create branch"),
+ e.message,
+ Gtk.MessageType.ERROR);
+ }
+
+ if (branch != null)
+ {
+ if (remote_branch_name != null) {
+ try
+ {
+ branch.set_upstream(remote_branch_name);
+ }
+ catch (Error e)
+ {
+ application.show_infobar(
+ _("Failed to set the upstream branch %s for
%s").printf(remote_branch_name,
+ new_branch_name),
+ e.message,
+ Gtk.MessageType.ERROR);
+ }
+ }
+ }
+
+ return branch;
}
}
diff --git a/gitg/history/gitg-history.vala b/gitg/history/gitg-history.vala
index 02582e2e..87289eb6 100644
--- a/gitg/history/gitg-history.vala
+++ b/gitg/history/gitg-history.vala
@@ -1123,7 +1123,7 @@ namespace GitgHistory
return;
}
- if (ref_row.reference.is_branch()) {
+ if (ref_row.reference.is_branch() || ref_row.reference.is_remote()) {
var af = new ActionInterface(application, d_main.refs_list);
var checkout = new Gitg.RefActionCheckout(application, af, ref_row.reference);
checkout.activate();
diff --git a/gitg/meson.build b/gitg/meson.build
index 51b341e1..85688b65 100644
--- a/gitg/meson.build
+++ b/gitg/meson.build
@@ -33,6 +33,7 @@ sources = gitg_sources + files(
'gitg-convert.vala',
'gitg-create-branch-dialog.vala',
'gitg-create-tag-dialog.vala',
+ 'gitg-checkout-remote-branch-dialog.vala',
'gitg-dash-view.vala',
'gitg-dirs.vala',
'gitg-notifications.vala',
@@ -109,6 +110,7 @@ resource_data = files(
'resources/ui/gitg-shortcuts.ui',
'resources/ui/gitg-simple-notification.ui',
'resources/ui/gitg-window.ui',
+ 'resources/ui/gitg-checkout-remote-branch-dialog.ui',
'resources/ui/style.css',
'resources/ui/style-@0@.css'.format(platform_name),
)
diff --git a/gitg/resources/gitg-resources.xml.in b/gitg/resources/gitg-resources.xml.in
index a97175f5..1224cefe 100644
--- a/gitg/resources/gitg-resources.xml.in
+++ b/gitg/resources/gitg-resources.xml.in
@@ -23,6 +23,7 @@
<file compressed="true" preprocess="xml-stripblanks">ui/gitg-simple-notification.ui</file>
<file compressed="true" preprocess="xml-stripblanks">ui/gitg-remote-notification.ui</file>
<file compressed="true" preprocess="xml-stripblanks">ui/gitg-shortcuts.ui</file>
+ <file compressed="true" preprocess="xml-stripblanks">ui/gitg-checkout-remote-branch-dialog.ui</file>
<file compressed="true">ui/style.css</file>
<file compressed="true">ui/style-@PLATFORM_NAME@.css</file>
diff --git a/gitg/resources/ui/gitg-checkout-remote-branch-dialog.ui
b/gitg/resources/ui/gitg-checkout-remote-branch-dialog.ui
new file mode 100644
index 00000000..c003270b
--- /dev/null
+++ b/gitg/resources/ui/gitg-checkout-remote-branch-dialog.ui
@@ -0,0 +1,152 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <!-- interface-requires gtk+ 3.0 -->
+ <template class="GitgCheckoutRemoteBranchDialog" parent="GtkDialog">
+ <property name="can_focus">False</property>
+ <property name="border_width">12</property>
+ <property name="title" translatable="yes">Checkout Remote Branch</property>
+ <property name="resizable">False</property>
+ <property name="modal">True</property>
+ <property name="type_hint">dialog</property>
+ <child internal-child="headerbar">
+ <object class="GtkHeaderBar" id="dialog-header_bar">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="show_close_button">False</property>
+ <child>
+ <object class="GtkButton" id="button_cancel">
+ <property name="label" translatable="yes">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_underline">True</property>
+ <property name="valign">center</property>
+ <style>
+ <class name="text-button"/>
+ </style>
+ </object>
+ <packing>
+ <property name="pack_type">start</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="d_button_create">
+ <property name="label" translatable="yes">C_heckout</property>
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_underline">True</property>
+ <style>
+ <class name="text-button"/>
+ <class name="suggested-action"/>
+ </style>
+ </object>
+ <packing>
+ <property name="pack_type">end</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">2</property>
+ <child>
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">end</property>
+ <property name="label" translatable="yes">Local branch _name:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">d_branch_name</property>
+ </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="GtkEntry" id="d_branch_name">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="activates_default">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">end</property>
+ <property name="label" translatable="yes">_Remote branch:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">d_remote_branch_name</property>
+ </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>
+ <child>
+ <object class="GtkComboBoxText" id="d_remote_branch_name">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="d_track_remote">
+ <property name="label" translatable="yes">_Track remote branch</property>
+ <property name="use_underline">True</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="draw_indicator">True</property>
+ <property name="active">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-6">button_cancel</action-widget>
+ <action-widget response="-5">d_button_create</action-widget>
+ </action-widgets>
+ </template>
+</interface>
diff --git a/tests/gitg/checkout-remote-branch-dialog-mock.vala
b/tests/gitg/checkout-remote-branch-dialog-mock.vala
new file mode 100644
index 00000000..69c9307c
--- /dev/null
+++ b/tests/gitg/checkout-remote-branch-dialog-mock.vala
@@ -0,0 +1,51 @@
+/*
+ * This file is part of gitg
+ *
+ * Copyright (C) 2020 - Armandas Jarušauskas
+ *
+ * gitg 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * gitg 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 gitg. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+namespace Gitg
+{
+
+class CheckoutRemoteBranchDialog : Gtk.Dialog
+{
+ public CheckoutRemoteBranchDialog(Gtk.Window? parent, Gitg.Repository? repository, Gitg.Ref reference)
+ {
+ }
+
+ public string new_branch_name {get; set; default = "test_branch"; }
+
+ public string remote_branch_name {get; set; default = "origin/test_branch"; }
+
+ public bool track_remote {get; set; default = true; }
+
+ public override void show()
+ {
+ }
+
+ private bool entries_valid()
+ {
+ return (new_branch_name.len() != 0) && (remote_branch_name.len() != 0);
+ }
+
+ private void update_entries()
+ {
+ }
+}
+
+}
+
+// ex: ts=4 noet
diff --git a/tests/gitg/meson.build b/tests/gitg/meson.build
index 87803dd6..445f71cd 100644
--- a/tests/gitg/meson.build
+++ b/tests/gitg/meson.build
@@ -4,6 +4,7 @@ sources = gitg_sources + support_sources + files(
'notifications-mock.vala',
'ref-action-interface-mock.vala',
'simple-notification-mock.vala',
+ 'checkout-remote-branch-dialog-mock.vala',
'test-checkout-ref.vala',
'test-cherry-pick-commit.vala',
'test-merge-ref.vala',
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]