Changeset 3387 for trunk/jons-gtk2-gui

Show
Ignore:
Timestamp:
03/20/03 01:48:14 (6 years ago)
Author:
bostjanlah
Message:

Rework this so that loading is done via timeout
callbacks
Simplify the display

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • trunk/jons-gtk2-gui/src/history_window.cpp

    r3324 r3387  
    2121#include "licq_gtk.h" 
    2222#include "event_description.h" 
     23#include "utilities.h" 
    2324 
    2425#include <gtk/gtk.h> 
    2526#include <time.h> 
    2627 
     28#include <string> 
     29using namespace std; 
     30 
    2731struct history 
    2832{ 
    2933    GtkWidget *text; 
    30     GtkWidget *check; 
    31     ICQUser *user; 
     34    GtkWidget *reverse; 
     35    GtkWidget *progress; 
     36    GtkTextTag *red, *blue, *bold; 
     37  HistoryList hlist; 
     38  HistoryListIter hlist_iter; 
     39  unsigned long uin; 
     40  size_t loaded; 
     41    guint timeout_id; 
    3242}; 
    3343 
    34 const gchar *line = "\n----------------------------\n"; 
    35  
    36 void reverse_history(GtkWidget *widget, struct history *hist); 
    37  
    38 void list_history(GtkWidget *widget, ICQUser *user) 
    39 { 
    40     GtkWidget *window; 
    41     GtkWidget *v_box; 
    42     GtkWidget *h_box; 
    43     GtkWidget *scroll; 
    44     GtkWidget *button; 
    45     struct history *hist; 
    46     const gchar *title = g_strdup_printf("History with %s", user->GetAlias()); 
     44static const int load_slice = 100; 
     45static const int time_slice = 200; 
     46 
     47GtkTextBuffer * 
     48text_buffer_create(struct history *hist) 
     49{ 
     50    GtkTextBuffer *tb = gtk_text_buffer_new(NULL); 
     51     
     52    hist->red = gtk_text_buffer_create_tag(tb, NULL,  
     53            "foreground-gdk", red, NULL); 
     54    hist->blue = gtk_text_buffer_create_tag(tb, NULL,  
     55            "foreground-gdk", blue, NULL); 
     56    hist->bold = gtk_text_buffer_create_tag(tb, NULL,  
     57            "weight", PANGO_WEIGHT_BOLD, NULL); 
     58             
     59    return tb; 
     60} 
     61  
     62gboolean 
     63load_history(struct history *hist) 
     64{ 
     65    bool reverse = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(hist->reverse)); 
     66     
     67  if (reverse) { 
     68    if (hist->hlist_iter == hist->hlist.begin()) 
     69      return FALSE; 
     70  } 
     71  else { 
     72    if (hist->hlist_iter == hist->hlist.end()) 
     73      return FALSE; 
     74  } 
     75       
     76    time_t _time; 
     77    tm *tmStupid; 
     78    char szDesc[36], szDate[30]; 
    4779    gchar szHdr[256]; 
    48     time_t _time; 
    49     HistoryList hist_list; 
    50     HistoryListIter history_iter; 
    51  
    52     hist = g_new0(struct history, 1); 
    53     hist->user = user; 
     80 
     81    GtkTextBuffer *tb = gtk_text_view_get_buffer(GTK_TEXT_VIEW(hist->text)); 
     82    GtkTextIter iter; 
     83 
     84  ICQUser *user = gUserManager.FetchUser(hist->uin, LOCK_R); 
     85    const char *encoding = user->UserEncoding(); 
     86    string alias(s_convert_to_utf8(user->GetAlias(), encoding)); 
     87    gboolean ret = TRUE; 
     88  for (int i = 0; i < load_slice; ++i) { 
     89    if (reverse) { 
     90      if (hist->hlist_iter == hist->hlist.begin()) { 
     91        ret = FALSE; 
     92        break; 
     93      } 
     94      --(hist->hlist_iter); 
     95    } 
     96 
     97    HistoryListIter h_iter = hist->hlist_iter; 
     98    _time = (*h_iter)->Time(); 
     99      tmStupid = localtime(&_time); 
     100      strftime(szDate, 29, "%c", tmStupid); 
     101      strcpy(szDesc, event_description(*(hist->hlist_iter))); 
     102 
     103    GtkTextTag *tag; 
     104        if ((*hist->hlist_iter)->Direction() == D_RECEIVER) 
     105            tag = hist->red; 
     106        else 
     107            tag = hist->blue; 
     108 
     109      snprintf(szHdr, 255, 
     110              "%s %s %s\n%s [%c%c%c%c]\n\n", 
     111              szDesc, 
     112        (*h_iter)->Direction() == D_RECEIVER ? "from" : "to", 
     113              alias.c_str(), 
     114              szDate, 
     115              (*h_iter)->IsDirect() ? 'D' : '-', 
     116              (*h_iter)->IsMultiRec() ? 'M' : '-', 
     117              (*h_iter)->IsUrgent() ? 'U' : '-', 
     118              (*h_iter)->IsEncrypted() ? 'E' : '-'); 
     119 
     120      szHdr[255] = '\0'; 
     121    gtk_text_buffer_get_end_iter(tb, &iter); 
     122      gtk_text_buffer_insert_with_tags(tb, &iter, 
     123        szHdr, -1, tag, hist->bold, NULL); 
     124      gtk_text_buffer_get_end_iter(tb, &iter); 
     125      gtk_text_buffer_insert_with_tags(tb, &iter,  
     126          s_convert_to_utf8((*h_iter)->Text(), encoding).c_str(), -1, tag, NULL); 
     127      gtk_text_buffer_get_end_iter(tb, &iter); 
     128    gtk_text_buffer_insert(tb, &iter, "\n\n\n", 3); 
     129 
     130    hist->loaded++; 
     131     
     132        if (!reverse) { 
     133      ++(hist->hlist_iter); 
     134      if (hist->hlist_iter == hist->hlist.end()) { 
     135        ret = FALSE; 
     136        break; 
     137      } 
     138    } 
     139  } 
     140   
     141    gUserManager.DropUser(user); 
     142 
     143  char txt[50]; 
     144  snprintf(txt, 30, "%u / %u", hist->loaded, hist->hlist.size()); 
     145  gtk_progress_bar_set_text(GTK_PROGRESS_BAR(hist->progress), txt); 
     146  gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(hist->progress), 
     147      (double)hist->loaded / hist->hlist.size()); 
     148  return ret; 
     149} 
     150 
     151void 
     152reverse_cb(GtkWidget *, struct history *hist) 
     153{ 
     154    if (hist->timeout_id != 0) 
     155        g_source_remove(hist->timeout_id); 
     156    GtkTextBuffer *tb = text_buffer_create(hist); 
     157    gtk_text_view_set_buffer(GTK_TEXT_VIEW(hist->text), tb); 
     158    g_object_unref(G_OBJECT(tb)); 
     159    hist->loaded = 0; 
     160  if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(hist->reverse))) 
     161        hist->hlist_iter = hist->hlist.end(); 
     162    else 
     163        hist->hlist_iter = hist->hlist.begin(); 
     164    if (load_history(hist)) 
     165    hist->timeout_id =  
     166        g_timeout_add(time_slice, GSourceFunc(load_history), hist); 
     167    else 
     168    hist->timeout_id = 0; 
     169} 
     170 
     171void 
     172hist_destroy_cb(GtkWidget *, struct history *hist) 
     173{ 
     174    if (hist->timeout_id != 0) 
     175        g_source_remove(hist->timeout_id); 
     176    delete hist; 
     177} 
     178 
     179void  
     180list_history(GtkWidget *widget, ICQUser *user) 
     181{ 
     182    struct history *hist = new history; 
     183  if (!user->GetHistory(hist->hlist)) { 
     184      GtkWidget *dialog = gtk_message_dialog_new(GTK_WINDOW(main_window), 
     185                                    GTK_DIALOG_DESTROY_WITH_PARENT, 
     186                                    GTK_MESSAGE_ERROR, 
     187                                    GTK_BUTTONS_CLOSE, 
     188                                    "History for %s could not be loaded.", 
     189                                    user->GetAlias()); 
     190    gtk_dialog_run (GTK_DIALOG (dialog)); 
     191    gtk_widget_destroy (dialog); 
     192    delete hist; 
     193        return; 
     194  } 
     195    hist->uin = user->Uin(); 
    54196 
    55197    // Make the window 
    56     window = gtk_window_new(GTK_WINDOW_TOPLEVEL); 
     198    gchar *title = g_strdup_printf("History with %s", user->GetAlias()); 
     199    GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL); 
    57200    gtk_window_set_title(GTK_WINDOW(window), title); 
    58201    gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); 
    59  
     202  g_free(title); 
     203    g_signal_connect(G_OBJECT(window), "destroy", 
     204      G_CALLBACK(hist_destroy_cb), hist); 
     205     
    60206    // Make the boxes 
    61     v_box = gtk_vbox_new(FALSE, 5); 
    62     h_box = gtk_hbox_new(FALSE, 5); 
     207    GtkWidget *v_box = gtk_vbox_new(FALSE, 5); 
     208    GtkWidget *h_box = gtk_hbox_new(FALSE, 5); 
    63209 
    64210    // Make the scrolled window 
    65     scroll = gtk_scrolled_window_new(0, 0); 
     211    GtkWidget *scroll = gtk_scrolled_window_new(0, 0); 
    66212    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), 
    67                        GTK_POLICY_NEVER, 
    68                        GTK_POLICY_AUTOMATIC); 
     213      GTK_POLICY_NEVER, 
     214            GTK_POLICY_AUTOMATIC); 
    69215    gtk_widget_set_size_request(scroll, 300, 225); 
    70216 
    71217    // Make the text box 
    72     hist->text = gtk_text_view_new(); 
     218    GtkTextBuffer *tb = text_buffer_create(hist); 
     219  if (hist->hlist.size() == 0) 
     220        gtk_text_buffer_set_text(tb, "No history for this contact.", -1); 
     221    hist->text = gtk_text_view_new_with_buffer(tb); 
     222    g_object_unref(G_OBJECT(tb)); 
     223 
    73224    gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(hist->text), GTK_WRAP_WORD); 
     225    gtk_text_view_set_editable(GTK_TEXT_VIEW(hist->text), FALSE); 
    74226    gtk_container_add(GTK_CONTAINER(scroll), hist->text); 
    75227 
    76228    // Pack the scrolled window 
    77     gtk_box_pack_start(GTK_BOX(v_box), scroll, TRUE, TRUE, 0); 
    78  
     229  GtkWidget *frame = gtk_frame_new(NULL); 
     230  gtk_container_add(GTK_CONTAINER(frame), scroll); 
     231    gtk_box_pack_start(GTK_BOX(v_box), frame, TRUE, TRUE, 5); 
     232   
     233  // Add the loading progress bar 
     234  hist->progress = gtk_progress_bar_new(); 
     235    gtk_box_pack_start(GTK_BOX(v_box), hist->progress, FALSE, FALSE, 5); 
     236   
    79237    // The close button 
    80     button = gtk_button_new_from_stock(GTK_STOCK_CLOSE); 
     238    GtkWidget *button = gtk_button_new_from_stock(GTK_STOCK_CLOSE); 
    81239    g_signal_connect(G_OBJECT(button), "clicked", 
    82240            G_CALLBACK(window_close), window); 
    83241 
    84242    // The reverse check button 
    85     hist->check = gtk_check_button_new_with_label("Reverse"); 
    86     g_signal_connect(G_OBJECT(hist->check), "toggled", 
    87                G_CALLBACK(reverse_history), hist); 
     243    hist->reverse = gtk_check_button_new_with_mnemonic("_Reverse"); 
     244    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(hist->reverse), TRUE); 
     245    g_signal_connect(G_OBJECT(hist->reverse), "toggled", 
     246      G_CALLBACK(reverse_cb), hist); 
    88247 
    89248    // Pack them 
    90     gtk_box_pack_start(GTK_BOX(h_box), hist->check, TRUE, TRUE, 5); 
     249    gtk_box_pack_start(GTK_BOX(h_box), hist->reverse, TRUE, TRUE, 5); 
    91250    gtk_box_pack_start(GTK_BOX(h_box), button, TRUE, TRUE, 5); 
    92251    gtk_box_pack_start(GTK_BOX(v_box), h_box, FALSE, FALSE, 0); 
    93252     
    94     // Add in the history 
    95     if(!user->GetHistory(hist_list)) 
    96         return; 
    97  
    98     // The three colors, blue, red, and white 
    99     GdkColor clrBlue, clrRed, clrWhite; 
    100  
    101     clrBlue.red   = 0; 
    102     clrBlue.green = 0; 
    103     clrBlue.blue  = 0xFFFF; 
    104     clrBlue.pixel = gulong(255 * 256); 
    105  
    106     clrRed.red   = 0xFFFF; 
    107     clrRed.green = 0; 
    108     clrRed.blue  = 0; 
    109     clrRed.pixel = 255; 
    110  
    111     clrWhite.red   = 0xFFFF; 
    112     clrWhite.green = 0xFFFF; 
    113     clrWhite.blue  = 0xFFFF; 
    114     clrWhite.pixel = 255; 
    115  
    116     history_iter = hist_list.begin(); 
    117     GtkTextBuffer *tb = gtk_text_buffer_new(NULL); 
    118  
    119     // Easy way, small memory 
    120     GdkColor *clrColor; 
    121     char szDesc[36], szDate[30]; 
    122     tm *tmStupid; 
    123      
    124     while(history_iter != hist_list.end()) 
    125     { 
    126         _time = (*history_iter)->Time(); 
    127         tmStupid = localtime(&_time); 
    128         strftime(szDate, 29, "%c", tmStupid); 
    129         strcpy(szDesc, event_description(*history_iter)); 
    130          
    131         if ((*history_iter)->Direction() == D_RECEIVER) 
    132         { 
    133             clrColor = &clrRed; 
    134             snprintf(szHdr, 255, 
    135                      "%s from %s\n%s [%c%c%c%c]\n\n", 
    136                  szDesc, 
    137                  user->GetAlias(), 
    138                  szDate, 
    139                  (*history_iter)->IsDirect() ? 'D' : '-', 
    140                  (*history_iter)->IsMultiRec() ? 'M' : '-', 
    141                  (*history_iter)->IsUrgent() ? 'U' : '-', 
    142                  (*history_iter)->IsEncrypted() ? 'E' : '-'); 
    143         } 
    144         else 
    145         { 
    146             clrColor = &clrBlue; 
    147             snprintf(szHdr, 255, 
    148                      "%s to %s\n%s [%c%c%c%c]\n\n", 
    149                  szDesc, 
    150                  user->GetAlias(), 
    151                  szDate, 
    152                  (*history_iter)->IsDirect() ? 'D' : '-', 
    153                  (*history_iter)->IsMultiRec() ? 'M' : '-', 
    154                  (*history_iter)->IsUrgent() ? 'U' : '-', 
    155                  (*history_iter)->IsEncrypted() ? 'E' : '-'); 
    156         } 
    157  
    158         szHdr[255] = '\0'; 
    159         GtkTextTag *tag = gtk_text_buffer_create_tag(tb, NULL,  
    160                 "foreground-gdk", clrColor, 
    161                 "background-gdk", &clrWhite, 
    162                 NULL); 
    163         GtkTextIter iter; 
    164         gtk_text_buffer_get_end_iter(tb, &iter); 
    165         gtk_text_buffer_insert_with_tags(tb, &iter,  
    166             szHdr, -1, tag, NULL); 
    167         gtk_text_buffer_get_end_iter(tb, &iter); 
    168         gtk_text_buffer_insert_with_tags(tb, &iter,  
    169             (*history_iter)->Text(), -1, tag, NULL); 
    170         gtk_text_buffer_get_end_iter(tb, &iter); 
    171         gtk_text_buffer_insert(tb, &iter, "\n\n", 2); 
    172         history_iter++; 
    173     } 
    174  
    175     gtk_text_view_set_buffer(GTK_TEXT_VIEW(hist->text), tb); 
    176     g_object_unref(G_OBJECT(tb)); 
    177  
     253    HistoryList hist_list; 
     254    gtk_container_set_border_width(GTK_CONTAINER(window), 10); 
    178255    gtk_container_add(GTK_CONTAINER(window), v_box); 
    179256    gtk_widget_show_all(window); 
    180 } 
    181  
    182 void reverse_history(GtkWidget *widget, struct history *hist) 
    183 { 
    184     HistoryList hist_list; 
    185     HistoryListIter history_iter; 
    186     time_t _time; 
    187     char sz_date[35]; 
    188  
    189     GtkTextBuffer *tb = gtk_text_buffer_new(NULL); 
    190  
    191     if(!hist->user->GetHistory(hist_list)) 
    192         return; 
    193      
    194     if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(hist->check))) 
    195       history_iter = --(hist_list.end()); 
    196     else 
    197         history_iter = hist_list.begin(); 
    198  
    199   while(1) 
    200   { 
    201         if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(hist->check))) 
    202         { 
    203             if(history_iter == --(hist_list.begin())) 
    204                 break; 
    205         } 
    206         else 
    207         { 
    208             if(history_iter == hist_list.end()) 
    209                 break; 
     257 
     258  hist->hlist_iter = hist->hlist.end(); 
     259  hist->loaded = 0; 
     260 
     261  if (hist->hlist.size() == 0) 
     262        gtk_widget_set_sensitive(hist->reverse, FALSE); 
     263    else { 
     264        if (load_history(hist)) 
     265        hist->timeout_id =  
     266                    g_timeout_add(time_slice, GSourceFunc(load_history), hist); 
     267        else { 
     268            hist->timeout_id = 0; 
     269        if (hist->hlist.size() == 1) 
     270                gtk_widget_set_sensitive(hist->reverse, FALSE); 
    210271        } 
    211     _time = (*history_iter)->Time(); 
    212     sprintf(sz_date, "%s\n", ctime(&_time)); 
    213  
    214         GtkTextIter iter; 
    215         gtk_text_buffer_get_end_iter(tb, &iter); 
    216         GtkTextTag *tag = gtk_text_buffer_create_tag(tb, NULL,  
    217                 "foreground-gdk",  
    218                 (*history_iter)->Direction() == D_RECEIVER ? red : blue, 
    219                 NULL); 
    220         gtk_text_buffer_insert_with_tags(tb, &iter, sz_date, -1, tag, NULL); 
    221         gtk_text_buffer_get_end_iter(tb, &iter); 
    222         gtk_text_buffer_insert_with_tags(tb, &iter,  
    223                 (*history_iter)->Text(), -1,  
    224                 tag, NULL); 
    225         gtk_text_buffer_get_end_iter(tb, &iter); 
    226     gtk_text_buffer_insert(tb, &iter, line, -1); 
    227  
    228         if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(hist->check))) 
    229             history_iter--; 
    230         else 
    231             history_iter++; 
    232272    } 
    233   
    234     gtk_text_view_set_buffer(GTK_TEXT_VIEW(hist->text), tb); 
    235     g_object_unref(G_OBJECT(tb)); 
    236 } 
     273}