GitMonitor.vala
[gitlive] / StatusIcon.vala
1 /**
2  * Status icon and menu for component of gitlive.
3  * 
4  * Implements XObject - however we want to control initialization.
5  * 
6  * 
7  * 
8  * Currently only does a few things
9  * a) Quit
10  * 
11  * b) Pause!??!
12  */
13    
14 // Compile::
15 // valac --pkg gtk+-3.0 StatusIcon.vala -o /tmp/StatusIcon
16    
17 //var gitlive = imports.gitlive;
18
19
20 using Gtk;
21 /*
22
23 static int main (string[] args) {
24     // A reference to our file
25     Gtk.init (ref args);
26     new StatusIconA();
27  
28     Gtk.main ();
29     return 0;
30      
31
32 }
33  */
34
35
36 //public StatusIconA statusicon;
37  
38 public class StatusIconA : StatusIcon {
39
40     public bool paused = false;
41     public static StatusIconA statusicon;
42  
43     
44     public StatusIconA() {
45         
46         statusicon = this;
47         
48          //title : 'gitlive',
49         this.stock = Gtk.Stock.REFRESH;
50         this.tooltip_text = "GitLive";
51         this.title = "gitlive";
52         
53         this.set_name("gitlive");
54         this.set_visible(true);      
55         
56         var menu = new MenuA();
57         menu.ref();       
58                 this.button_press_event.connect( ( ev ) =>{
59               print("button press event called\n");
60  
61             menu.show_all();
62             
63             if (this.paused) {
64                 menu.resume.show();
65                 menu.pause.hide();
66             } else {
67                 menu.resume.hide();
68                 menu.pause.show();
69             }
70               //                public void popup (Gtk.Widget? parent_menu_shell, Gtk.Widget? parent_menu_item,
71                     // [CCode (scope = "async")] Gtk.MenuPositionFunc? func, uint button, uint32 activate_time);
72             //Gtk.get_current_event_device ()
73             menu.popup(
74
75                         null, null,
76                        this.position_menu,
77                        
78                     ev.button,  ev.time //   time
79             );
80               
81               return true;
82             
83             });
84        this.popup_menu.connect( (  button,   time) =>{
85        //this.button_press_event.connect( (  ) =>{
86  
87             //print(Array.prototype.slice.call(arguments).join(','));
88             print("menu activiate called\n");
89             //var menu = this.get('menu');
90             
91             menu.show_all();
92             
93             if (this.paused) {
94                 menu.resume.show();
95                 menu.pause.hide();
96             } else {
97                 menu.resume.hide();
98                 menu.pause.show();
99             }
100               //                public void popup (Gtk.Widget? parent_menu_shell, Gtk.Widget? parent_menu_item,
101                     // [CCode (scope = "async")] Gtk.MenuPositionFunc? func, uint button, uint32 activate_time);
102             //Gtk.get_current_event_device ()
103             menu.popup(
104
105                         null, null,
106                        this.position_menu,
107                        
108                     button,  time //   time
109             );
110                         
111             
112             //var g = { };
113             //var a = new Gdk.Rectangle();
114             //  needs direction=inout setting in gir to work (in bugzilla @present)
115             //this.el.get_geometry(g,a,null);
116              
117             // should check to see if @ top or bottom I guess..
118             //menu.el.get_toplevel().move(a.x, a.y +a.height);
119             //menu.el.get_toplevel().move(10,10);
120             //return false;
121               
122         }); 
123         
124     }
125     
126     public void pause()
127     {
128                 this.set_from_stock( Gtk.Stock.MEDIA_PAUSE );
129                 this.paused = true;
130     }
131     
132     public void resume()
133     {
134                 this.set_from_stock( Gtk.Stock.MEDIA_PLAY );
135                 this.paused = false;
136     }
137     
138     public void refreshing()
139     {
140                 this.set_from_stock( Gtk.Stock.REFRESH );
141     }
142     
143     public void pauseError()
144     {
145                  this.paused = true;
146                  var flag = true;
147                  Timeout.add_full(Priority.LOW, 500, () => {
148                  
149                         if (!this.paused) {
150                                 return false;
151                         }
152                         this.set_from_stock( flag == true ? Gtk.Stock.MEDIA_RECORD  
153                                         : Gtk.Stock.MEDIA_PAUSE);
154                         flag = !flag;
155                         return true;
156                 });
157                  
158     }
159     
160     class MenuA : Gtk.Menu
161     {
162         public ImageMenuItem pause;
163         public ImageMenuItem resume;
164         
165         public MenuA()
166         {
167             this.pause = new ImageMenuItemA();
168             this.append(this.pause);
169             this.resume = new ImageMenuItemB();
170             this.append(this.resume);
171             this.append(new ImageMenuItemC());
172             this.append(new ImageMenuItemD());
173             this.append(new ImageMenuItemE());
174             this.append(new ImageMenuItemF());
175             this.append(new ImageMenuItemG());
176             
177             
178             
179         }
180         
181         
182         class ImageMenuItemA : ImageMenuItem {
183             
184             public ImageMenuItemA()
185             {
186                 //this.set_from_stock( Gtk.Stock.MEDIA_PAUSE );
187                 
188                 var  image = new Gtk.Image();
189                 image.set_from_stock(Gtk.Stock.MEDIA_PAUSE,Gtk.IconSize.MENU );
190                 this.set_image (image);
191                 
192                 this.label= "Pause Commits";
193                 this.always_show_image = true;
194                 this.accel_group = null;
195                 
196                 this.activate.connect( () => {
197                     statusicon.paused = true;
198                     GitMonitor.gitmonitor.stop();
199
200                    // this.el.label  = status ? 'Resume' : 'Pause';
201                     statusicon.set_from_stock( Gtk.Stock.MEDIA_PAUSE );
202                     
203                     
204                 });
205                 //    id : 'pause',
206             }
207             
208             
209         }
210         class ImageMenuItemB : ImageMenuItem {
211             
212             public ImageMenuItemB()
213             {
214                 
215                 var  image = new Gtk.Image();
216                 image.set_from_stock(Gtk.Stock.MEDIA_PLAY,Gtk.IconSize.MENU );
217                 this.set_image (image);
218                 this.label= "Start Commits";
219                 this.always_show_image = true;
220                 this.accel_group = null;
221                 
222                 this.activate.connect( () => {
223                     GitMonitor.gitmonitor.start();
224                     statusicon.paused = false;
225                     
226                     //
227                    // this.el.label  = status ? 'Resume' : 'Pause';
228                     statusicon.set_from_stock( Gtk.Stock.MEDIA_PLAY );
229                     
230                     
231                 });
232             }
233             
234             
235         }
236         
237         
238         class ImageMenuItemC : ImageMenuItem {
239             
240             public ImageMenuItemC()
241             {
242                 
243                 var  image = new Gtk.Image();
244                 image.set_from_stock(Gtk.Stock.FULLSCREEN,Gtk.IconSize.MENU );
245                 this.set_image (image);
246                 this.label= "Pull (Refresh) All";
247                 this.always_show_image = true;
248                 this.accel_group = null;
249                 
250                 this.activate.connect( () => {
251                     
252                     this.pullAll();
253                     /*
254                     GitMonitor.gitmonitor.stop();
255                     var tr = GitRepo.list();
256                     
257                     
258                     
259                     for (var i= 0; i< tr.length;i++) {
260                         statusicon.set_from_stock( 
261                                 i%2 == 0 ?  Gtk.Stock.FULLSCREEN : Gtk.Stock.LEAVE_FULLSCREEN );
262                                 
263                         var repo = tr.index(i);
264                         //if (!repo.autocommit()) {
265                             //??? should we ignore ones not on autocommit..
266                         //    continue;
267                         //}
268                         try {
269                             statusicon.set_tooltip_text("pull: " + repo.name);
270                             var str = repo.pull();
271                                     // do not care if it's already in sycn..
272                             if (Regex.match_simple ("Already up-to-date", str) ) {
273                                 continue;
274                             }
275                             var notification = new Notify.Notification( 
276                                      "Updated " + repo.name,
277                                      str,
278                                        "dialog-information"
279                                    
280                             );
281                         
282                             notification.set_timeout(20);
283                             notification.show();
284                                      
285                         } catch(Error e) {
286                             print("notification or push errror- probably to many in queue..");
287                             statusicon.set_from_stock( Gtk.Stock.MEDIA_RECORD );
288                             print(e.message);
289                             
290                         }        
291
292                     } 
293                     */
294                            
295                            
296                 });
297             }
298             void pullAll()
299             {
300                         var tr = GitRepo.list();
301                 
302                 GitMonitor.gitmonitor.stop();
303                     
304                 
305                this.total = tr.length;
306                 this.has_error = 0;
307                 this.pull_all_error_message = "";
308                 for (var i= 0; i< tr.length;i++) {
309                     statusicon.set_from_stock( 
310                                 i%2 == 0 ?  Gtk.Stock.FULLSCREEN : Gtk.Stock.LEAVE_FULLSCREEN );
311                             
312                     var repo = tr.index(i);
313                     //repo.ref();
314                     //this.ref();
315                     
316                     statusicon.set_tooltip_text("pull: " + repo.name);
317                                         
318                     repo.pull_async(this.pullAllCallback); 
319                                 // do not care if it's already in sycn..
320                         
321                      
322
323                 } 
324
325                   
326         
327         
328                 }
329                 uint total = 0; 
330                         uint has_error = 0;
331                         string pull_all_error_message = "";
332                 
333                 void pullAllCallback(GitRepo repo, int err, string res)
334                 {
335                         this.total--;
336                         
337                         if (err > 0) {
338                                 this.has_error = 1;
339                                 this.pull_all_error_message += this.pull_all_error_message.length > 0 ? "\n" : "";
340                                 this.pull_all_error_message += "Error Pulling " + repo.name +"\n" + res;
341                         }
342                         
343                         if (!Regex.match_simple ("Already up-to-date", res) ) {
344                         var notification = new Notify.Notification( 
345                          "Pull completed ",
346                           "Updated: " +repo.name + "\n" + res +"\n",
347                              "dialog-information"
348                     );
349                     notification.set_timeout(20);
350                                 notification.show();
351                         
352  
353  
354                         }
355                         if (this.total < 1) {
356                                 if (this.has_error > 0) {
357                                         GitMonitor.gitmonitor.pauseError(this.pull_all_error_message);
358                                         return;
359                                 }
360                         
361                         statusicon.set_tooltip_text("Gitlive");
362                   
363                                 GitMonitor.gitmonitor.start();
364                                 //this.unref();
365                                 //repo.unref();
366                         }
367                         
368                 }
369         
370             
371         }
372         
373         
374         class ImageMenuItemD : ImageMenuItem {
375             
376             public ImageMenuItemD()
377             {
378                 
379                 var  image = new Gtk.Image();
380                 image.set_from_stock(Gtk.Stock.SAVE,Gtk.IconSize.MENU );
381                 this.set_image (image);
382                 this.label= "Update Timesheet";
383                 this.always_show_image = true;
384                 this.accel_group = null;
385                 
386                 this.activate.connect( () => {
387                  //var ret = imports.FixBug.FixBug.show();
388                 });
389             }
390             
391             
392         }
393         
394         class ImageMenuItemE : ImageMenuItem {
395             
396             public ImageMenuItemE()
397             {
398                 
399                 var  image = new Gtk.Image();
400                 image.set_from_stock(Gtk.Stock.FULLSCREEN,Gtk.IconSize.MENU );
401                 this.set_image (image);
402                 this.label= "Manage Clones";
403                 this.always_show_image = true;
404                 this.accel_group = null;
405                 
406                 this.activate.connect( () => {
407                       Clones.singleton().show();
408                 });
409             }
410             
411             
412         }
413         
414         class ImageMenuItemF : ImageMenuItem {
415             
416             public ImageMenuItemF()
417             {
418                 
419                 var  image = new Gtk.Image();
420                 image.set_from_stock(Gtk.Stock.ABOUT,Gtk.IconSize.MENU );
421                 this.set_image (image);
422                 this.label= "About Gitlive";
423                 this.always_show_image = true;
424                 this.accel_group = null;
425                 
426                 this.activate.connect( () => {
427                  //var ret = imports.Clones.Clones.show();
428                  
429                     var msg = new Gtk.AboutDialog();
430                     msg.program_name = "Git Live";
431                     msg.version= "0.3";
432                     msg.website= "http://www.roojs.org/index.php/projects/gitlive.html";
433                     msg.website_label= "Roo J Solutions Ltd.";
434                     msg.license = "LGPL";
435                     msg.authors = { "Alan Knowles <alan@roojs.com>" };
436                     msg.run();
437                     msg.destroy();
438                 });
439             }
440             
441             
442         }
443         
444          class ImageMenuItemG : ImageMenuItem {
445             
446             public ImageMenuItemG()
447             {
448                 
449                 var  image = new Gtk.Image();
450                 image.set_from_stock(Gtk.Stock.QUIT,Gtk.IconSize.MENU );
451                 this.set_image (image);
452                 this.label= "Quit";
453                 this.always_show_image = true;
454                 this.accel_group = null;
455                 
456                 this.activate.connect( () => {
457                     // confirm?
458                     Gtk.main_quit();
459                  //var ret = imports.Clones.Clones.show();
460                  });
461             }
462             
463             
464         }
465         
466     }
467 }
468       
469                 
470