Changeset 13731


Ignore:
Timestamp:
Jan 1, 2013, 6:43:41 PM (8 years ago)
Author:
jordan
Message:

(gtk) copyediting: indentation & whitespace

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/gtk/filter.c

    r13722 r13731  
    3838enum
    3939{
    40     CAT_FILTER_TYPE_ALL,
    41     CAT_FILTER_TYPE_PRIVATE,
    42     CAT_FILTER_TYPE_PUBLIC,
    43     CAT_FILTER_TYPE_HOST,
    44     CAT_FILTER_TYPE_PARENT,
    45     CAT_FILTER_TYPE_PRI_HIGH,
    46     CAT_FILTER_TYPE_PRI_NORMAL,
    47     CAT_FILTER_TYPE_PRI_LOW,
    48     CAT_FILTER_TYPE_TAG,
    49     CAT_FILTER_TYPE_SEPARATOR,
     40  CAT_FILTER_TYPE_ALL,
     41  CAT_FILTER_TYPE_PRIVATE,
     42  CAT_FILTER_TYPE_PUBLIC,
     43  CAT_FILTER_TYPE_HOST,
     44  CAT_FILTER_TYPE_PARENT,
     45  CAT_FILTER_TYPE_PRI_HIGH,
     46  CAT_FILTER_TYPE_PRI_NORMAL,
     47  CAT_FILTER_TYPE_PRI_LOW,
     48  CAT_FILTER_TYPE_TAG,
     49  CAT_FILTER_TYPE_SEPARATOR,
    5050};
    5151
    5252enum
    5353{
    54     CAT_FILTER_COL_NAME, /* human-readable name; ie, Legaltorrents */
    55     CAT_FILTER_COL_COUNT, /* how many matches there are */
    56     CAT_FILTER_COL_TYPE,
    57     CAT_FILTER_COL_HOST, /* pattern-matching text; ie, legaltorrents.com */
    58     CAT_FILTER_COL_PIXBUF,
    59     CAT_FILTER_N_COLS
     54  CAT_FILTER_COL_NAME, /* human-readable name; ie, Legaltorrents */
     55  CAT_FILTER_COL_COUNT, /* how many matches there are */
     56  CAT_FILTER_COL_TYPE,
     57  CAT_FILTER_COL_HOST, /* pattern-matching text; ie, legaltorrents.com */
     58  CAT_FILTER_COL_PIXBUF,
     59  CAT_FILTER_N_COLS
    6060};
    6161
     
    6363pstrcmp (const void * a, const void * b)
    6464{
    65     return strcmp (* (const char**)a, * (const char**)b);
     65  return strcmp (* (const char**)a, * (const char**)b);
    6666}
    6767
     
    7070get_name_from_host (const char * host)
    7171{
    72     char * name;
    73     const char * dot = strrchr (host, '.');
    74 
    75     if (tr_addressIsIP (host))
    76         name = g_strdup (host);
    77     else if (dot)
    78         name = g_strndup (host, dot - host);
    79     else
    80         name = g_strdup (host);
    81 
    82     *name = g_ascii_toupper (*name);
    83 
    84     return name;
     72  char * name;
     73  const char * dot = strrchr (host, '.');
     74
     75  if (tr_addressIsIP (host))
     76    name = g_strdup (host);
     77  else if (dot)
     78    name = g_strndup (host, dot - host);
     79  else
     80    name = g_strdup (host);
     81
     82  *name = g_ascii_toupper (*name);
     83
     84  return name;
    8585}
    8686
     
    8888category_model_update_count (GtkTreeStore * store, GtkTreeIter * iter, int n)
    8989{
    90     int count;
    91     GtkTreeModel * model = GTK_TREE_MODEL (store);
    92     gtk_tree_model_get (model, iter, CAT_FILTER_COL_COUNT, &count, -1);
    93     if (n != count)
    94         gtk_tree_store_set (store, iter, CAT_FILTER_COL_COUNT, n, -1);
     90  int count;
     91  GtkTreeModel * model = GTK_TREE_MODEL (store);
     92  gtk_tree_model_get (model, iter, CAT_FILTER_COL_COUNT, &count, -1);
     93  if (n != count)
     94    gtk_tree_store_set (store, iter, CAT_FILTER_COL_COUNT, n, -1);
    9595}
    9696
     
    9898favicon_ready_cb (gpointer pixbuf, gpointer vreference)
    9999{
    100     GtkTreeIter iter;
    101     GtkTreeRowReference * reference = vreference;
    102 
    103     if (pixbuf != NULL)
    104     {
    105         GtkTreePath * path = gtk_tree_row_reference_get_path (reference);
    106         GtkTreeModel * model = gtk_tree_row_reference_get_model (reference);
    107 
    108         if (gtk_tree_model_get_iter (model, &iter, path))
    109             gtk_tree_store_set (GTK_TREE_STORE (model), &iter,
    110                                 CAT_FILTER_COL_PIXBUF, pixbuf,
    111                                 -1);
    112 
    113         gtk_tree_path_free (path);
    114 
    115         g_object_unref (pixbuf);
    116     }
    117 
    118     gtk_tree_row_reference_free (reference);
     100  GtkTreeIter iter;
     101  GtkTreeRowReference * reference = vreference;
     102
     103  if (pixbuf != NULL)
     104    {
     105      GtkTreePath * path = gtk_tree_row_reference_get_path (reference);
     106      GtkTreeModel * model = gtk_tree_row_reference_get_model (reference);
     107
     108      if (gtk_tree_model_get_iter (model, &iter, path))
     109        gtk_tree_store_set (GTK_TREE_STORE (model), &iter,
     110                            CAT_FILTER_COL_PIXBUF, pixbuf,
     111                            -1);
     112
     113      gtk_tree_path_free (path);
     114
     115      g_object_unref (pixbuf);
     116    }
     117
     118  gtk_tree_row_reference_free (reference);
    119119}
    120120
     
    122122category_filter_model_update (GtkTreeStore * store)
    123123{
    124     int i, n;
    125     int low = 0;
    126     int all = 0;
    127     int high = 0;
    128     int public = 0;
    129     int normal = 0;
    130     int private = 0;
    131     int store_pos;
    132     GtkTreeIter top;
    133     GtkTreeIter iter;
    134     GtkTreeModel * model = GTK_TREE_MODEL (store);
    135     GPtrArray * hosts = g_ptr_array_new ();
    136     GStringChunk * strings = g_string_chunk_new (4096);
    137     GHashTable * hosts_hash = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);
    138     GObject * o = G_OBJECT (store);
    139     GtkTreeModel * tmodel = GTK_TREE_MODEL (g_object_get_qdata (o, TORRENT_MODEL_KEY));
    140 
    141     g_object_steal_qdata (o, DIRTY_KEY);
    142 
    143     /* Walk through all the torrents, tallying how many matches there are
    144      * for the various categories. Also make a sorted list of all tracker
    145      * hosts s.t. we can merge it with the existing list */
    146     if (gtk_tree_model_iter_nth_child (tmodel, &iter, NULL, 0)) do
    147     {
    148         tr_torrent * tor;
    149         const tr_info * inf;
    150         int keyCount;
    151         char ** keys;
    152 
    153         gtk_tree_model_get (tmodel, &iter, MC_TORRENT, &tor, -1);
    154         inf = tr_torrentInfo (tor);
    155         keyCount = 0;
    156         keys = g_new (char*, inf->trackerCount);
    157 
    158         for (i=0, n=inf->trackerCount; i<n; ++i)
    159         {
    160             int k;
    161             int * count;
    162             char buf[1024];
    163             char * key;
    164 
    165             gtr_get_host_from_url (buf, sizeof (buf), inf->trackers[i].announce);
    166             key = g_string_chunk_insert_const (strings, buf);
    167 
    168             count = g_hash_table_lookup (hosts_hash, key);
    169             if (count == NULL)
     124  int i, n;
     125  int low = 0;
     126  int all = 0;
     127  int high = 0;
     128  int public = 0;
     129  int normal = 0;
     130  int private = 0;
     131  int store_pos;
     132  GtkTreeIter top;
     133  GtkTreeIter iter;
     134  GtkTreeModel * model = GTK_TREE_MODEL (store);
     135  GPtrArray * hosts = g_ptr_array_new ();
     136  GStringChunk * strings = g_string_chunk_new (4096);
     137  GHashTable * hosts_hash = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);
     138  GObject * o = G_OBJECT (store);
     139  GtkTreeModel * tmodel = GTK_TREE_MODEL (g_object_get_qdata (o, TORRENT_MODEL_KEY));
     140
     141  g_object_steal_qdata (o, DIRTY_KEY);
     142
     143  /* Walk through all the torrents, tallying how many matches there are
     144   * for the various categories. Also make a sorted list of all tracker
     145   * hosts s.t. we can merge it with the existing list */
     146  if (gtk_tree_model_iter_nth_child (tmodel, &iter, NULL, 0)) do
     147    {
     148      tr_torrent * tor;
     149      const tr_info * inf;
     150      int keyCount;
     151      char ** keys;
     152
     153      gtk_tree_model_get (tmodel, &iter, MC_TORRENT, &tor, -1);
     154      inf = tr_torrentInfo (tor);
     155      keyCount = 0;
     156      keys = g_new (char*, inf->trackerCount);
     157
     158      for (i=0, n=inf->trackerCount; i<n; ++i)
     159        {
     160          int k;
     161          int * count;
     162          char buf[1024];
     163          char * key;
     164
     165          gtr_get_host_from_url (buf, sizeof (buf), inf->trackers[i].announce);
     166          key = g_string_chunk_insert_const (strings, buf);
     167
     168          count = g_hash_table_lookup (hosts_hash, key);
     169          if (count == NULL)
    170170            {
    171                 count = tr_new0 (int, 1);
    172                 g_hash_table_insert (hosts_hash, key, count);
    173                 g_ptr_array_add (hosts, key);
     171              count = tr_new0 (int, 1);
     172              g_hash_table_insert (hosts_hash, key, count);
     173              g_ptr_array_add (hosts, key);
    174174            }
    175175
    176             for (k=0; k<keyCount; ++k)
    177                 if (!strcmp (keys[k], key))
    178                     break;
    179             if (k==keyCount)
    180                 keys[keyCount++] = key;
    181         }
    182 
    183         for (i=0; i<keyCount; ++i)
    184         {
    185             int * incrementme = g_hash_table_lookup (hosts_hash, keys[i]);
    186             ++*incrementme;
    187         }
    188         g_free (keys);
    189 
    190         ++all;
    191 
    192         if (inf->isPrivate)
    193             ++private;
    194         else
    195             ++public;
    196 
    197         switch (tr_torrentGetPriority (tor))
    198         {
    199             case TR_PRI_HIGH: ++high; break;
    200             case TR_PRI_LOW: ++low; break;
    201             default: ++normal; break;
    202         }
    203     }
    204     while (gtk_tree_model_iter_next (tmodel, &iter));
    205     qsort (hosts->pdata, hosts->len, sizeof (char*), pstrcmp);
    206 
    207     /* update the "all" count */
    208     gtk_tree_model_iter_children (model, &top, NULL);
    209     category_model_update_count (store, &top, all);
    210 
    211     /* skip separator */
    212     gtk_tree_model_iter_next (model, &top);
    213 
    214     /* update the "hosts" subtree */
    215     gtk_tree_model_iter_next (model, &top);
    216     for (i=store_pos=0, n=hosts->len ; ;)
    217     {
    218         const gboolean new_hosts_done = i >= n;
    219         const gboolean old_hosts_done = !gtk_tree_model_iter_nth_child (model, &iter, &top, store_pos);
    220         gboolean remove_row = FALSE;
    221         gboolean insert_row = FALSE;
    222 
    223         /* are we done yet? */
    224         if (new_hosts_done && old_hosts_done)
    225             break;
    226 
    227         /* decide what to do */
    228         if (new_hosts_done)
     176          for (k=0; k<keyCount; ++k)
     177            if (!strcmp (keys[k], key))
     178              break;
     179
     180          if (k==keyCount)
     181            keys[keyCount++] = key;
     182        }
     183
     184      for (i=0; i<keyCount; ++i)
     185        {
     186          int * incrementme = g_hash_table_lookup (hosts_hash, keys[i]);
     187          ++*incrementme;
     188        }
     189
     190      g_free (keys);
     191
     192      ++all;
     193
     194      if (inf->isPrivate)
     195        ++private;
     196      else
     197        ++public;
     198
     199      switch (tr_torrentGetPriority (tor))
     200        {
     201          case TR_PRI_HIGH: ++high; break;
     202          case TR_PRI_LOW: ++low; break;
     203          default: ++normal; break;
     204        }
     205    }
     206  while (gtk_tree_model_iter_next (tmodel, &iter));
     207
     208  qsort (hosts->pdata, hosts->len, sizeof (char*), pstrcmp);
     209
     210  /* update the "all" count */
     211  gtk_tree_model_iter_children (model, &top, NULL);
     212  category_model_update_count (store, &top, all);
     213
     214  /* skip separator */
     215  gtk_tree_model_iter_next (model, &top);
     216
     217  /* update the "hosts" subtree */
     218  gtk_tree_model_iter_next (model, &top);
     219  for (i=store_pos=0, n=hosts->len ; ;)
     220    {
     221      const gboolean new_hosts_done = i >= n;
     222      const gboolean old_hosts_done = !gtk_tree_model_iter_nth_child (model, &iter, &top, store_pos);
     223      gboolean remove_row = FALSE;
     224      gboolean insert_row = FALSE;
     225
     226      /* are we done yet? */
     227      if (new_hosts_done && old_hosts_done)
     228        break;
     229
     230      /* decide what to do */
     231      if (new_hosts_done)
     232        {
     233          remove_row = TRUE;
     234        }
     235      else if (old_hosts_done)
     236        {
     237          insert_row = TRUE;
     238        }
     239      else
     240        {
     241          int cmp;
     242          char * host;
     243          gtk_tree_model_get (model, &iter, CAT_FILTER_COL_HOST, &host,  -1);
     244          cmp = strcmp (host, hosts->pdata[i]);
     245
     246          if (cmp < 0)
    229247            remove_row = TRUE;
    230         else if (old_hosts_done)
     248          else if (cmp > 0)
    231249            insert_row = TRUE;
    232         else {
    233             int cmp;
    234             char * host;
    235             gtk_tree_model_get (model, &iter, CAT_FILTER_COL_HOST, &host,  -1);
    236             cmp = strcmp (host, hosts->pdata[i]);
    237             if (cmp < 0)
    238                 remove_row = TRUE;
    239             else if (cmp > 0)
    240                 insert_row = TRUE;
    241             g_free (host);
    242         }
    243 
    244         /* do something */
    245         if (remove_row) {
    246             /* g_message ("removing row and incrementing i"); */
    247             gtk_tree_store_remove (store, &iter);
    248         } else if (insert_row) {
    249             GtkTreeIter add;
    250             GtkTreePath * path;
    251             GtkTreeRowReference * reference;
    252             tr_session * session = g_object_get_qdata (G_OBJECT (store), SESSION_KEY);
    253             const char * host = hosts->pdata[i];
    254             char * name = get_name_from_host (host);
    255             const int count = * (int*)g_hash_table_lookup (hosts_hash, host);
    256             gtk_tree_store_insert_with_values (store, &add, &top, store_pos,
    257                 CAT_FILTER_COL_HOST, host,
    258                 CAT_FILTER_COL_NAME, name,
    259                 CAT_FILTER_COL_COUNT, count,
    260                 CAT_FILTER_COL_TYPE, CAT_FILTER_TYPE_HOST,
    261                 -1);
    262             path = gtk_tree_model_get_path (model, &add);
    263             reference = gtk_tree_row_reference_new (model, path);
    264             gtr_get_favicon (session, host, favicon_ready_cb, reference);
    265             gtk_tree_path_free (path);
    266             g_free (name);
    267             ++store_pos;
    268             ++i;
    269         } else { /* update row */
    270             const char * host = hosts->pdata[i];
    271             const int count = * (int*)g_hash_table_lookup (hosts_hash, host);
    272             category_model_update_count (store, &iter, count);
    273             ++store_pos;
    274             ++i;
    275         }
    276     }
    277 
    278     /* update the "public" subtree */
    279     gtk_tree_model_iter_next (model, &top);
    280     gtk_tree_model_iter_children (model, &iter, &top);
    281     category_model_update_count (store, &iter, public);
    282     gtk_tree_model_iter_next (model, &iter);
    283     category_model_update_count (store, &iter, private);
    284 
    285     /* update the "priority" subtree */
    286     gtk_tree_model_iter_next (model, &top);
    287     gtk_tree_model_iter_children (model, &iter, &top);
    288     category_model_update_count (store, &iter, high);
    289     gtk_tree_model_iter_next (model, &iter);
    290     category_model_update_count (store, &iter, normal);
    291     gtk_tree_model_iter_next (model, &iter);
    292     category_model_update_count (store, &iter, low);
    293 
    294     /* cleanup */
    295     g_ptr_array_free (hosts, TRUE);
    296     g_hash_table_unref (hosts_hash);
    297     g_string_chunk_free (strings);
    298     return FALSE;
     250
     251          g_free (host);
     252        }
     253
     254      /* do something */
     255      if (remove_row)
     256        {
     257          /* g_message ("removing row and incrementing i"); */
     258          gtk_tree_store_remove (store, &iter);
     259        }
     260      else if (insert_row)
     261        {
     262          GtkTreeIter add;
     263          GtkTreePath * path;
     264          GtkTreeRowReference * reference;
     265          tr_session * session = g_object_get_qdata (G_OBJECT (store), SESSION_KEY);
     266          const char * host = hosts->pdata[i];
     267          char * name = get_name_from_host (host);
     268          const int count = * (int*)g_hash_table_lookup (hosts_hash, host);
     269          gtk_tree_store_insert_with_values (store, &add, &top, store_pos,
     270                                             CAT_FILTER_COL_HOST, host,
     271                                             CAT_FILTER_COL_NAME, name,
     272                                             CAT_FILTER_COL_COUNT, count,
     273                                             CAT_FILTER_COL_TYPE, CAT_FILTER_TYPE_HOST,
     274                                             -1);
     275          path = gtk_tree_model_get_path (model, &add);
     276          reference = gtk_tree_row_reference_new (model, path);
     277          gtr_get_favicon (session, host, favicon_ready_cb, reference);
     278          gtk_tree_path_free (path);
     279          g_free (name);
     280          ++store_pos;
     281          ++i;
     282        }
     283      else /* update row */
     284        {
     285          const char * host = hosts->pdata[i];
     286          const int count = * (int*)g_hash_table_lookup (hosts_hash, host);
     287          category_model_update_count (store, &iter, count);
     288          ++store_pos;
     289          ++i;
     290        }
     291    }
     292
     293  /* update the "public" subtree */
     294  gtk_tree_model_iter_next (model, &top);
     295  gtk_tree_model_iter_children (model, &iter, &top);
     296  category_model_update_count (store, &iter, public);
     297  gtk_tree_model_iter_next (model, &iter);
     298  category_model_update_count (store, &iter, private);
     299
     300  /* update the "priority" subtree */
     301  gtk_tree_model_iter_next (model, &top);
     302  gtk_tree_model_iter_children (model, &iter, &top);
     303  category_model_update_count (store, &iter, high);
     304  gtk_tree_model_iter_next (model, &iter);
     305  category_model_update_count (store, &iter, normal);
     306  gtk_tree_model_iter_next (model, &iter);
     307  category_model_update_count (store, &iter, low);
     308
     309  /* cleanup */
     310  g_ptr_array_free (hosts, TRUE);
     311  g_hash_table_unref (hosts_hash);
     312  g_string_chunk_free (strings);
     313  return FALSE;
    299314}
    300315
     
    302317category_filter_model_new (GtkTreeModel * tmodel)
    303318{
    304     GtkTreeIter iter;
    305     const int invisible_number = -1; /* doesn't get rendered */
    306     GtkTreeStore * store = gtk_tree_store_new (CAT_FILTER_N_COLS,
    307                                                G_TYPE_STRING,
    308                                                G_TYPE_INT,
    309                                                G_TYPE_INT,
    310                                                G_TYPE_STRING,
    311                                                GDK_TYPE_PIXBUF);
    312 
    313     gtk_tree_store_insert_with_values (store, NULL, NULL, -1,
    314         CAT_FILTER_COL_NAME, _("All"),
    315         CAT_FILTER_COL_TYPE, CAT_FILTER_TYPE_ALL,
    316         -1);
    317     gtk_tree_store_insert_with_values (store, NULL, NULL, -1,
    318         CAT_FILTER_COL_TYPE, CAT_FILTER_TYPE_SEPARATOR,
    319         -1);
    320 
    321     gtk_tree_store_insert_with_values (store, &iter, NULL, -1,
    322         CAT_FILTER_COL_NAME, _("Trackers"),
    323         CAT_FILTER_COL_COUNT, invisible_number,
    324         CAT_FILTER_COL_TYPE, CAT_FILTER_TYPE_PARENT,
    325         -1);
    326 
    327     gtk_tree_store_insert_with_values (store, &iter, NULL, -1,
    328         CAT_FILTER_COL_NAME, _("Privacy"),
    329         CAT_FILTER_COL_COUNT, invisible_number,
    330         CAT_FILTER_COL_TYPE, CAT_FILTER_TYPE_PARENT,
    331         -1);
    332     gtk_tree_store_insert_with_values (store, NULL, &iter, -1,
    333         CAT_FILTER_COL_NAME, _("Public"),
    334         CAT_FILTER_COL_TYPE, CAT_FILTER_TYPE_PUBLIC,
    335         -1);
    336     gtk_tree_store_insert_with_values (store, NULL, &iter, -1,
    337         CAT_FILTER_COL_NAME, _("Private"),
    338         CAT_FILTER_COL_TYPE, CAT_FILTER_TYPE_PRIVATE,
    339         -1);
    340 
    341     gtk_tree_store_insert_with_values (store, &iter, NULL, -1,
    342         CAT_FILTER_COL_NAME, _("Priority"),
    343         CAT_FILTER_COL_COUNT, invisible_number,
    344         CAT_FILTER_COL_TYPE, CAT_FILTER_TYPE_PARENT,
    345         -1);
    346     gtk_tree_store_insert_with_values (store, NULL, &iter, -1,
    347         CAT_FILTER_COL_NAME, _("High"),
    348         CAT_FILTER_COL_TYPE, CAT_FILTER_TYPE_PRI_HIGH,
    349         -1);
    350     gtk_tree_store_insert_with_values (store, NULL, &iter, -1,
    351         CAT_FILTER_COL_NAME, _("Normal"),
    352         CAT_FILTER_COL_TYPE, CAT_FILTER_TYPE_PRI_NORMAL,
    353         -1);
    354     gtk_tree_store_insert_with_values (store, NULL, &iter, -1,
    355         CAT_FILTER_COL_NAME, _("Low"),
    356         CAT_FILTER_COL_TYPE, CAT_FILTER_TYPE_PRI_LOW,
    357         -1);
    358 
    359     g_object_set_qdata (G_OBJECT (store), TORRENT_MODEL_KEY, tmodel);
    360     category_filter_model_update (store);
    361     return GTK_TREE_MODEL (store);
     319  GtkTreeIter iter;
     320  const int invisible_number = -1; /* doesn't get rendered */
     321  GtkTreeStore * store = gtk_tree_store_new (CAT_FILTER_N_COLS,
     322                                             G_TYPE_STRING,
     323                                             G_TYPE_INT,
     324                                             G_TYPE_INT,
     325                                             G_TYPE_STRING,
     326                                             GDK_TYPE_PIXBUF);
     327
     328  gtk_tree_store_insert_with_values (store, NULL, NULL, -1,
     329                                     CAT_FILTER_COL_NAME, _("All"),
     330                                     CAT_FILTER_COL_TYPE, CAT_FILTER_TYPE_ALL,
     331                                     -1);
     332  gtk_tree_store_insert_with_values (store, NULL, NULL, -1,
     333                                     CAT_FILTER_COL_TYPE, CAT_FILTER_TYPE_SEPARATOR,
     334                                     -1);
     335
     336  gtk_tree_store_insert_with_values (store, &iter, NULL, -1,
     337                                     CAT_FILTER_COL_NAME, _("Trackers"),
     338                                     CAT_FILTER_COL_COUNT, invisible_number,
     339                                     CAT_FILTER_COL_TYPE, CAT_FILTER_TYPE_PARENT,
     340                                     -1);
     341
     342  gtk_tree_store_insert_with_values (store, &iter, NULL, -1,
     343                                     CAT_FILTER_COL_NAME, _("Privacy"),
     344                                     CAT_FILTER_COL_COUNT, invisible_number,
     345                                     CAT_FILTER_COL_TYPE, CAT_FILTER_TYPE_PARENT,
     346                                     -1);
     347  gtk_tree_store_insert_with_values (store, NULL, &iter, -1,
     348                                     CAT_FILTER_COL_NAME, _("Public"),
     349                                     CAT_FILTER_COL_TYPE, CAT_FILTER_TYPE_PUBLIC,
     350                                     -1);
     351  gtk_tree_store_insert_with_values (store, NULL, &iter, -1,
     352                                     CAT_FILTER_COL_NAME, _("Private"),
     353                                     CAT_FILTER_COL_TYPE, CAT_FILTER_TYPE_PRIVATE,
     354                                     -1);
     355
     356  gtk_tree_store_insert_with_values (store, &iter, NULL, -1,
     357                                     CAT_FILTER_COL_NAME, _("Priority"),
     358                                     CAT_FILTER_COL_COUNT, invisible_number,
     359                                     CAT_FILTER_COL_TYPE, CAT_FILTER_TYPE_PARENT,
     360                                     -1);
     361  gtk_tree_store_insert_with_values (store, NULL, &iter, -1,
     362                                     CAT_FILTER_COL_NAME, _("High"),
     363                                     CAT_FILTER_COL_TYPE, CAT_FILTER_TYPE_PRI_HIGH,
     364                                     -1);
     365  gtk_tree_store_insert_with_values (store, NULL, &iter, -1,
     366                                     CAT_FILTER_COL_NAME, _("Normal"),
     367                                     CAT_FILTER_COL_TYPE, CAT_FILTER_TYPE_PRI_NORMAL,
     368                                     -1);
     369  gtk_tree_store_insert_with_values (store, NULL, &iter, -1,
     370                                     CAT_FILTER_COL_NAME, _("Low"),
     371                                     CAT_FILTER_COL_TYPE, CAT_FILTER_TYPE_PRI_LOW,
     372                                     -1);
     373
     374  g_object_set_qdata (G_OBJECT (store), TORRENT_MODEL_KEY, tmodel);
     375  category_filter_model_update (store);
     376  return GTK_TREE_MODEL (store);
    362377}
    363378
     
    365380is_it_a_separator (GtkTreeModel * m, GtkTreeIter * iter, gpointer data UNUSED)
    366381{
    367     int type;
    368     gtk_tree_model_get (m, iter, CAT_FILTER_COL_TYPE, &type, -1);
    369     return type == CAT_FILTER_TYPE_SEPARATOR;
     382  int type;
     383  gtk_tree_model_get (m, iter, CAT_FILTER_COL_TYPE, &type, -1);
     384  return type == CAT_FILTER_TYPE_SEPARATOR;
    370385}
    371386
     
    373388category_model_update_idle (gpointer category_model)
    374389{
    375     GObject * o = G_OBJECT (category_model);
    376     const gboolean pending = g_object_get_qdata (o, DIRTY_KEY) != NULL;
    377     if (!pending)
    378     {
    379         GSourceFunc func = (GSourceFunc) category_filter_model_update;
    380         g_object_set_qdata (o, DIRTY_KEY, GINT_TO_POINTER (1));
    381         gdk_threads_add_idle (func, category_model);
     390  GObject * o = G_OBJECT (category_model);
     391  const gboolean pending = g_object_get_qdata (o, DIRTY_KEY) != NULL;
     392  if (!pending)
     393    {
     394      GSourceFunc func = (GSourceFunc) category_filter_model_update;
     395      g_object_set_qdata (o, DIRTY_KEY, GINT_TO_POINTER (1));
     396      gdk_threads_add_idle (func, category_model);
    382397    }
    383398}
     
    389404                           gpointer        category_model)
    390405{
    391     category_model_update_idle (category_model);
     406  category_model_update_idle (category_model);
    392407}
    393408
     
    397412                              gpointer       category_model)
    398413{
    399     category_model_update_idle (category_model);
     414  category_model_update_idle (category_model);
    400415}
    401416
     
    407422                    gpointer           data UNUSED)
    408423{
    409     int type;
    410     int width = 0;
    411     const gboolean leaf = !gtk_tree_model_iter_has_child (tree_model, iter);
    412 
    413     gtk_tree_model_get (tree_model, iter, CAT_FILTER_COL_TYPE, &type, -1);
    414     if (type == CAT_FILTER_TYPE_HOST)
    415         width = 20;
    416 
    417     g_object_set (cell_renderer, "width", width,
    418                                  "sensitive", leaf,
    419                                  NULL);
     424  int type;
     425  int width = 0;
     426  const gboolean leaf = !gtk_tree_model_iter_has_child (tree_model, iter);
     427
     428  gtk_tree_model_get (tree_model, iter, CAT_FILTER_COL_TYPE, &type, -1);
     429  if (type == CAT_FILTER_TYPE_HOST)
     430    width = 20;
     431
     432  g_object_set (cell_renderer, "width", width,
     433                               "sensitive", leaf,
     434                               NULL);
    420435}
    421436
     
    427442                      gpointer          data UNUSED)
    428443{
    429     const gboolean leaf = !gtk_tree_model_iter_has_child (tree_model, iter);
    430 
    431     g_object_set (cell_renderer, "sensitive", leaf,
    432                                  NULL);
     444  const gboolean leaf = !gtk_tree_model_iter_has_child (tree_model, iter);
     445
     446  g_object_set (cell_renderer, "sensitive", leaf,
     447                               NULL);
    433448}
    434449
     
    440455                    gpointer           data UNUSED)
    441456{
    442     int count;
    443     char buf[32];
    444     const gboolean leaf = !gtk_tree_model_iter_has_child (tree_model, iter);
    445 
    446     gtk_tree_model_get (tree_model, iter, CAT_FILTER_COL_COUNT, &count, -1);
    447 
    448     if (count >= 0)
    449         g_snprintf (buf, sizeof (buf), "%'d", count);
    450     else
    451         *buf = '\0';
    452 
    453     g_object_set (cell_renderer, "text", buf,
    454                                  "sensitive", leaf,
    455                                  NULL);
     457  int count;
     458  char buf[32];
     459  const gboolean leaf = !gtk_tree_model_iter_has_child (tree_model, iter);
     460
     461  gtk_tree_model_get (tree_model, iter, CAT_FILTER_COL_COUNT, &count, -1);
     462
     463  if (count >= 0)
     464    g_snprintf (buf, sizeof (buf), "%'d", count);
     465  else
     466    *buf = '\0';
     467
     468  g_object_set (cell_renderer, "text", buf,
     469                               "sensitive", leaf,
     470                               NULL);
    456471}
    457472
     
    459474number_renderer_new (void)
    460475{
    461     GtkCellRenderer * r = gtk_cell_renderer_text_new ();
    462 
    463     g_object_set (G_OBJECT (r), "alignment", PANGO_ALIGN_RIGHT,
    464                                  "weight", PANGO_WEIGHT_ULTRALIGHT,
    465                                  "xalign", 1.0,
    466                                  "xpad", GUI_PAD,
    467                                  NULL);
    468 
    469     return r;
     476  GtkCellRenderer * r = gtk_cell_renderer_text_new ();
     477
     478  g_object_set (G_OBJECT (r), "alignment", PANGO_ALIGN_RIGHT,
     479                              "weight", PANGO_WEIGHT_ULTRALIGHT,
     480                              "xalign", 1.0,
     481                              "xpad", GUI_PAD,
     482                              NULL);
     483
     484  return r;
    470485}
    471486
     
    473488disconnect_cat_model_callbacks (gpointer tmodel, GObject * cat_model)
    474489{
    475     g_signal_handlers_disconnect_by_func (tmodel, torrent_model_row_changed, cat_model);
    476     g_signal_handlers_disconnect_by_func (tmodel, torrent_model_row_deleted_cb, cat_model);
     490  g_signal_handlers_disconnect_by_func (tmodel, torrent_model_row_changed, cat_model);
     491  g_signal_handlers_disconnect_by_func (tmodel, torrent_model_row_deleted_cb, cat_model);
    477492}
    478493
     
    480495category_combo_box_new (GtkTreeModel * tmodel)
    481496{
    482     GtkWidget * c;
    483     GtkCellRenderer * r;
    484     GtkTreeModel * cat_model;
    485     GtkCellLayout * c_cell_layout;
    486     GtkComboBox * c_combo_box;
    487 
    488     /* create the category combobox */
    489     cat_model = category_filter_model_new (tmodel);
    490     c = gtk_combo_box_new_with_model (cat_model);
    491     c_combo_box = GTK_COMBO_BOX (c);
    492     c_cell_layout = GTK_CELL_LAYOUT (c);
    493     g_object_unref (cat_model);
    494     gtk_combo_box_set_row_separator_func (c_combo_box,
    495                                           is_it_a_separator, NULL, NULL);
    496     gtk_combo_box_set_active (c_combo_box, 0);
    497 
    498     r = gtk_cell_renderer_pixbuf_new ();
    499     gtk_cell_layout_pack_start (c_cell_layout, r, FALSE);
    500     gtk_cell_layout_set_cell_data_func (c_cell_layout, r,
    501                                         render_pixbuf_func, NULL, NULL);
    502     gtk_cell_layout_set_attributes (c_cell_layout, r,
    503                                     "pixbuf", CAT_FILTER_COL_PIXBUF,
    504                                     NULL);
    505 
    506     r = gtk_cell_renderer_text_new ();
    507     gtk_cell_layout_pack_start (c_cell_layout, r, FALSE);
    508     gtk_cell_layout_set_attributes (c_cell_layout, r,
    509                                     "text", CAT_FILTER_COL_NAME,
    510                                     NULL);
    511     gtk_cell_layout_set_cell_data_func (c_cell_layout, r,
    512                                         is_capital_sensitive,
    513                                         NULL, NULL);
    514 
    515 
    516     r = number_renderer_new ();
    517     gtk_cell_layout_pack_end (c_cell_layout, r, TRUE);
    518     gtk_cell_layout_set_cell_data_func (c_cell_layout, r,
    519                                         render_number_func, NULL, NULL);
    520 
    521     g_object_weak_ref (G_OBJECT (cat_model), disconnect_cat_model_callbacks, tmodel);
    522     g_signal_connect (tmodel, "row-changed", G_CALLBACK (torrent_model_row_changed), cat_model);
    523     g_signal_connect (tmodel, "row-inserted", G_CALLBACK (torrent_model_row_changed), cat_model);
    524     g_signal_connect (tmodel, "row-deleted", G_CALLBACK (torrent_model_row_deleted_cb), cat_model);
    525 
    526     return c;
     497  GtkWidget * c;
     498  GtkCellRenderer * r;
     499  GtkTreeModel * cat_model;
     500  GtkCellLayout * c_cell_layout;
     501  GtkComboBox * c_combo_box;
     502
     503  /* create the category combobox */
     504  cat_model = category_filter_model_new (tmodel);
     505  c = gtk_combo_box_new_with_model (cat_model);
     506  c_combo_box = GTK_COMBO_BOX (c);
     507  c_cell_layout = GTK_CELL_LAYOUT (c);
     508  g_object_unref (cat_model);
     509  gtk_combo_box_set_row_separator_func (c_combo_box,
     510                                        is_it_a_separator, NULL, NULL);
     511  gtk_combo_box_set_active (c_combo_box, 0);
     512
     513  r = gtk_cell_renderer_pixbuf_new ();
     514  gtk_cell_layout_pack_start (c_cell_layout, r, FALSE);
     515  gtk_cell_layout_set_cell_data_func (c_cell_layout, r,
     516                                      render_pixbuf_func, NULL, NULL);
     517  gtk_cell_layout_set_attributes (c_cell_layout, r,
     518                                  "pixbuf", CAT_FILTER_COL_PIXBUF,
     519                                  NULL);
     520
     521  r = gtk_cell_renderer_text_new ();
     522  gtk_cell_layout_pack_start (c_cell_layout, r, FALSE);
     523  gtk_cell_layout_set_attributes (c_cell_layout, r,
     524                                  "text", CAT_FILTER_COL_NAME,
     525                                  NULL);
     526  gtk_cell_layout_set_cell_data_func (c_cell_layout, r,
     527                                      is_capital_sensitive,
     528                                      NULL, NULL);
     529
     530
     531  r = number_renderer_new ();
     532  gtk_cell_layout_pack_end (c_cell_layout, r, TRUE);
     533  gtk_cell_layout_set_cell_data_func (c_cell_layout, r,
     534                                      render_number_func, NULL, NULL);
     535
     536  g_object_weak_ref (G_OBJECT (cat_model), disconnect_cat_model_callbacks, tmodel);
     537  g_signal_connect (tmodel, "row-changed", G_CALLBACK (torrent_model_row_changed), cat_model);
     538  g_signal_connect (tmodel, "row-inserted", G_CALLBACK (torrent_model_row_changed), cat_model);
     539  g_signal_connect (tmodel, "row-deleted", G_CALLBACK (torrent_model_row_deleted_cb), cat_model);
     540
     541  return c;
    527542}
    528543
     
    530545test_category (tr_torrent * tor, int active_category_type, const char * host)
    531546{
    532     const tr_info * const inf = tr_torrentInfo (tor);
    533 
    534     switch (active_category_type)
    535     {
    536         case CAT_FILTER_TYPE_ALL:
    537             return TRUE;
    538 
    539         case CAT_FILTER_TYPE_PRIVATE:
    540             return inf->isPrivate;
    541 
    542         case CAT_FILTER_TYPE_PUBLIC:
    543             return !inf->isPrivate;
    544 
    545         case CAT_FILTER_TYPE_PRI_HIGH:
    546             return tr_torrentGetPriority (tor) == TR_PRI_HIGH;
    547 
    548         case CAT_FILTER_TYPE_PRI_NORMAL:
    549             return tr_torrentGetPriority (tor) == TR_PRI_NORMAL;
    550 
    551         case CAT_FILTER_TYPE_PRI_LOW:
    552             return tr_torrentGetPriority (tor) == TR_PRI_LOW;
    553 
    554         case CAT_FILTER_TYPE_HOST: {
    555             unsigned int i;
    556             char tmp[1024];
    557             for (i=0; i<inf->trackerCount; ++i) {
    558                 gtr_get_host_from_url (tmp, sizeof (tmp), inf->trackers[i].announce);
    559                 if (!strcmp (tmp, host))
    560                     break;
     547  const tr_info * const inf = tr_torrentInfo (tor);
     548
     549  switch (active_category_type)
     550    {
     551      case CAT_FILTER_TYPE_ALL:
     552        return TRUE;
     553
     554      case CAT_FILTER_TYPE_PRIVATE:
     555        return inf->isPrivate;
     556
     557      case CAT_FILTER_TYPE_PUBLIC:
     558        return !inf->isPrivate;
     559
     560      case CAT_FILTER_TYPE_PRI_HIGH:
     561        return tr_torrentGetPriority (tor) == TR_PRI_HIGH;
     562
     563      case CAT_FILTER_TYPE_PRI_NORMAL:
     564        return tr_torrentGetPriority (tor) == TR_PRI_NORMAL;
     565
     566      case CAT_FILTER_TYPE_PRI_LOW:
     567        return tr_torrentGetPriority (tor) == TR_PRI_LOW;
     568
     569      case CAT_FILTER_TYPE_HOST:
     570        {
     571          unsigned int i;
     572          char tmp[1024];
     573          for (i=0; i<inf->trackerCount; ++i)
     574            {
     575              gtr_get_host_from_url (tmp, sizeof (tmp), inf->trackers[i].announce);
     576              if (!strcmp (tmp, host))
     577                break;
    561578            }
    562             return i < inf->trackerCount;
    563         }
    564 
    565         case CAT_FILTER_TYPE_TAG:
    566             /* FIXME */
    567             return TRUE;
    568 
    569         default:
    570             return TRUE;
     579          return i < inf->trackerCount;
     580        }
     581
     582      case CAT_FILTER_TYPE_TAG:
     583        /* FIXME */
     584        return TRUE;
     585
     586      default:
     587        return TRUE;
    571588    }
    572589}
     
    580597enum
    581598{
    582     ACTIVITY_FILTER_ALL,
    583     ACTIVITY_FILTER_DOWNLOADING,
    584     ACTIVITY_FILTER_SEEDING,
    585     ACTIVITY_FILTER_ACTIVE,
    586     ACTIVITY_FILTER_PAUSED,
    587     ACTIVITY_FILTER_FINISHED,
    588     ACTIVITY_FILTER_VERIFYING,
    589     ACTIVITY_FILTER_ERROR,
    590     ACTIVITY_FILTER_SEPARATOR
     599  ACTIVITY_FILTER_ALL,
     600  ACTIVITY_FILTER_DOWNLOADING,
     601  ACTIVITY_FILTER_SEEDING,
     602  ACTIVITY_FILTER_ACTIVE,
     603  ACTIVITY_FILTER_PAUSED,
     604  ACTIVITY_FILTER_FINISHED,
     605  ACTIVITY_FILTER_VERIFYING,
     606  ACTIVITY_FILTER_ERROR,
     607  ACTIVITY_FILTER_SEPARATOR
    591608};
    592609
    593610enum
    594611{
    595     ACTIVITY_FILTER_COL_NAME,
    596     ACTIVITY_FILTER_COL_COUNT,
    597     ACTIVITY_FILTER_COL_TYPE,
    598     ACTIVITY_FILTER_COL_STOCK_ID,
    599     ACTIVITY_FILTER_N_COLS
     612  ACTIVITY_FILTER_COL_NAME,
     613  ACTIVITY_FILTER_COL_COUNT,
     614  ACTIVITY_FILTER_COL_TYPE,
     615  ACTIVITY_FILTER_COL_STOCK_ID,
     616  ACTIVITY_FILTER_N_COLS
    600617};
    601618
     
    603620activity_is_it_a_separator (GtkTreeModel * m, GtkTreeIter * i, gpointer d UNUSED)
    604621{
    605     int type;
    606     gtk_tree_model_get (m, i, ACTIVITY_FILTER_COL_TYPE, &type, -1);
    607     return type == ACTIVITY_FILTER_SEPARATOR;
     622  int type;
     623  gtk_tree_model_get (m, i, ACTIVITY_FILTER_COL_TYPE, &type, -1);
     624  return type == ACTIVITY_FILTER_SEPARATOR;
    608625}
    609626
     
    611628test_torrent_activity (tr_torrent * tor, int type)
    612629{
    613     const tr_stat * st = tr_torrentStatCached (tor);
    614 
    615     switch (type)
    616     {
    617         case ACTIVITY_FILTER_DOWNLOADING:
    618             return (st->activity == TR_STATUS_DOWNLOAD)
    619                 || (st->activity == TR_STATUS_DOWNLOAD_WAIT);
    620 
    621         case ACTIVITY_FILTER_SEEDING:
    622             return (st->activity == TR_STATUS_SEED)
    623                 || (st->activity == TR_STATUS_SEED_WAIT);
    624 
    625         case ACTIVITY_FILTER_ACTIVE:
    626             return (st->peersSendingToUs > 0)
    627                 || (st->peersGettingFromUs > 0)
    628                 || (st->webseedsSendingToUs > 0)
    629                 || (st->activity == TR_STATUS_CHECK);
    630 
    631         case ACTIVITY_FILTER_PAUSED:
    632             return st->activity == TR_STATUS_STOPPED;
    633 
    634         case ACTIVITY_FILTER_FINISHED:
    635             return st->finished == TRUE;
    636 
    637         case ACTIVITY_FILTER_VERIFYING:
    638             return (st->activity == TR_STATUS_CHECK)
    639                 || (st->activity == TR_STATUS_CHECK_WAIT);
    640 
    641         case ACTIVITY_FILTER_ERROR:
    642             return st->error != 0;
    643 
    644         default: /* ACTIVITY_FILTER_ALL */
    645             return TRUE;
     630  const tr_stat * st = tr_torrentStatCached (tor);
     631
     632  switch (type)
     633    {
     634      case ACTIVITY_FILTER_DOWNLOADING:
     635        return (st->activity == TR_STATUS_DOWNLOAD)
     636            || (st->activity == TR_STATUS_DOWNLOAD_WAIT);
     637
     638      case ACTIVITY_FILTER_SEEDING:
     639        return (st->activity == TR_STATUS_SEED)
     640            || (st->activity == TR_STATUS_SEED_WAIT);
     641
     642      case ACTIVITY_FILTER_ACTIVE:
     643        return (st->peersSendingToUs > 0)
     644            || (st->peersGettingFromUs > 0)
     645            || (st->webseedsSendingToUs > 0)
     646            || (st->activity == TR_STATUS_CHECK);
     647
     648      case ACTIVITY_FILTER_PAUSED:
     649        return st->activity == TR_STATUS_STOPPED;
     650
     651      case ACTIVITY_FILTER_FINISHED:
     652        return st->finished == TRUE;
     653
     654      case ACTIVITY_FILTER_VERIFYING:
     655        return (st->activity == TR_STATUS_CHECK)
     656            || (st->activity == TR_STATUS_CHECK_WAIT);
     657
     658      case ACTIVITY_FILTER_ERROR:
     659        return st->error != 0;
     660
     661      default: /* ACTIVITY_FILTER_ALL */
     662        return TRUE;
    646663    }
    647664}
     
    650667status_model_update_count (GtkListStore * store, GtkTreeIter * iter, int n)
    651668{
    652     int count;
    653     GtkTreeModel * model = GTK_TREE_MODEL (store);
    654     gtk_tree_model_get (model, iter, ACTIVITY_FILTER_COL_COUNT, &count, -1);
    655     if (n != count)
    656         gtk_list_store_set (store, iter, ACTIVITY_FILTER_COL_COUNT, n, -1);
     669  int count;
     670  GtkTreeModel * model = GTK_TREE_MODEL (store);
     671  gtk_tree_model_get (model, iter, ACTIVITY_FILTER_COL_COUNT, &count, -1);
     672  if (n != count)
     673    gtk_list_store_set (store, iter, ACTIVITY_FILTER_COL_COUNT, n, -1);
    657674}
    658675
     
    660677activity_filter_model_update (GtkListStore * store)
    661678{
    662     GtkTreeIter iter;
    663     GtkTreeModel * model = GTK_TREE_MODEL (store);
    664     GObject * o = G_OBJECT (store);
    665     GtkTreeModel * tmodel = GTK_TREE_MODEL (g_object_get_qdata (o, TORRENT_MODEL_KEY));
    666 
    667     g_object_steal_qdata (o, DIRTY_KEY);
    668 
    669     if (gtk_tree_model_iter_nth_child (model, &iter, NULL, 0)) do
    670     {
    671         int hits;
    672         int type;
    673         GtkTreeIter torrent_iter;
    674 
    675         gtk_tree_model_get (model, &iter, ACTIVITY_FILTER_COL_TYPE, &type, -1);
    676 
    677         hits = 0;
    678         if (gtk_tree_model_iter_nth_child (tmodel, &torrent_iter, NULL, 0)) do {
    679             tr_torrent * tor;
    680             gtk_tree_model_get (tmodel, &torrent_iter, MC_TORRENT, &tor, -1);
    681             if (test_torrent_activity (tor, type))
    682                 ++hits;
    683         } while (gtk_tree_model_iter_next (tmodel, &torrent_iter));
    684 
    685         status_model_update_count (store, &iter, hits);
    686 
    687     } while (gtk_tree_model_iter_next (model, &iter));
     679  GtkTreeIter iter;
     680  GtkTreeModel * model = GTK_TREE_MODEL (store);
     681  GObject * o = G_OBJECT (store);
     682  GtkTreeModel * tmodel = GTK_TREE_MODEL (g_object_get_qdata (o, TORRENT_MODEL_KEY));
     683
     684  g_object_steal_qdata (o, DIRTY_KEY);
     685
     686  if (gtk_tree_model_iter_nth_child (model, &iter, NULL, 0)) do
     687    {
     688      int hits;
     689      int type;
     690      GtkTreeIter torrent_iter;
     691
     692      gtk_tree_model_get (model, &iter, ACTIVITY_FILTER_COL_TYPE, &type, -1);
     693
     694      hits = 0;
     695      if (gtk_tree_model_iter_nth_child (tmodel, &torrent_iter, NULL, 0)) do
     696        {
     697          tr_torrent * tor;
     698          gtk_tree_model_get (tmodel, &torrent_iter, MC_TORRENT, &tor, -1);
     699          if (test_torrent_activity (tor, type))
     700            ++hits;
     701        }
     702      while (gtk_tree_model_iter_next (tmodel, &torrent_iter));
     703
     704      status_model_update_count (store, &iter, hits);
     705
     706    }
     707  while (gtk_tree_model_iter_next (model, &iter));
    688708}
    689709
     
    691711activity_filter_model_new (GtkTreeModel * tmodel)
    692712{
    693     int i, n;
    694     struct {
    695         int type;
    696         const char * context;
    697         const char * name;
    698         const char * stock_id;
    699     } types[] = {
    700         { ACTIVITY_FILTER_ALL, NULL, N_("All"), NULL },
    701         { ACTIVITY_FILTER_SEPARATOR, NULL, NULL, NULL },
    702         { ACTIVITY_FILTER_ACTIVE, NULL, N_("Active"), GTK_STOCK_EXECUTE },
    703         { ACTIVITY_FILTER_DOWNLOADING, "Verb", NC_("Verb", "Downloading"), GTK_STOCK_GO_DOWN },
    704         { ACTIVITY_FILTER_SEEDING, "Verb", NC_("Verb", "Seeding"), GTK_STOCK_GO_UP },
    705         { ACTIVITY_FILTER_PAUSED, NULL, N_("Paused"), GTK_STOCK_MEDIA_PAUSE },
    706         { ACTIVITY_FILTER_FINISHED, NULL, N_("Finished"), NULL },
    707         { ACTIVITY_FILTER_VERIFYING, "Verb", NC_("Verb", "Verifying"), GTK_STOCK_REFRESH },
    708         { ACTIVITY_FILTER_ERROR, NULL, N_("Error"), GTK_STOCK_DIALOG_ERROR }
    709     };
    710     GtkListStore * store = gtk_list_store_new (ACTIVITY_FILTER_N_COLS,
    711                                                G_TYPE_STRING,
    712                                                G_TYPE_INT,
    713                                                G_TYPE_INT,
    714                                                G_TYPE_STRING);
    715     for (i=0, n=G_N_ELEMENTS (types); i<n; ++i) {
    716         const char * name = types[i].context ? g_dpgettext2 (NULL, types[i].context, types[i].name)
    717                                              : _ (types[i].name);
    718         gtk_list_store_insert_with_values (store, NULL, -1,
    719             ACTIVITY_FILTER_COL_NAME, name,
    720             ACTIVITY_FILTER_COL_TYPE, types[i].type,
    721             ACTIVITY_FILTER_COL_STOCK_ID, types[i].stock_id,
    722             -1);
    723     }
    724 
    725     g_object_set_qdata (G_OBJECT (store), TORRENT_MODEL_KEY, tmodel);
    726     activity_filter_model_update (store);
    727     return GTK_TREE_MODEL (store);
     713  int i, n;
     714  struct {
     715    int type;
     716    const char * context;
     717    const char * name;
     718    const char * stock_id;
     719  } types[] = {
     720    { ACTIVITY_FILTER_ALL, NULL, N_("All"), NULL },
     721    { ACTIVITY_FILTER_SEPARATOR, NULL, NULL, NULL },
     722    { ACTIVITY_FILTER_ACTIVE, NULL, N_("Active"), GTK_STOCK_EXECUTE },
     723    { ACTIVITY_FILTER_DOWNLOADING, "Verb", NC_("Verb", "Downloading"), GTK_STOCK_GO_DOWN },
     724    { ACTIVITY_FILTER_SEEDING, "Verb", NC_("Verb", "Seeding"), GTK_STOCK_GO_UP },
     725    { ACTIVITY_FILTER_PAUSED, NULL, N_("Paused"), GTK_STOCK_MEDIA_PAUSE },
     726    { ACTIVITY_FILTER_FINISHED, NULL, N_("Finished"), NULL },
     727    { ACTIVITY_FILTER_VERIFYING, "Verb", NC_("Verb", "Verifying"), GTK_STOCK_REFRESH },
     728    { ACTIVITY_FILTER_ERROR, NULL, N_("Error"), GTK_STOCK_DIALOG_ERROR }
     729  };
     730
     731  GtkListStore * store = gtk_list_store_new (ACTIVITY_FILTER_N_COLS,
     732                                             G_TYPE_STRING,
     733                                             G_TYPE_INT,
     734                                             G_TYPE_INT,
     735                                             G_TYPE_STRING);
     736  for (i=0, n=G_N_ELEMENTS (types); i<n; ++i)
     737    {
     738      const char * name = types[i].context ? g_dpgettext2 (NULL, types[i].context, types[i].name)
     739                                           : _ (types[i].name);
     740      gtk_list_store_insert_with_values (store, NULL, -1,
     741                                         ACTIVITY_FILTER_COL_NAME, name,
     742                                         ACTIVITY_FILTER_COL_TYPE, types[i].type,
     743                                         ACTIVITY_FILTER_COL_STOCK_ID, types[i].stock_id,
     744                                         -1);
     745    }
     746
     747  g_object_set_qdata (G_OBJECT (store), TORRENT_MODEL_KEY, tmodel);
     748  activity_filter_model_update (store);
     749  return GTK_TREE_MODEL (store);
    728750}
    729751
     
    735757                             gpointer           data UNUSED)
    736758{
    737     int type;
    738     int width;
    739     int ypad;
    740     const gboolean leaf = !gtk_tree_model_iter_has_child (tree_model, iter);
    741 
    742     gtk_tree_model_get (tree_model, iter, ACTIVITY_FILTER_COL_TYPE, &type, -1);
    743     width = type == ACTIVITY_FILTER_ALL ? 0 : 20;
    744     ypad = type == ACTIVITY_FILTER_ALL ? 0 : 2;
    745 
    746     g_object_set (cell_renderer, "width", width,
    747                                  "sensitive", leaf,
    748                                  "ypad", ypad,
    749                                  NULL);
     759  int type;
     760  int width;
     761  int ypad;
     762  const gboolean leaf = !gtk_tree_model_iter_has_child (tree_model, iter);
     763
     764  gtk_tree_model_get (tree_model, iter, ACTIVITY_FILTER_COL_TYPE, &type, -1);
     765  width = type == ACTIVITY_FILTER_ALL ? 0 : 20;
     766  ypad = type == ACTIVITY_FILTER_ALL ? 0 : 2;
     767
     768  g_object_set (cell_renderer, "width", width,
     769                               "sensitive", leaf,
     770                               "ypad", ypad,
     771                               NULL);
    750772}
    751773
     
    753775activity_model_update_idle (gpointer activity_model)
    754776{
    755     GObject * o = G_OBJECT (activity_model);
    756     const gboolean pending = g_object_get_qdata (o, DIRTY_KEY) != NULL;
    757     if (!pending)
    758     {
    759         GSourceFunc func = (GSourceFunc) activity_filter_model_update;
    760         g_object_set_qdata (o, DIRTY_KEY, GINT_TO_POINTER (1));
    761         gdk_threads_add_idle (func, activity_model);
     777  GObject * o = G_OBJECT (activity_model);
     778  const gboolean pending = g_object_get_qdata (o, DIRTY_KEY) != NULL;
     779  if (!pending)
     780    {
     781      GSourceFunc func = (GSourceFunc) activity_filter_model_update;
     782      g_object_set_qdata (o, DIRTY_KEY, GINT_TO_POINTER (1));
     783      gdk_threads_add_idle (func, activity_model);
    762784    }
    763785}
     
    769791                                    gpointer        activity_model)
    770792{
    771     activity_model_update_idle (activity_model);
     793  activity_model_update_idle (activity_model);
    772794}
    773795
     
    777799                                       gpointer        activity_model)
    778800{
    779     activity_model_update_idle (activity_model);
     801  activity_model_update_idle (activity_model);
    780802}
    781803
     
    783805disconnect_activity_model_callbacks (gpointer tmodel, GObject * cat_model)
    784806{
    785     g_signal_handlers_disconnect_by_func (tmodel, activity_torrent_model_row_changed, cat_model);
    786     g_signal_handlers_disconnect_by_func (tmodel, activity_torrent_model_row_deleted_cb, cat_model);
     807  g_signal_handlers_disconnect_by_func (tmodel, activity_torrent_model_row_changed, cat_model);
     808  g_signal_handlers_disconnect_by_func (tmodel, activity_torrent_model_row_deleted_cb, cat_model);
    787809}
    788810
     
    790812activity_combo_box_new (GtkTreeModel * tmodel)
    791813{
    792     GtkWidget * c;
    793     GtkCellRenderer * r;
    794     GtkTreeModel * activity_model;
    795     GtkComboBox * c_combo_box;
    796     GtkCellLayout * c_cell_layout;
    797 
    798     activity_model = activity_filter_model_new (tmodel);
    799     c = gtk_combo_box_new_with_model (activity_model);
    800     c_combo_box = GTK_COMBO_BOX (c);
    801     c_cell_layout = GTK_CELL_LAYOUT (c);
    802     g_object_unref (activity_model);
    803     gtk_combo_box_set_row_separator_func (c_combo_box,
    804                                           activity_is_it_a_separator, NULL, NULL);
    805     gtk_combo_box_set_active (c_combo_box, 0);
    806 
    807     r = gtk_cell_renderer_pixbuf_new ();
    808     gtk_cell_layout_pack_start (c_cell_layout, r, FALSE);
    809     gtk_cell_layout_set_attributes (c_cell_layout, r,
    810                                     "stock-id", ACTIVITY_FILTER_COL_STOCK_ID,
    811                                     NULL);
    812     gtk_cell_layout_set_cell_data_func (c_cell_layout, r,
    813                                         render_activity_pixbuf_func, NULL, NULL);
    814 
    815     r = gtk_cell_renderer_text_new ();
    816     gtk_cell_layout_pack_start (c_cell_layout, r, TRUE);
    817     gtk_cell_layout_set_attributes (c_cell_layout, r,
    818                                     "text", ACTIVITY_FILTER_COL_NAME,
    819                                     NULL);
    820 
    821     r = number_renderer_new ();
    822     gtk_cell_layout_pack_end (c_cell_layout, r, TRUE);
    823     gtk_cell_layout_set_cell_data_func (c_cell_layout, r,
    824                                         render_number_func, NULL, NULL);
    825 
    826     g_object_weak_ref (G_OBJECT (activity_model), disconnect_activity_model_callbacks, tmodel);
    827     g_signal_connect (tmodel, "row-changed", G_CALLBACK (activity_torrent_model_row_changed), activity_model);
    828     g_signal_connect (tmodel, "row-inserted", G_CALLBACK (activity_torrent_model_row_changed), activity_model);
    829     g_signal_connect (tmodel, "row-deleted", G_CALLBACK (activity_torrent_model_row_deleted_cb), activity_model);
    830 
    831     return c;
     814  GtkWidget * c;
     815  GtkCellRenderer * r;
     816  GtkTreeModel * activity_model;
     817  GtkComboBox * c_combo_box;
     818  GtkCellLayout * c_cell_layout;
     819
     820  activity_model = activity_filter_model_new (tmodel);
     821  c = gtk_combo_box_new_with_model (activity_model);
     822  c_combo_box = GTK_COMBO_BOX (c);
     823  c_cell_layout = GTK_CELL_LAYOUT (c);
     824  g_object_unref (activity_model);
     825  gtk_combo_box_set_row_separator_func (c_combo_box,
     826                                        activity_is_it_a_separator, NULL, NULL);
     827  gtk_combo_box_set_active (c_combo_box, 0);
     828
     829  r = gtk_cell_renderer_pixbuf_new ();
     830  gtk_cell_layout_pack_start (c_cell_layout, r, FALSE);
     831  gtk_cell_layout_set_attributes (c_cell_layout, r,
     832                                  "stock-id", ACTIVITY_FILTER_COL_STOCK_ID,
     833                                  NULL);
     834  gtk_cell_layout_set_cell_data_func (c_cell_layout, r,
     835                                      render_activity_pixbuf_func, NULL, NULL);
     836
     837  r = gtk_cell_renderer_text_new ();
     838  gtk_cell_layout_pack_start (c_cell_layout, r, TRUE);
     839  gtk_cell_layout_set_attributes (c_cell_layout, r,
     840                                  "text", ACTIVITY_FILTER_COL_NAME,
     841                                  NULL);
     842
     843  r = number_renderer_new ();
     844  gtk_cell_layout_pack_end (c_cell_layout, r, TRUE);
     845  gtk_cell_layout_set_cell_data_func (c_cell_layout, r,
     846                                      render_number_func, NULL, NULL);
     847
     848  g_object_weak_ref (G_OBJECT (activity_model), disconnect_activity_model_callbacks, tmodel);
     849  g_signal_connect (tmodel, "row-changed", G_CALLBACK (activity_torrent_model_row_changed), activity_model);
     850  g_signal_connect (tmodel, "row-inserted", G_CALLBACK (activity_torrent_model_row_changed), activity_model);
     851  g_signal_connect (tmodel, "row-deleted", G_CALLBACK (activity_torrent_model_row_deleted_cb), activity_model);
     852
     853  return c;
    832854}
    833855
     
    841863testText (const tr_torrent * tor, const char * key)
    842864{
    843     gboolean ret = FALSE;
    844 
    845     if (!key || !*key)
    846     {
    847         ret = TRUE;
    848     }
    849     else
    850     {
    851         tr_file_index_t i;
    852         const tr_info * inf = tr_torrentInfo (tor);
    853 
    854         /* test the torrent name... */
    855         {
    856             char * pch = g_utf8_casefold (tr_torrentName (tor), -1);
    857             ret = !key || strstr (pch, key) != NULL;
    858             g_free (pch);
    859         }
    860 
    861         /* test the files... */
    862         for (i=0; i<inf->fileCount && !ret; ++i)
    863         {
    864             char * pch = g_utf8_casefold (inf->files[i].name, -1);
    865             ret = !key || strstr (pch, key) != NULL;
    866             g_free (pch);
    867         }
    868     }
    869 
    870     return ret;
     865  gboolean ret = FALSE;
     866
     867  if (!key || !*key)
     868    {
     869      ret = TRUE;
     870    }
     871  else
     872    {
     873      tr_file_index_t i;
     874      const tr_info * inf = tr_torrentInfo (tor);
     875
     876      /* test the torrent name... */
     877      {
     878        char * pch = g_utf8_casefold (tr_torrentName (tor), -1);
     879        ret = !key || strstr (pch, key) != NULL;
     880        g_free (pch);
     881      }
     882
     883      /* test the files... */
     884      for (i=0; i<inf->fileCount && !ret; ++i)
     885        {
     886          char * pch = g_utf8_casefold (inf->files[i].name, -1);
     887          ret = !key || strstr (pch, key) != NULL;
     888          g_free (pch);
     889        }
     890    }
     891
     892  return ret;
    871893}
    872894
     
    874896entry_clear (GtkEntry * e)
    875897{
    876     gtk_entry_set_text (e, "");
     898  gtk_entry_set_text (e, "");
    877899}
    878900
     
    880902filter_entry_changed (GtkEditable * e, gpointer filter_model)
    881903{
    882     char * pch;
    883     char * folded;
    884 
    885     pch = gtk_editable_get_chars (e, 0, -1);
    886     folded = g_utf8_casefold (pch, -1);
    887     g_strstrip (folded);
    888     g_object_set_qdata_full (filter_model, TEXT_KEY, folded, g_free);
    889     g_free (pch);
    890 
    891     gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (filter_model));
     904  char * pch;
     905  char * folded;
     906
     907  pch = gtk_editable_get_chars (e, 0, -1);
     908  folded = g_utf8_casefold (pch, -1);
     909  g_strstrip (folded);
     910  g_object_set_qdata_full (filter_model, TEXT_KEY, folded, g_free);
     911  g_free (pch);
     912
     913  gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (filter_model));
    892914}
    893915
     
    900922struct filter_data
    901923{
    902     GtkWidget * activity;
    903     GtkWidget * category;
    904     GtkWidget * entry;
    905     GtkTreeModel * filter_model;
    906     int active_activity_type;
    907     int active_category_type;
    908     char * active_category_host;
     924  GtkWidget * activity;
     925  GtkWidget * category;
     926  GtkWidget * entry;
     927  GtkTreeModel * filter_model;
     928  int active_activity_type;
     929  int active_category_type;
     930  char * active_category_host;
    909931};
    910932
     
    912934is_row_visible (GtkTreeModel * model, GtkTreeIter * iter, gpointer vdata)
    913935{
    914     const char * text;
    915     tr_torrent * tor;
    916     struct filter_data * data = vdata;
    917     GObject * o = G_OBJECT (data->filter_model);
    918 
    919     gtk_tree_model_get (model, iter, MC_TORRENT, &tor, -1);
    920 
    921     text = (const char*) g_object_get_qdata (o, TEXT_KEY);
    922 
    923     return (tor != NULL) && test_category (tor, data->active_category_type, data->active_category_host)
    924                            && test_torrent_activity (tor, data->active_activity_type)
    925                            && testText (tor, text);
     936  const char * text;
     937  tr_torrent * tor;
     938  struct filter_data * data = vdata;
     939  GObject * o = G_OBJECT (data->filter_model);
     940
     941  gtk_tree_model_get (model, iter, MC_TORRENT, &tor, -1);
     942
     943  text = (const char*) g_object_get_qdata (o, TEXT_KEY);
     944
     945  return (tor != NULL) && test_category (tor, data->active_category_type, data->active_category_host)
     946                       && test_torrent_activity (tor, data->active_activity_type)
     947                       && testText (tor, text);
    926948}
    927949
     
    929951selection_changed_cb (GtkComboBox * combo, gpointer vdata)
    930952{
    931     int type;
    932     char * host;
    933     GtkTreeIter iter;
    934     GtkTreeModel * model;
    935     struct filter_data * data = vdata;
    936 
    937     /* set data->active_activity_type from the activity combobox */
    938     combo = GTK_COMBO_BOX (data->activity);
    939     model = gtk_combo_box_get_model (combo);
    940     if (gtk_combo_box_get_active_iter (combo, &iter))
    941         gtk_tree_model_get (model, &iter, ACTIVITY_FILTER_COL_TYPE, &type, -1);
    942     else
    943         type = ACTIVITY_FILTER_ALL;
    944     data->active_activity_type = type;
    945 
    946     /* set the active category type & host from the category combobox */
    947     combo = GTK_COMBO_BOX (data->category);
    948     model = gtk_combo_box_get_model (combo);
    949     if (gtk_combo_box_get_active_iter (combo, &iter)) {
    950         gtk_tree_model_get (model, &iter, CAT_FILTER_COL_TYPE, &type,
    951                                           CAT_FILTER_COL_HOST, &host,
    952                                           -1);
    953     } else {
    954         type = CAT_FILTER_TYPE_ALL;
    955         host = NULL;
    956     }
    957     g_free (data->active_category_host);
    958     data->active_category_host = host;
    959     data->active_category_type = type;
    960 
    961     /* refilter */
    962     gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (data->filter_model));
     953  int type;
     954  char * host;
     955  GtkTreeIter iter;
     956  GtkTreeModel * model;
     957  struct filter_data * data = vdata;
     958
     959  /* set data->active_activity_type from the activity combobox */
     960  combo = GTK_COMBO_BOX (data->activity);
     961  model = gtk_combo_box_get_model (combo);
     962  if (gtk_combo_box_get_active_iter (combo, &iter))
     963    gtk_tree_model_get (model, &iter, ACTIVITY_FILTER_COL_TYPE, &type, -1);
     964  else
     965    type = ACTIVITY_FILTER_ALL;
     966  data->active_activity_type = type;
     967
     968  /* set the active category type & host from the category combobox */
     969  combo = GTK_COMBO_BOX (data->category);
     970  model = gtk_combo_box_get_model (combo);
     971  if (gtk_combo_box_get_active_iter (combo, &iter))
     972    {
     973      gtk_tree_model_get (model, &iter, CAT_FILTER_COL_TYPE, &type,
     974                                        CAT_FILTER_COL_HOST, &host,
     975                                        -1);
     976    }
     977  else
     978    {
     979      type = CAT_FILTER_TYPE_ALL;
     980      host = NULL;
     981    }
     982  g_free (data->active_category_host);
     983  data->active_category_host = host;
     984  data->active_category_type = type;
     985
     986  /* refilter */
     987  gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (data->filter_model));
    963988}
    964989
     
    966991gtr_filter_bar_new (tr_session * session, GtkTreeModel * tmodel, GtkTreeModel ** filter_model)
    967992{
    968     GtkWidget * l;
    969     GtkWidget * w;
    970     GtkWidget * h;
    971     GtkWidget * s;
    972     GtkWidget * activity;
    973     GtkWidget * category;
    974     GtkBox * h_box;
    975     const char * str;
    976     struct filter_data * data;
    977 
    978     g_assert (DIRTY_KEY == 0);
    979     TEXT_KEY = g_quark_from_static_string ("tr-filter-text-key");
    980     DIRTY_KEY = g_quark_from_static_string ("tr-filter-dirty-key");
    981     SESSION_KEY = g_quark_from_static_string ("tr-session-key");
    982     TORRENT_MODEL_KEY = g_quark_from_static_string ("tr-filter-torrent-model-key");
    983 
    984     data = g_new0 (struct filter_data, 1);
    985     data->activity = activity = activity_combo_box_new (tmodel);
    986     data->category = category = category_combo_box_new (tmodel);
    987     data->filter_model = gtk_tree_model_filter_new (tmodel, NULL);
    988 
    989     g_object_set (G_OBJECT (data->category), "width-request", 170, NULL);
    990     g_object_set_qdata (G_OBJECT (gtk_combo_box_get_model (GTK_COMBO_BOX (data->category))), SESSION_KEY, session);
    991 
    992     gtk_tree_model_filter_set_visible_func (
    993         GTK_TREE_MODEL_FILTER (data->filter_model),
    994         is_row_visible, data, g_free);
    995 
    996     g_signal_connect (data->category, "changed", G_CALLBACK (selection_changed_cb), data);
    997     g_signal_connect (data->activity, "changed", G_CALLBACK (selection_changed_cb), data);
    998 
    999 
    1000     h = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, GUI_PAD_SMALL);
    1001     h_box = GTK_BOX (h);
    1002 
    1003     /* add the activity combobox */
    1004     str = _("_Show:");
    1005     w = activity;
    1006     l = gtk_label_new (NULL);
    1007     gtk_label_set_markup_with_mnemonic (GTK_LABEL (l), str);
    1008     gtk_label_set_mnemonic_widget (GTK_LABEL (l), w);
    1009     gtk_box_pack_start (h_box, l, FALSE, FALSE, 0);
    1010     gtk_box_pack_start (h_box, w, TRUE, TRUE, 0);
    1011 
    1012     /* add a spacer */
    1013     w = gtk_alignment_new (0.0f, 0.0f, 0.0f, 0.0f);
    1014     gtk_widget_set_size_request (w, 0u, GUI_PAD_BIG);
    1015     gtk_box_pack_start (h_box, w, FALSE, FALSE, 0);
    1016 
    1017     /* add the category combobox */
    1018     w = category;
    1019     gtk_box_pack_start (h_box, w, TRUE, TRUE, 0);
    1020 
    1021     /* add a spacer */
    1022     w = gtk_alignment_new (0.0f, 0.0f, 0.0f, 0.0f);
    1023     gtk_widget_set_size_request (w, 0u, GUI_PAD_BIG);
    1024     gtk_box_pack_start (h_box, w, FALSE, FALSE, 0);
    1025 
    1026     /* add the entry field */
    1027     s = gtk_entry_new ();
    1028     gtk_entry_set_icon_from_stock (GTK_ENTRY (s), GTK_ENTRY_ICON_SECONDARY, GTK_STOCK_CLEAR);
    1029     g_signal_connect (s, "icon-release", G_CALLBACK (entry_clear), NULL);
    1030     gtk_box_pack_start (h_box, s, TRUE, TRUE, 0);
    1031 
    1032     g_signal_connect (s, "changed", G_CALLBACK (filter_entry_changed), data->filter_model);
    1033     selection_changed_cb (NULL, data);
    1034 
    1035     *filter_model = data->filter_model;
    1036     return h;
    1037 }
     993  GtkWidget * l;
     994  GtkWidget * w;
     995  GtkWidget * h;
     996  GtkWidget * s;
     997  GtkWidget * activity;
     998  GtkWidget * category;
     999  GtkBox * h_box;
     1000  const char * str;
     1001  struct filter_data * data;
     1002
     1003  g_assert (DIRTY_KEY == 0);
     1004  TEXT_KEY = g_quark_from_static_string ("tr-filter-text-key");
     1005  DIRTY_KEY = g_quark_from_static_string ("tr-filter-dirty-key");
     1006  SESSION_KEY = g_quark_from_static_string ("tr-session-key");
     1007  TORRENT_MODEL_KEY = g_quark_from_static_string ("tr-filter-torrent-model-key");
     1008
     1009  data = g_new0 (struct filter_data, 1);
     1010  data->activity = activity = activity_combo_box_new (tmodel);
     1011  data->category = category = category_combo_box_new (tmodel);
     1012  data->filter_model = gtk_tree_model_filter_new (tmodel, NULL);
     1013
     1014  g_object_set (G_OBJECT (data->category), "width-request", 170, NULL);
     1015  g_object_set_qdata (G_OBJECT (gtk_combo_box_get_model (GTK_COMBO_BOX (data->category))), SESSION_KEY, session);
     1016
     1017  gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (data->filter_model),
     1018                                          is_row_visible, data, g_free);
     1019
     1020  g_signal_connect (data->category, "changed", G_CALLBACK (selection_changed_cb), data);
     1021  g_signal_connect (data->activity, "changed", G_CALLBACK (selection_changed_cb), data);
     1022
     1023
     1024  h = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, GUI_PAD_SMALL);
     1025  h_box = GTK_BOX (h);
     1026
     1027  /* add the activity combobox */
     1028  str = _("_Show:");
     1029  w = activity;
     1030  l = gtk_label_new (NULL);
     1031  gtk_label_set_markup_with_mnemonic (GTK_LABEL (l), str);
     1032  gtk_label_set_mnemonic_widget (GTK_LABEL (l), w);
     1033  gtk_box_pack_start (h_box, l, FALSE, FALSE, 0);
     1034  gtk_box_pack_start (h_box, w, TRUE, TRUE, 0);
     1035
     1036  /* add a spacer */
     1037  w = gtk_alignment_new (0.0f, 0.0f, 0.0f, 0.0f);
     1038  gtk_widget_set_size_request (w, 0u, GUI_PAD_BIG);
     1039  gtk_box_pack_start (h_box, w, FALSE, FALSE, 0);
     1040
     1041  /* add the category combobox */
     1042  w = category;
     1043  gtk_box_pack_start (h_box, w, TRUE, TRUE, 0);
     1044
     1045  /* add a spacer */
     1046  w = gtk_alignment_new (0.0f, 0.0f, 0.0f, 0.0f);
     1047  gtk_widget_set_size_request (w, 0u, GUI_PAD_BIG);
     1048  gtk_box_pack_start (h_box, w, FALSE, FALSE, 0);
     1049
     1050  /* add the entry field */
     1051  s = gtk_entry_new ();
     1052  gtk_entry_set_icon_from_stock (GTK_ENTRY (s), GTK_ENTRY_ICON_SECONDARY, GTK_STOCK_CLEAR);
     1053  g_signal_connect (s, "icon-release", G_CALLBACK (entry_clear), NULL);
     1054  gtk_box_pack_start (h_box, s, TRUE, TRUE, 0);
     1055
     1056  g_signal_connect (s, "changed", G_CALLBACK (filter_entry_changed), data->filter_model);
     1057  selection_changed_cb (NULL, data);
     1058
     1059  *filter_model = data->filter_model;
     1060  return h;
     1061}
Note: See TracChangeset for help on using the changeset viewer.