/** * Status icon and menu for component of gitlive. * * Implements XObject - however we want to control initialization. * * * * Currently only does a few things * a) Quit * * b) Pause!??! */ // Compile:: // valac --pkg gtk+-3.0 StatusIcon.vala -o /tmp/StatusIcon //var gitlive = imports.gitlive; using Gtk; /* static int main (string[] args) { // A reference to our file Gtk.init (ref args); new StatusIconA(); Gtk.main (); return 0; } */ //public StatusIconA statusicon; public class StatusIconA : StatusIcon { public bool paused = false; public static StatusIconA statusicon; public StatusIconA() { statusicon = this; //title : 'gitlive', this.stock = Gtk.Stock.REFRESH; this.tooltip_text = "GitLive"; this.title = "gitlive"; this.set_name("gitlive"); this.set_visible(true); var menu = new GitliveMenu(); menu.ref(); this.button_press_event.connect( ( ev ) =>{ print("button press event called\n"); menu.updateMerges(); menu.show_all(); if (this.paused) { menu.resume.show(); menu.pause.hide(); } else { menu.resume.hide(); menu.pause.show(); } // public void popup (Gtk.Widget? parent_menu_shell, Gtk.Widget? parent_menu_item, // [CCode (scope = "async")] Gtk.MenuPositionFunc? func, uint button, uint32 activate_time); //Gtk.get_current_event_device () menu.popup( null, null, this.position_menu, ev.button, ev.time // time ); return true; }); this.popup_menu.connect( ( button, time) =>{ //this.button_press_event.connect( ( ) =>{ //print(Array.prototype.slice.call(arguments).join(',')); print("menu activiate called\n"); menu.updateMerges(); //var menu = this.get('menu'); menu.show_all(); if (this.paused) { menu.resume.show(); menu.pause.hide(); } else { menu.resume.hide(); menu.pause.show(); } // public void popup (Gtk.Widget? parent_menu_shell, Gtk.Widget? parent_menu_item, // [CCode (scope = "async")] Gtk.MenuPositionFunc? func, uint button, uint32 activate_time); //Gtk.get_current_event_device () menu.popup( null, null, this.position_menu, button, time // time ); //var g = { }; //var a = new Gdk.Rectangle(); // needs direction=inout setting in gir to work (in bugzilla @present) //this.el.get_geometry(g,a,null); // should check to see if @ top or bottom I guess.. //menu.el.get_toplevel().move(a.x, a.y +a.height); //menu.el.get_toplevel().move(10,10); //return false; }); } public void pause() { this.set_from_stock( Gtk.Stock.MEDIA_PAUSE ); this.paused = true; } public void resume() { this.set_from_stock( Gtk.Stock.MEDIA_PLAY ); this.paused = false; } public void refreshing() { this.set_from_stock( Gtk.Stock.REFRESH ); } public void pauseError() { this.paused = true; var flag = true; Timeout.add_full(Priority.LOW, 500, () => { if (!this.paused) { return false; } this.set_from_stock( flag == true ? Gtk.Stock.MEDIA_RECORD : Gtk.Stock.MEDIA_PAUSE); flag = !flag; return true; }); } class GitliveMenu : Gtk.Menu { public ImageMenuItem pause; public ImageMenuItem resume; public Gtk.MenuItem before_seperator; public Gtk.MenuItem after_seperator; public GitliveMenu() { this.pause = new MenuItemPause(); this.append(this.pause); this.resume = new MenuItemStartCommits(); this.append(this.resume); this.append(new MenuItemPullAll()); this.before_seperator = new Gtk.SeparatorMenuItem(); this.append(this.before_seperator); this.after_seperator = new Gtk.SeparatorMenuItem(); this.append(this.after_seperator); //this.append(new MenuItemUpdateTimesheet()); this.append(new MenuItemManageClones()); this.append(new MenuItemNewTicket()); this.append(new MenuItemAbout()); this.append(new MenuItemQuit()); this.merge_items = new Gee.ArrayList(); } public Gee.ArrayList merge_items; public void updateMerges() { // show a list of possible merges on the menu. foreach (var m in this.merge_items) { this.remove(m); } foreach(var r in GitRepo.singleton().cache.values ) { GLib.debug("checking %s for branch = %s", r.name, r.currentBranch.name); if (!r.is_wip_branch()) { continue; } GLib.debug("checking for activeTicket"); var t = r.activeTicket; if (t == null) { continue; } var mi = new MergeMenuItem(r,t); this.insert (mi,4); //backwards. this.merge_items.add(mi); } } class MergeMenuItem : Gtk.MenuItem { GitRepo repo; RooTicket ticket; public MergeMenuItem(GitRepo r, RooTicket t) { this.repo = r; this.ticket = t; this.label = ("Merge [%s] #%s %s".printf(r.name, t.id , t.summary)); this.activate.connect(() => { MergeBranch.singleton().show(this.ticket, null); // show merge dialog.. }); } } class MenuItemPause : ImageMenuItem { public MenuItemPause() { //this.set_from_stock( Gtk.Stock.MEDIA_PAUSE ); var image = new Gtk.Image(); image.set_from_stock(Gtk.Stock.MEDIA_PAUSE,Gtk.IconSize.MENU ); this.set_image (image); this.label= "Pause Commits"; this.always_show_image = true; this.accel_group = null; this.activate.connect( () => { statusicon.paused = true; GitMonitor.gitmonitor.stop(); // this.el.label = status ? 'Resume' : 'Pause'; statusicon.set_from_stock( Gtk.Stock.MEDIA_PAUSE ); }); // id : 'pause', } } class MenuItemStartCommits : ImageMenuItem { public MenuItemStartCommits() { var image = new Gtk.Image(); image.set_from_stock(Gtk.Stock.MEDIA_PLAY,Gtk.IconSize.MENU ); this.set_image (image); this.label= "Start Commits"; this.always_show_image = true; this.accel_group = null; this.activate.connect( () => { GitMonitor.gitmonitor.start(); statusicon.paused = false; // // this.el.label = status ? 'Resume' : 'Pause'; statusicon.set_from_stock( Gtk.Stock.MEDIA_PLAY ); }); } } class MenuItemPullAll : ImageMenuItem { public MenuItemPullAll() { var image = new Gtk.Image(); image.set_from_stock(Gtk.Stock.FULLSCREEN,Gtk.IconSize.MENU ); this.set_image (image); this.label= "Pull (Refresh) All"; this.always_show_image = true; this.accel_group = null; this.activate.connect( () => { this.pullAll(); /* GitMonitor.gitmonitor.stop(); var tr = GitRepo.list(); for (var i= 0; i< tr.length;i++) { statusicon.set_from_stock( i%2 == 0 ? Gtk.Stock.FULLSCREEN : Gtk.Stock.LEAVE_FULLSCREEN ); var repo = tr.index(i); //if (!repo.autocommit()) { //??? should we ignore ones not on autocommit.. // continue; //} try { statusicon.set_tooltip_text("pull: " + repo.name); var str = repo.pull(); // do not care if it's already in sycn.. if (Regex.match_simple ("Already up-to-date", str) ) { continue; } var notification = new Notify.Notification( "Updated " + repo.name, str, "dialog-information" ); notification.set_timeout(20); notification.show(); } catch(Error e) { print("notification or push errror- probably to many in queue.."); statusicon.set_from_stock( Gtk.Stock.MEDIA_RECORD ); print(e.message); } } */ }); } void pullAll() { var tr = GitRepo.list(); GitMonitor.gitmonitor.stop(); this.total = tr.length; this.has_error = 0; this.pull_all_error_message = ""; for (var i= 0; i< tr.length;i++) { statusicon.set_from_stock( i%2 == 0 ? Gtk.Stock.FULLSCREEN : Gtk.Stock.LEAVE_FULLSCREEN ); var repo = tr.index(i); //repo.ref(); //this.ref(); statusicon.set_tooltip_text("pull: " + repo.name); repo.pull_async(this.pullAllCallback); // do not care if it's already in sycn.. } } uint total = 0; uint has_error = 0; string pull_all_error_message = ""; void pullAllCallback(GitRepo repo, int err, string res) { this.total--; if (err > 0) { this.has_error = 1; this.pull_all_error_message += this.pull_all_error_message.length > 0 ? "\n" : ""; this.pull_all_error_message += "Error Pulling " + repo.name +"\n" + res; } if (!Regex.match_simple ("Already up-to-date", res) ) { var notification = new Notify.Notification( "Pull completed ", "Updated: " +repo.name + "\n" + res +"\n", "dialog-information" ); notification.set_timeout(20); notification.show(); } if (this.total < 1) { if (this.has_error > 0) { GitMonitor.gitmonitor.pauseError(this.pull_all_error_message); return; } statusicon.set_tooltip_text("Gitlive"); GitMonitor.gitmonitor.start(); //this.unref(); //repo.unref(); } } } class MenuItemUpdateTimesheet : ImageMenuItem { public MenuItemUpdateTimesheet() { var image = new Gtk.Image(); image.set_from_stock(Gtk.Stock.SAVE,Gtk.IconSize.MENU ); this.set_image (image); this.label= "Update Timesheet"; this.always_show_image = true; this.accel_group = null; this.activate.connect( () => { //var ret = imports.FixBug.FixBug.show(); }); } } class MenuItemManageClones : ImageMenuItem { public MenuItemManageClones() { var image = new Gtk.Image(); image.set_from_stock(Gtk.Stock.FULLSCREEN,Gtk.IconSize.MENU ); this.set_image (image); this.label= "Manage Clones"; this.always_show_image = true; this.accel_group = null; this.activate.connect( () => { GitRepo.updateAll("show_clones"); // Clones.singleton().show(); }); } } class MenuItemNewTicket : ImageMenuItem { public MenuItemNewTicket() { var image = new Gtk.Image(); image.set_from_stock(Gtk.Stock.FULLSCREEN,Gtk.IconSize.MENU ); this.set_image (image); this.label= "New Ticket"; this.always_show_image = true; this.accel_group = null; this.activate.connect( () => { Ticket.singleton().show(null); // Clones.singleton().show(); }); } } class MenuItemAbout : ImageMenuItem { public MenuItemAbout() { var image = new Gtk.Image(); image.set_from_stock(Gtk.Stock.ABOUT,Gtk.IconSize.MENU ); this.set_image (image); this.label= "About Gitlive"; this.always_show_image = true; this.accel_group = null; this.activate.connect( () => { //var ret = imports.Clones.Clones.show(); var msg = new Gtk.AboutDialog(); msg.program_name = "Git Live"; msg.version= "0.3"; msg.website= "http://www.roojs.org/index.php/projects/gitlive.html"; msg.website_label= "Roo J Solutions Ltd."; msg.license = "LGPL"; msg.authors = { "Alan Knowles " }; msg.run(); msg.destroy(); }); } } class MenuItemQuit : ImageMenuItem { public MenuItemQuit() { var image = new Gtk.Image(); image.set_from_stock(Gtk.Stock.QUIT,Gtk.IconSize.MENU ); this.set_image (image); this.label= "Quit"; this.always_show_image = true; this.accel_group = null; this.activate.connect( () => { // confirm? Gtk.main_quit(); //var ret = imports.Clones.Clones.show(); }); } } } }