diff --git a/gitg/Makefile.am b/gitg/Makefile.am index 08a5b767..100a4ec0 100644 --- a/gitg/Makefile.am +++ b/gitg/Makefile.am @@ -77,6 +77,7 @@ gitg_gitg_VALASOURCES = \ gitg/gitg-ref-action-fetch.vala \ gitg/gitg-ref-action-rename.vala \ gitg/gitg-remote-manager.vala \ + gitg/gitg-remote-notification.vala \ gitg/gitg-resource.vala \ gitg/gitg-ui-elements.vala \ gitg/gitg-window.vala \ diff --git a/gitg/gitg-notifications.vala b/gitg/gitg-notifications.vala index ce6dfa64..2f33db29 100644 --- a/gitg/gitg-notifications.vala +++ b/gitg/gitg-notifications.vala @@ -25,11 +25,13 @@ public class Notifications : Object, GitgExt.Notifications private Gtk.Overlay d_overlay; private Gee.HashSet d_delay_handles; private Gtk.Box d_box; + private Gee.HashMap d_handles; public Notifications(Gtk.Overlay overlay) { d_overlay = overlay; d_delay_handles = new Gee.HashSet(); + d_handles = new Gee.HashMap(); d_box = new Gtk.Box(Gtk.Orientation.VERTICAL, 3); d_box.get_style_context().add_class("notifications"); @@ -48,49 +50,57 @@ public class Notifications : Object, GitgExt.Notifications d_delay_handles.clear(); + foreach (var notification in d_handles.keys) + { + notification.disconnect(d_handles[notification]); + } + + d_handles.clear(); + base.dispose(); } - public void add(Gtk.Widget widget) + public new void add(GitgExt.Notification notification) { var revealer = new Gtk.Revealer(); revealer.margin_top = 1; revealer.set_transition_duration(500); revealer.set_transition_type(Gtk.RevealerTransitionType.SLIDE_UP); - revealer.add(widget); + revealer.add(notification.widget); - widget.show(); + notification.widget.show(); revealer.show(); d_box.add(revealer); revealer.reveal_child = true; + + d_handles[notification] = notification.close.connect((delay) => { + remove(notification, delay); + }); } - private void remove_now(Gtk.Widget widget) + private void remove_now(GitgExt.Notification notification) { - var revealer = widget.get_parent() as Gtk.Revealer; + var revealer = notification.widget.get_parent() as Gtk.Revealer; + + notification.disconnect(d_handles[notification]); revealer.notify["child-revealed"].connect(() => { - revealer.remove(widget); + revealer.remove(notification.widget); revealer.destroy(); }); revealer.reveal_child = false; } - public void remove(Gtk.Widget widget, uint delay) + public void remove(GitgExt.Notification notification, uint delay) { - if (delay == 0) - { - remove_now(widget); - } - uint id = 0; id = Timeout.add(delay, () => { d_delay_handles.remove(id); - remove_now(widget); + remove_now(notification); return false; }); diff --git a/gitg/gitg-ref-action-fetch.vala b/gitg/gitg-ref-action-fetch.vala index ba5b8e57..bf0b5ac5 100644 --- a/gitg/gitg-ref-action-fetch.vala +++ b/gitg/gitg-ref-action-fetch.vala @@ -90,7 +90,7 @@ class RefActionFetch : GitgExt.UIElement, GitgExt.Action, GitgExt.RefAction, Obj get { return d_remote != null; } } - public void activate() + public async bool fetch() { var notification = new RemoteNotification(d_remote); application.notifications.add(notification); @@ -99,7 +99,7 @@ class RefActionFetch : GitgExt.UIElement, GitgExt.Action, GitgExt.RefAction, Obj var updates = new Gee.ArrayList(); - var tip_updated_id = d_remote.tip_updated.connect((remote, name, a, b) => { + var tip_updated_id = d_remote.tip_updated.connect((d_remote, name, a, b) => { if (a.is_zero()) { /* Translators: new refers to a new remote reference having been fetched, */ @@ -112,35 +112,41 @@ class RefActionFetch : GitgExt.UIElement, GitgExt.Action, GitgExt.RefAction, Obj } }); - d_remote.fetch.begin(null, null, (obj, res) =>{ - try - { - d_remote.fetch.end(res); - } - catch (Error e) - { - notification.error(_("Failed to fetch from %s: %s").printf(d_remote.get_url(), e.message)); - stderr.printf("Failed to fetch: %s\n", e.message); - return; - } - finally - { - (d_remote as Object).disconnect(tip_updated_id); - } + try + { + yield d_remote.fetch(null, null); + } + catch (Error e) + { + notification.error(_("Failed to fetch from %s: %s").printf(d_remote.get_url(), e.message)); + stderr.printf("Failed to fetch: %s\n", e.message); - if (updates.size == 0) - { - /* Translators: the %s will get replaced with the remote url, */ - notification.success(_("Fetched from %s: everything is up to date").printf(d_remote.get_url())); - } - else - { - /* Translators: the first %s is the remote url to fetch from, - * the second is a list of references that got updated. */ - notification.success(_("Fetched from %s: %s").printf(d_remote.get_url(), string.joinv(", ", updates.to_array()))); - } + return false; + } + finally + { + ((Object)d_remote).disconnect(tip_updated_id); + } - application.notifications.remove(notification, 3000); + if (updates.size == 0) + { + /* Translators: the %s will get replaced with the remote url, */ + notification.success(_("Fetched from %s: everything is up to date").printf(d_remote.get_url())); + } + else + { + /* Translators: the first %s is the remote url to fetch from, + * the second is a list of references that got updated. */ + notification.success(_("Fetched from %s: %s").printf(d_remote.get_url(), string.joinv(", ", updates.to_array()))); + } + + return true; + } + + public void activate() + { + fetch.begin((obj, res) => { + fetch.end(res); }); } } diff --git a/libgitg/gitg-remote-notification.vala b/gitg/gitg-remote-notification.vala similarity index 55% rename from libgitg/gitg-remote-notification.vala rename to gitg/gitg-remote-notification.vala index aabaeaa3..185a88bd 100644 --- a/libgitg/gitg-remote-notification.vala +++ b/gitg/gitg-remote-notification.vala @@ -21,8 +21,11 @@ namespace Gitg { [GtkTemplate (ui = "/org/gnome/gitg/ui/gitg-remote-notification.ui")] -public class RemoteNotification : ProgressBin +public class RemoteNotification : ProgressBin, GitgExt.Notification { + // Do this to pull in config.h before glib.h (for gettext...) + private const string version = Gitg.Config.VERSION; + private Remote? d_remote; [GtkChild ( name = "image_icon" )] @@ -37,7 +40,8 @@ public class RemoteNotification : ProgressBin private bool d_finished; public signal void cancel(); - public signal void close(); + + private string d_text; public RemoteNotification(Remote remote) { @@ -47,53 +51,85 @@ public class RemoteNotification : ProgressBin d_remote.bind_property("transfer-progress", this, "fraction"); } + public Gtk.Widget? widget + { + owned get { return this; } + } + public void success(string text) { - d_image_icon.icon_name = "emblem-ok-symbolic"; - this.text = text; + Idle.add(() => { + d_image_icon.icon_name = "emblem-ok-symbolic"; + this.text = text; - get_style_context().add_class("success"); + get_style_context().add_class("success"); - finish(); + finish(); + + return false; + }); } public void error(string text) { - d_image_icon.icon_name = "network-error-symbolic"; - this.text = text; + Idle.add(() => { + d_image_icon.icon_name = "network-error-symbolic"; + this.text = text; - get_style_context().add_class("error"); - finish(); + get_style_context().add_class("error"); + finish(); + + return false; + }); } private void finish() { - d_finished = true; - d_button_cancel.label = _("Close"); + Idle.add(() => { + d_finished = true; + d_button_cancel.label = _("Close"); + + close(3000); + return false; + }); } public string text { - get { return d_label_text.label; } - set { d_label_text.label = value; } + get + { + return d_text; + } + + set + { + Idle.add(() => { + d_label_text.label = value; + return false; + }); + } } public RemoteState remote_state { set { - switch (value) - { - case Gitg.RemoteState.CONNECTING: - d_image_icon.icon_name = "network-wireless-acquiring-symbolic"; - break; - case Gitg.RemoteState.CONNECTED: - d_image_icon.icon_name = "network-idle-symbolic"; - break; - case Gitg.RemoteState.TRANSFERRING: - d_image_icon.icon_name = "network-transmit-receive-symbolic"; - break; - } + Idle.add(() => { + switch (value) + { + case Gitg.RemoteState.CONNECTING: + d_image_icon.icon_name = "network-wireless-acquiring-symbolic"; + break; + case Gitg.RemoteState.CONNECTED: + d_image_icon.icon_name = "network-idle-symbolic"; + break; + case Gitg.RemoteState.TRANSFERRING: + d_image_icon.icon_name = "network-transmit-receive-symbolic"; + break; + } + + return false; + }); } } diff --git a/gitg/resources/gitg-resources.xml b/gitg/resources/gitg-resources.xml index a3d9d972..515e65f4 100644 --- a/gitg/resources/gitg-resources.xml +++ b/gitg/resources/gitg-resources.xml @@ -21,6 +21,8 @@ ui/gitg-create-branch-dialog.ui ui/gitg-create-tag-dialog.ui ui/gitg-dash-view.ui + ui/gitg-remote-notification.ui + ui/style.css diff --git a/libgitg/resources/ui/gitg-remote-notification.ui b/gitg/resources/ui/gitg-remote-notification.ui similarity index 100% rename from libgitg/resources/ui/gitg-remote-notification.ui rename to gitg/resources/ui/gitg-remote-notification.ui diff --git a/libgitg-ext/Makefile.am b/libgitg-ext/Makefile.am index 0e48656e..64617ed4 100644 --- a/libgitg-ext/Makefile.am +++ b/libgitg-ext/Makefile.am @@ -54,6 +54,7 @@ libgitg_ext_libgitg_ext_1_0_la_VALASOURCES = \ libgitg-ext/gitg-ext-message-bus.vala \ libgitg-ext/gitg-ext-message-id.vala \ libgitg-ext/gitg-ext-message.vala \ + libgitg-ext/gitg-ext-notification.vala \ libgitg-ext/gitg-ext-notifications.vala \ libgitg-ext/gitg-ext-preferences.vala \ libgitg-ext/gitg-ext-ref-action-interface.vala \ diff --git a/libgitg-ext/gitg-ext-notification.vala b/libgitg-ext/gitg-ext-notification.vala new file mode 100644 index 00000000..cdfcb2f0 --- /dev/null +++ b/libgitg-ext/gitg-ext-notification.vala @@ -0,0 +1,31 @@ +/* + * This file is part of gitg + * + * Copyright (C) 2015 - Jesse van den Kieboom + * + * 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 . + */ + +namespace GitgExt +{ + +public interface Notification : Object +{ + public signal void close(uint delay = 0); + public abstract Gtk.Widget? widget { owned get; } +} + +} + +// ex:set ts=4 noet: diff --git a/libgitg-ext/gitg-ext-notifications.vala b/libgitg-ext/gitg-ext-notifications.vala index 2b4d9de4..873901fc 100644 --- a/libgitg-ext/gitg-ext-notifications.vala +++ b/libgitg-ext/gitg-ext-notifications.vala @@ -22,8 +22,8 @@ namespace GitgExt public interface Notifications : Object { - public abstract void add(Gtk.Widget widget); - public abstract void remove(Gtk.Widget widget, uint delay); + public abstract void add(Notification notification); + public abstract void remove(Notification notification, uint delay); } } diff --git a/libgitg/Makefile.am b/libgitg/Makefile.am index 35b49b0d..efa6f3d2 100644 --- a/libgitg/Makefile.am +++ b/libgitg/Makefile.am @@ -81,7 +81,6 @@ libgitg_libgitg_1_0_la_VALASOURCES = \ libgitg/gitg-ref-base.vala \ libgitg/gitg-ref.vala \ libgitg/gitg-remote.vala \ - libgitg/gitg-remote-notification.vala \ libgitg/gitg-repository-list-box.vala \ libgitg/gitg-repository.vala \ libgitg/gitg-sidebar.vala \ diff --git a/libgitg/resources/resources.xml b/libgitg/resources/resources.xml index 1c3053d6..6368ba62 100644 --- a/libgitg/resources/resources.xml +++ b/libgitg/resources/resources.xml @@ -11,7 +11,6 @@ ui/gitg-repository-list-box-row.ui ui/gitg-authentication-dialog.ui ui/gitg-sidebar.ui - ui/gitg-remote-notification.ui