mail-notification

Fork of Jean-Yves Lefort's mail-notification, a tray icon to notify of new mail
git clone https://code.djc.id.au/git/mail-notification/

src/mn-mail-icon.gob (8753B) - raw

      1 /*
      2  * Size adjustment code (size_allocate_h(), find_icon_size()) taken
      3  * from GtkStatusIcon,
      4  * Copyright (C) 2003 Sun Microsystems, Inc.
      5  * Copyright (C) 2005 Hans Breuer <hans@breuer.org>
      6  * Copyright (C) 2005 Novell, Inc.
      7  *
      8  * Mail Notification
      9  * Copyright (C) 2003-2008 Jean-Yves Lefort <jylefort@brutele.be>
     10  *
     11  * This program is free software; you can redistribute it and/or modify
     12  * it under the terms of the GNU General Public License as published by
     13  * the Free Software Foundation; either version 3 of the License, or
     14  * (at your option) any later version.
     15  *
     16  * This program is distributed in the hope that it will be useful,
     17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     19  * GNU General Public License for more details.
     20  *
     21  * You should have received a copy of the GNU General Public License along
     22  * with this program; if not, write to the Free Software Foundation, Inc.,
     23  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
     24  */
     25 
     26 %headertop{
     27 #include <gtk/gtk.h>
     28 #include "eggtrayicon.h"
     29 %}
     30 
     31 %privateheader{
     32 #include "mn-tooltips.h"
     33 %}
     34 
     35 %{
     36 #include <glib/gi18n.h>
     37 #include <gdk/gdkkeysyms.h>
     38 #include "mn-stock.h"
     39 #include "mn-util.h"
     40 #include "mn-mail-icon-widget.h"
     41 %}
     42 
     43 class MN:Mail:Icon from Egg:Tray:Icon
     44 {
     45   private MNTooltips *tooltips = {mn_tooltips_new()} unrefwith g_object_unref;
     46   private GtkWidget *widget = {mn_mail_icon_widget_new()};
     47 
     48   private char *stock_id destroywith g_free;
     49   private int size;
     50 
     51   private GtkWidget *menu = {gtk_menu_new()} destroywith gtk_widget_destroy;
     52   public GtkWidget *mail_reader_item;
     53   public GtkWidget *open_latest_message_item;
     54   public GtkWidget *update_item;
     55   public GtkWidget *consider_new_mail_as_read_item;
     56 
     57   signal (ACTION) private NONE (NONE)
     58     void activate (self);
     59   signal (ACTION) private NONE (NONE)
     60     void activate_mail_reader (self);
     61   signal (ACTION) private NONE (NONE)
     62     void activate_open_latest_message (self);
     63   signal (ACTION) private NONE (NONE)
     64     void activate_consider_new_mail_as_read (self);
     65   signal (ACTION) private NONE (NONE)
     66     void activate_update (self);
     67   signal (ACTION) private NONE (NONE)
     68     void activate_properties (self);
     69   signal (ACTION) private NONE (NONE)
     70     void activate_help (self);
     71   signal (ACTION) private NONE (NONE)
     72     void activate_about (self);
     73   signal (ACTION) private NONE (NONE)
     74     void activate_remove (self);
     75 
     76   init (self)
     77   {
     78     GtkMenuShell *shell;
     79     GtkWidget *properties_item;
     80     GtkWidget *help_item;
     81     GtkWidget *about_item;
     82     GtkWidget *remove_item;
     83 
     84     shell = GTK_MENU_SHELL(selfp->menu);
     85     /* translators: header capitalization */
     86     self->mail_reader_item = mn_menu_shell_append(shell, MN_STOCK_MAIL_READER, _("_Mail Reader"));
     87     /* translators: header capitalization */
     88     self->open_latest_message_item = mn_menu_shell_append(shell, MN_STOCK_OPEN_MESSAGE, _("_Open Latest Message"));
     89 
     90     mn_menu_shell_append(shell, NULL, NULL);
     91 
     92     /* translators: header capitalization */
     93     self->consider_new_mail_as_read_item = mn_menu_shell_append(shell, MN_STOCK_CONSIDER_NEW_MAIL_AS_READ, _("_Consider New Mail as Read"));
     94     /* translators: header capitalization */
     95     self->update_item = mn_menu_shell_append(shell, GTK_STOCK_REFRESH, _("_Update"));
     96 
     97     mn_menu_shell_append(shell, NULL, NULL);
     98 
     99     properties_item = mn_menu_shell_append(shell, GTK_STOCK_PROPERTIES, NULL);
    100     help_item = mn_menu_shell_append(shell, GTK_STOCK_HELP, NULL);
    101     about_item = mn_menu_shell_append(shell, GTK_STOCK_ABOUT, NULL);
    102 
    103     mn_menu_shell_append(shell, NULL, NULL);
    104 
    105     /* translators: header capitalization */
    106     remove_item = mn_menu_shell_append(shell, GTK_STOCK_REMOVE, _("R_emove From Notification Area"));
    107 
    108     g_signal_connect_swapped(self->mail_reader_item, "activate", G_CALLBACK(self_activate_mail_reader), self);
    109     g_signal_connect_swapped(self->open_latest_message_item, "activate", G_CALLBACK(self_activate_open_latest_message), self);
    110     g_signal_connect_swapped(self->consider_new_mail_as_read_item, "activate", G_CALLBACK(self_activate_consider_new_mail_as_read), self);
    111     g_signal_connect_swapped(self->update_item, "activate", G_CALLBACK(self_activate_update), self);
    112     g_signal_connect_swapped(properties_item, "activate", G_CALLBACK(self_activate_properties), self);
    113     g_signal_connect_swapped(help_item, "activate", G_CALLBACK(self_activate_help), self);
    114     g_signal_connect_swapped(about_item, "activate", G_CALLBACK(self_activate_about), self);
    115     g_signal_connect_swapped(remove_item, "activate", G_CALLBACK(self_activate_remove), self);
    116 
    117     gtk_widget_add_events(GTK_WIDGET(self), GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
    118 
    119     gtk_container_add(GTK_CONTAINER(self), selfp->widget);
    120 
    121     g_object_connect(self,
    122 		     "signal::button-press-event", self_button_press_event_h, self,
    123 		     "signal::button-release-event", self_button_release_event_h, self,
    124 		     NULL);
    125 
    126     g_signal_connect(selfp->widget, "size-allocate", G_CALLBACK(self_size_allocate_h), self);
    127 
    128     gtk_widget_show(selfp->widget);
    129   }
    130 
    131   private void
    132     size_allocate_h (GtkWidget *widget,
    133 		     GtkAllocation *allocation,
    134 		     gpointer user_data)
    135   {
    136     Self *self = user_data;
    137     GtkOrientation orientation;
    138     int size;
    139 
    140     orientation = egg_tray_icon_get_orientation(EGG_TRAY_ICON(self));
    141 
    142     if (orientation == GTK_ORIENTATION_HORIZONTAL)
    143       size = allocation->height;
    144     else
    145       size = allocation->width;
    146 
    147     if (selfp->size != size)
    148       {
    149 	selfp->size = size;
    150 	self_update_image(self);
    151       }
    152   }
    153 
    154   private GtkIconSize
    155     find_icon_size (Gtk:Widget *widget (check null type), int pixel_size)
    156   {
    157     GdkScreen *screen;
    158     GtkSettings *settings;
    159     GtkIconSize s, size;
    160     int w, h, d, dist;
    161 
    162     screen = gtk_widget_get_screen(widget);
    163 
    164     if (! screen)
    165       return GTK_ICON_SIZE_MENU;
    166 
    167     settings = gtk_settings_get_for_screen(screen);
    168 
    169     dist = G_MAXINT;
    170     size = GTK_ICON_SIZE_MENU;
    171 
    172     for (s = GTK_ICON_SIZE_MENU; s < GTK_ICON_SIZE_DIALOG; s++)
    173       {
    174 	if (gtk_icon_size_lookup_for_settings(settings, s, &w, &h)
    175 	    && w <= pixel_size
    176 	    && h <= pixel_size)
    177 	  {
    178 	    d = MAX(pixel_size - w, pixel_size - h);
    179 	    if (d < dist)
    180 	      {
    181 		dist = d;
    182 		size = s;
    183 	      }
    184 	  }
    185       }
    186 
    187     return size;
    188   }
    189 
    190   private void
    191     update_image (self)
    192   {
    193     GtkIconSize size;
    194 
    195     size = self_find_icon_size(selfp->widget, selfp->size);
    196     mn_mail_icon_widget_set_from_stock(MN_MAIL_ICON_WIDGET(selfp->widget), selfp->stock_id, size);
    197   }
    198 
    199   private gboolean
    200     button_press_event_h (GtkWidget *widget,
    201 			  GdkEventButton *event,
    202 			  gpointer user_data)
    203   {
    204     Self *self = user_data;
    205 
    206     if (event->button == 1)
    207       self_activate(self);
    208     else if (event->button == 3)
    209       {
    210 	gtk_menu_popup(GTK_MENU(selfp->menu), NULL, NULL, self_popup_menu_position_cb, self, event->button, event->time);
    211 	return TRUE;		/* do not propagate event */
    212       }
    213 
    214     return FALSE;		/* propagate event */
    215   }
    216 
    217   private gboolean
    218     button_release_event_h (GtkWidget *widget,
    219 			    GdkEventButton *event,
    220 			    gpointer user_data)
    221   {
    222     Self *self = user_data;
    223 
    224     if (event->button == 3)
    225       {
    226 	gtk_menu_popdown(GTK_MENU(selfp->menu));
    227 	return TRUE;		/* do not propagate event */
    228       }
    229 
    230     return FALSE;		/* propagate event */
    231   }
    232 
    233   private void
    234     popup_menu_position_cb (GtkMenu *menu,
    235 			    int *x,
    236 			    int *y,
    237 			    gboolean *push_in,
    238 			    gpointer user_data)
    239   {
    240     GtkWidget *widget = user_data;
    241 
    242     gdk_window_get_origin(widget->window, x, y);
    243 
    244     *x += widget->allocation.x;
    245     *y += widget->allocation.y;
    246 
    247     if (*y > gdk_screen_get_height(gtk_widget_get_screen(widget)) / 2)
    248       {
    249 	GtkRequisition req;
    250 
    251 	gtk_widget_size_request(GTK_WIDGET(menu), &req);
    252 	*y -= req.height;
    253       }
    254     else
    255       *y += widget->allocation.height;
    256 
    257     *push_in = TRUE;
    258   }
    259 
    260   public void
    261     set_from_stock (self, const char *stock_id)
    262   {
    263     g_free(selfp->stock_id);
    264     selfp->stock_id = g_strdup(stock_id);
    265 
    266     self_update_image(self);
    267   }
    268 
    269   public void
    270     set_blinking (self, gboolean blinking)
    271   {
    272     mn_mail_icon_widget_set_blinking(MN_MAIL_ICON_WIDGET(selfp->widget), blinking);
    273   }
    274 
    275   public void
    276     set_count (self, int count)
    277   {
    278     mn_mail_icon_widget_set_count(MN_MAIL_ICON_WIDGET(selfp->widget), count);
    279   }
    280 
    281   public void
    282     set_tip (self, const char *tip)
    283   {
    284     mn_tooltips_set_tip(selfp->tooltips, GTK_WIDGET(self), tip);
    285   }
    286 
    287   public void
    288     set_tip_widget (self, Gtk:Widget *tip_widget)
    289   {
    290     mn_tooltips_set_tip_widget(selfp->tooltips, GTK_WIDGET(self), tip_widget);
    291   }
    292 
    293   public GtkWidget *
    294     new (void)
    295   {
    296     return GTK_WIDGET(GET_NEW_VARG("title", _("Mail Notification"), NULL));
    297   }
    298 }