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 }