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-message-view.gob (4060B) - raw

      1 /*
      2  * Mail Notification
      3  * Copyright (C) 2003-2008 Jean-Yves Lefort <jylefort@brutele.be>
      4  *
      5  * This program is free software; you can redistribute it and/or modify
      6  * it under the terms of the GNU General Public License as published by
      7  * the Free Software Foundation; either version 3 of the License, or
      8  * (at your option) any later version.
      9  *
     10  * This program is distributed in the hope that it will be useful,
     11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13  * GNU General Public License for more details.
     14  *
     15  * You should have received a copy of the GNU General Public License along
     16  * with this program; if not, write to the Free Software Foundation, Inc.,
     17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
     18  */
     19 
     20 %headertop{
     21 #include "mn-text-table.h"
     22 #include "mn-message.h"
     23 %}
     24 
     25 %privateheader{
     26 #include <time.h>
     27 %}
     28 
     29 %{
     30 #include "mn-util.h"
     31 #include <glib/gi18n.h>
     32 
     33 typedef struct
     34 {
     35   MNMessageView		*self;
     36   MNTextTableCell	*cell;
     37   GList			*link;
     38   time_t		past_time;
     39 } PastTimeCell;
     40 
     41 /* use a GQueue for O(1) append and removal */
     42 static GQueue past_time_cells = G_QUEUE_INIT;
     43 static unsigned int past_time_cells_timeout_id = 0;
     44 %}
     45 
     46 class MN:Message:View from MN:Text:Table (abstract)
     47 {
     48   private GSList *past_time_cells;
     49 
     50   finalize (self)
     51   {
     52     self_clear_past_time_cells(self);
     53   }
     54 
     55   override (MN:Text:Table) void
     56     clear (MNTextTable *table)
     57   {
     58     self_clear_past_time_cells(SELF(table));
     59 
     60     PARENT_HANDLER(table);
     61   }
     62 
     63   public void
     64     set_messages (self, GSList *messages)
     65   {
     66     time_t now;
     67     GSList *l;
     68 
     69     mn_text_table_clear(MN_TEXT_TABLE(self));
     70 
     71     self_append_header(self);
     72 
     73     now = mn_time();
     74 
     75     MN_LIST_FOREACH(l, messages)
     76       {
     77 	MNMessage *message = l->data;
     78 
     79 	self_append_message(self, message, now);
     80 	if (l->next)
     81 	  self_append_message_separator(self);
     82       }
     83   }
     84 
     85   virtual private void
     86     append_header (self);
     87 
     88   virtual private void
     89     append_message (self, MN:Message *message (check null type), time_t now);
     90 
     91   virtual private void
     92     append_message_separator (self);
     93 
     94   protected void
     95     append_past_time_cell (self, time_t past_time, time_t now)
     96   {
     97     PastTimeCell *pcell;
     98 
     99     pcell = g_new(PastTimeCell, 1);
    100     pcell->self = self;
    101     pcell->cell = mn_text_table_append_text_cell(MN_TEXT_TABLE(self), NULL);
    102     pcell->link = g_list_alloc();
    103     pcell->link->data = pcell;
    104     pcell->past_time = past_time;
    105 
    106     self_update_past_time_cell(pcell, now);
    107 
    108     selfp->past_time_cells = g_slist_prepend(selfp->past_time_cells, pcell);
    109     g_queue_push_tail_link(&past_time_cells, pcell->link);
    110 
    111     if (! past_time_cells_timeout_id)
    112       self_install_past_time_cells_timeout();
    113   }
    114 
    115   private void
    116     clear_past_time_cells (self)
    117   {
    118     GSList *l;
    119 
    120     if (! selfp->past_time_cells)
    121       return;
    122 
    123     MN_LIST_FOREACH(l, selfp->past_time_cells)
    124       {
    125 	PastTimeCell *pcell = l->data;
    126 
    127 	g_queue_delete_link(&past_time_cells, pcell->link);
    128 	g_free(pcell);
    129       }
    130 
    131     mn_g_slist_clear(&selfp->past_time_cells);
    132 
    133     if (g_queue_is_empty(&past_time_cells))
    134       mn_source_clear(&past_time_cells_timeout_id);
    135   }
    136 
    137   private void
    138     install_past_time_cells_timeout (void)
    139   {
    140     GTimeVal now;
    141     int timeout;
    142 
    143     g_get_current_time(&now);
    144     timeout = (G_USEC_PER_SEC - now.tv_usec) / 1000 + 1;
    145 
    146     past_time_cells_timeout_id = gdk_threads_add_timeout(timeout, self_update_past_time_cells_cb, NULL);
    147   }
    148 
    149   private gboolean
    150     update_past_time_cells_cb (gpointer data)
    151   {
    152     time_t now;
    153     GList *l;
    154 
    155     now = mn_time();
    156     MN_QUEUE_FOREACH(l, &past_time_cells)
    157       self_update_past_time_cell(l->data, now);
    158 
    159     self_install_past_time_cells_timeout();
    160     return FALSE;		/* remove source */
    161   }
    162 
    163   private void
    164     update_past_time_cell (PastTimeCell *pcell (check null), time_t now)
    165   {
    166     char *formatted;
    167 
    168     formatted = mn_format_past_time(pcell->past_time, now);
    169     mn_text_table_cell_set_text(MN_TEXT_TABLE(pcell->self), pcell->cell, formatted);
    170     g_free(formatted);
    171   }
    172 }