using Notify; using GLib; using Gtk; namespace VineLinux { class UpdateNotification : Notify.Notification { private TrayIcon tray_icon; public UpdateNotification(TrayIcon icon) { tray_icon = icon; } public void showNotification(int packages) { string title = _("Package Update"); string content; string icon = "vine-notify-update-red"; if (packages > 1) { content = _("%d packages are available to upgrade.").printf(packages); } else if (packages > 0) { content = _("An package is.available to upgrade."); } else { title = _("This system is up to date."); content = ""; icon = "vine-notify-update"; } try { update(title, content, icon); if (packages > 0) { show(); } } catch(GLib.Error e) { GLib.warning ("Notification.show() [%s]", e.message); } } public override void closed() { if (this.closed_reason == 2) { tray_icon.showDialogs(); } } } class RebootNotification : Notify.Notification { private TrayIcon tray_icon; public RebootNotification(TrayIcon icon) { tray_icon = icon; summary = _("Restarting computer is required"); body = _("You must restart this computer to use upgraded software."); icon_name = "vine-notify-update-orange"; } public void showNotification() { try { show(); } catch(GLib.Error e) { GLib.warning ("Notification.show() [%s]", e.message); } } public override void closed() { if (this.closed_reason == 2) { tray_icon.showDialogs(); } } } [DBus (name = "org.vinelinux.NotifyUpdate")] class NotificationReceiver : Object { UpdateNotification upgrade_notification; RebootNotification reboot_notification; public int upgrade_packages; public int require_reboot; private TrayIcon tray_icon; public NotificationReceiver(TrayIcon icon) { tray_icon = icon; upgrade_notification = new UpdateNotification(icon); reboot_notification = new RebootNotification(icon); upgrade_packages = 0; require_reboot = 0; Bus.own_name (BusType.SYSTEM, "org.vinelinux.NotifyUpdate", BusNameOwnerFlags.NONE, onBusAquired, () => stderr.printf ("Bus name aquired\n"), () => stderr.printf ("Could not aquire name\n")); } private void onBusAquired(DBusConnection conn) { try { conn.register_object("/org/vinelinux/NotifyUpdate", this); } catch(IOError e) { GLib.critical("Could not register service"); } } public void showMessage(string msg) { string[] params = msg.split(" "); string icon_name; if (params.length != 2) { GLib.warning("invalid parameter: %s", msg); return; } upgrade_packages = int.parse(params[0]); require_reboot = int.parse(params[1]); if (upgrade_packages > 0) { icon_name = "vine-notify-update-red"; upgrade_notification.showNotification(upgrade_packages); } else if (require_reboot != 0) { icon_name = "vine-notify-update-orange"; reboot_notification.showNotification(); } else { icon_name = "vine-notify-update"; upgrade_notification.showNotification(0); } tray_icon.set_from_icon_name(icon_name); } } class TrayIcon: Gtk.StatusIcon { Gtk.Menu menu; Gtk.ImageMenuItem menuitem_quit; NotificationReceiver receiver; public TrayIcon() { set_from_icon_name("vine-notify-update"); receiver = new NotificationReceiver(this); initActions(); } private void initActions() { activate.connect(() => { showDialogs(); }); menu = new Gtk.Menu(); menuitem_quit = new Gtk.ImageMenuItem.from_stock(Gtk.Stock.QUIT, null); menu.append(menuitem_quit); menu.show_all(); popup_menu.connect((source, button, activate_time) => { menu.popup(null, null, source.position_menu, button, activate_time); }); menuitem_quit.activate.connect(Gtk.main_quit); } public void showDialogs() { if (receiver.upgrade_packages > 0) { showUpgradeDialog(receiver.upgrade_packages); } else if (receiver.require_reboot != 0) { showRebootDialog(); } else { showUpToDateDialog(); } } private void showUpToDateDialog() { var dialog = new Gtk.MessageDialog(null, Gtk.DialogFlags.MODAL, Gtk.MessageType.INFO, Gtk.ButtonsType.OK, ""); dialog.title = _("Package Update"); dialog.text = _("This system is up to date."); dialog.run(); dialog.destroy(); } private void showUpgradeDialog(int upgrade_packages) { Builder builder = new Builder(); Dialog dialog; Label summary; Gtk.ListStore store; FileStream f; string pkg; builder.set_translation_domain("vine-notify-update"); builder.add_from_file("/usr/share/vine-notify-update/vine-notify-update.glade"); dialog = builder.get_object("upgrade_dialog") as Dialog; summary = builder.get_object("summary") as Label; store = builder.get_object("pkglist") as Gtk.ListStore; if (upgrade_packages > 1) { summary.set_text(_("%d packages will be upgraded. Are you sure?").printf(upgrade_packages)); } else { summary.set_text(_("A package will be upgraded. Are you sure?")); } if ((f = FileStream.open("/var/run/upgrade-list.txt", "r")) == null) { //dialog.destroy(); return; } while (!f.eof()) { TreeIter iter; pkg = f.read_line(); if (pkg != null && pkg.strip() != "") { store.append(out iter); store.set(iter, 0, pkg); } } if (dialog.run() == 1) { GLib.warning ("dialog: ok"); try { GLib.Process.spawn_command_line_async("synaptic --upgrade-mode --non-interactive --hide-main-window -o Synaptic::AskRelated=false"); } catch(SpawnError e) { GLib.warning ("cannot execute synaptic: [%s]", e.message); } } dialog.destroy(); } private void showRebootDialog() { var dialog = new Gtk.MessageDialog(null, Gtk.DialogFlags.MODAL, Gtk.MessageType.QUESTION, Gtk.ButtonsType.YES_NO, ""); dialog.title = _("Package Update"); dialog.text = _("You must restart this computer to use upgraded software."); if (dialog.run() == Gtk.ResponseType.YES) { } dialog.destroy(); } } class NotifyUpdateMain { public static int main(string[] args) { TrayIcon status_icon; Gtk.init(ref args); if (!Notify.init("vine-notify-update")) { GLib.critical("Couldn't initialize libnotify"); return 1; } status_icon = new TrayIcon(); Gtk.main(); return 0; } } }