Changeset 1746
- Timestamp:
- 03/25/07 13:55:19
- Files:
-
- trunk/ChangeLog (modified) (1 diff)
- trunk/libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-folder.c (modified) (6 diffs)
- trunk/libtinymail-camel/tny-camel-folder.c (modified) (2 diffs)
- trunk/libtinymailui-gtk/tny-gtk-header-list-model.c (modified) (17 diffs)
- trunk/tests/c-demo/tny-demoui-summary-view.c (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/ChangeLog
r1743 r1746 1 2007-03-25 Philip Van Hoof <pvanhoof@gnome.org> 2 3 * Support for filling up the header view (a.k.a. the summary view) 4 with already or recently downloaded information while downloading is 5 taking place. Take a look at the demo user interface's code to learn 6 how to leverage this feature: You basically need to register the list 7 (which will for example be a TnyGtkHeaderListModel instance) with the 8 TnyFolderMonitor before launching the tny_folder_refresh_async method. 9 10 * This ain't an API change, but this new feature does make more 11 possible with the same API. It might also change behaviour a little 12 bit (although it shouldn't for the old-style of using the TnyFolderMonitor, 13 or at least not as far as I know and tested). 14 1 15 2007-03-23 Philip Van Hoof <pvanhoof@gnome.org> 2 16 trunk/libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-folder.c
r1743 r1746 2977 2977 gboolean did_hack = FALSE; 2978 2978 gint hcnt = 0; 2979 CamelFolderChangeInfo *mchanges; 2979 2980 2980 2981 imap_folder->need_rescan = TRUE; … … 3081 3082 qsort (needheaders->pdata, needheaders->len, 3082 3083 sizeof (void *), uid_compar); 3084 3085 mchanges = camel_folder_change_info_new (); 3083 3086 3084 3087 while (uid < needheaders->len) … … 3150 3153 for (r = curlen-1; r >= sequence -1; r--) 3151 3154 { 3152 printf ("curlen=%d, r=%d, seq=%d\n", curlen, r, sequence);3155 g_warning ("Problem with your local summary store (too much), correcting: curlen=%d, r=%d, seq=%d\n", curlen, r, sequence); 3153 3156 CamelMessageInfo *ri = g_ptr_array_index (folder->summary->messages, r); 3154 3157 if (ri) { 3155 3156 /* CamelFolderChangeInfo *uchange = camel_folder_change_info_new (); 3157 camel_folder_change_info_remove_uid (uchange, camel_message_info_uid (mi)); 3158 if (camel_folder_change_info_changed (uchange)) 3159 camel_object_trigger_event (CAMEL_OBJECT (folder), "folder_changed", uchange); 3160 camel_folder_change_info_free (uchange); */ 3161 3158 /* camel_folder_change_info_remove_uid (mchange, camel_message_info_uid (mi)); */ 3162 3159 ((CamelMessageInfoBase*)ri)->flags |= CAMEL_MESSAGE_EXPUNGED; 3163 3160 ((CamelMessageInfoBase*)ri)->flags |= CAMEL_MESSAGE_FREED; … … 3169 3166 { 3170 3167 CamelMessageInfo *ni = camel_message_info_clone (mi); 3171 if (ni) 3168 if (ni) { 3169 g_warning ("Problem with your local summary store (too few), correcting: curlen=%d, r=%d, seq=%d\n", curlen, r, sequence); 3172 3170 camel_folder_summary_add (folder->summary, (CamelMessageInfo *)ni); 3171 /* camel_folder_change_info_add_uid (mchanges, camel_message_info_uid (ni)); */ 3172 } 3173 3173 } 3174 3174 } … … 3177 3177 3178 3178 camel_folder_summary_add (folder->summary, (CamelMessageInfo *)mi); 3179 camel_folder_change_info_add_uid (changes, camel_message_info_uid (mi)); 3179 3180 /* printf ("Change: %s!\n", camel_message_info_uid (mi)); */ 3181 camel_folder_change_info_add_uid (mchanges, camel_message_info_uid (mi)); 3180 3182 if ((mi->info.flags & CAMEL_IMAP_MESSAGE_RECENT)) 3181 camel_folder_change_info_recent_uid( changes, camel_message_info_uid (mi));3183 camel_folder_change_info_recent_uid(mchanges, camel_message_info_uid (mi)); 3182 3184 } 3183 3185 … … 3211 3213 3212 3214 } 3215 3216 3217 if (camel_folder_change_info_changed (mchanges)) { 3218 camel_object_trigger_event (CAMEL_OBJECT (folder), "folder_changed", mchanges); 3219 /* printf ("Changes!\n"); */ 3220 } 3221 camel_folder_change_info_free (mchanges); 3222 3213 3223 } 3214 3224 trunk/libtinymail-camel/tny-camel-folder.c
r1737 r1746 134 134 gboolean need_unread_sync; 135 135 136 /* printf ("want changes: %s, have folder: %s\n", 137 priv->want_changes?"yes":"no", 138 priv->folder?"yes":"no"); 139 136 140 if (!priv->want_changes) 137 return; 141 return; */ 138 142 139 143 g_static_rec_mutex_lock (priv->folder_lock); … … 145 149 146 150 summary = priv->folder->summary; 151 152 /* printf ("%d added\n", info->uid_added?info->uid_added->len:-1); */ 147 153 148 154 for (i = 0; i< info->uid_added->len; i++) trunk/libtinymailui-gtk/tny-gtk-header-list-model.c
r1740 r1746 94 94 g_return_val_if_fail (gtk_tree_path_get_depth (path) > 0, FALSE); 95 95 96 g_mutex_lock (list_model->folder_lock);97 96 g_static_rec_mutex_lock (list_model->iterator_lock); 98 97 … … 112 111 113 112 g_static_rec_mutex_unlock (list_model->iterator_lock); 114 g_mutex_unlock (list_model->folder_lock);115 113 116 114 return retval; … … 125 123 126 124 /* Return the path of an existing GtkTreeIter */ 127 128 125 if (!(iter->stamp == TNY_GTK_HEADER_LIST_MODEL (self)->stamp)) 129 126 return NULL; 130 127 131 g_mutex_lock (list_model->folder_lock);132 128 g_static_rec_mutex_lock (list_model->iterator_lock); 133 129 … … 136 132 if (i < 0 || i >= list_model->items->len) { 137 133 g_static_rec_mutex_unlock (list_model->iterator_lock); 138 g_mutex_unlock (list_model->folder_lock);139 134 return NULL; 140 135 } … … 144 139 145 140 g_static_rec_mutex_unlock (list_model->iterator_lock); 146 g_mutex_unlock (list_model->folder_lock);147 141 148 142 return tree_path; … … 234 228 return; 235 229 236 g_mutex_lock (list_model->folder_lock);237 230 g_static_rec_mutex_lock (list_model->iterator_lock); 238 231 … … 317 310 318 311 g_static_rec_mutex_unlock (list_model->iterator_lock); 319 g_mutex_unlock (list_model->folder_lock);320 312 321 313 return; … … 332 324 return FALSE; 333 325 334 g_mutex_lock (list_model->folder_lock);335 326 g_static_rec_mutex_lock (list_model->iterator_lock); 336 327 … … 347 338 348 339 g_static_rec_mutex_unlock (list_model->iterator_lock); 349 g_mutex_unlock (list_model->folder_lock);350 340 351 341 return retval; … … 368 358 return the full length. */ 369 359 370 g_mutex_lock (list_model->folder_lock);371 360 g_static_rec_mutex_lock (list_model->iterator_lock); 372 361 … … 375 364 376 365 g_static_rec_mutex_unlock (list_model->iterator_lock); 377 g_mutex_unlock (list_model->folder_lock);378 366 379 367 return retval; … … 389 377 return FALSE; 390 378 391 g_mutex_lock (list_model->folder_lock);392 379 g_static_rec_mutex_lock (list_model->iterator_lock); 393 380 … … 403 390 404 391 g_static_rec_mutex_unlock (list_model->iterator_lock); 405 g_mutex_unlock (list_model->folder_lock);406 392 407 393 return retval; … … 427 413 428 414 415 typedef struct 416 { 417 TnyGtkHeaderListModel *self; 418 GtkTreePath *path; 419 GtkTreeIter iter; 420 } notify_views_data_t; 421 422 static gboolean 423 notify_views (gpointer data) 424 { 425 notify_views_data_t *stuff = data; 426 427 gtk_tree_model_row_inserted (GTK_TREE_MODEL (stuff->self), stuff->path, &(stuff->iter)); 428 gtk_tree_path_free (stuff->path); 429 g_object_unref (G_OBJECT (stuff->self)); 430 g_slice_free (notify_views_data_t, data); 431 432 return FALSE; 433 } 434 429 435 static void 430 436 tny_gtk_header_list_model_prepend (TnyList *self, GObject* item) … … 432 438 TnyGtkHeaderListModel *me = (TnyGtkHeaderListModel*)self; 433 439 GtkTreePath *path; 434 GtkTreeIter iter;440 notify_views_data_t *stuff; 435 441 436 442 g_static_rec_mutex_lock (me->iterator_lock); 437 443 438 path = gtk_tree_path_new (); 439 gtk_tree_path_append_index (path, 0); 440 iter.stamp = me->stamp; 444 stuff = g_slice_new (notify_views_data_t); 445 stuff->self = g_object_ref (G_OBJECT (self)); 446 stuff->path = gtk_tree_path_new (); 447 gtk_tree_path_append_index (stuff->path, 0); 448 stuff->iter.stamp = me->stamp; 441 449 442 450 /* Prepend something to the list */ 443 444 451 g_object_ref (G_OBJECT (item)); 445 452 g_ptr_array_add (me->items, item); 446 iter.user_data = (gpointer) (me->items->len - 1); 447 448 /* Letting the observers know about this (the GtkTreeView) */ 449 gtk_tree_model_row_inserted (GTK_TREE_MODEL (me), path, &iter); 450 gtk_tree_path_free (path); 453 stuff->iter.user_data = (gpointer) (me->items->len - 1); 454 455 /* Letting the model observers know about this (the GtkTreeViews). The 456 * g_timeout_add stuff keeps it possible to launch the prepender in a 457 * thread. Else wouldn't the GtkTreeViews like this. */ 458 459 if (stuff->path) 460 g_timeout_add (0, notify_views, stuff); 461 else { 462 g_object_unref (G_OBJECT (stuff->self)); 463 g_slice_free (notify_views_data_t, stuff); 464 } 451 465 452 466 g_static_rec_mutex_unlock (me->iterator_lock); … … 479 493 { 480 494 TnyGtkHeaderListModel *me = (TnyGtkHeaderListModel*)self; 481 GtkTreePath *path ;495 GtkTreePath *path = NULL; 482 496 gint i; gboolean found = FALSE; 483 497 … … 502 516 iter.user_data = (gpointer) i; 503 517 path = tny_gtk_header_list_model_get_path (GTK_TREE_MODEL (me), &iter); 518 if (path) 519 { 520 /* Letting the observers know about this (the GtkTreeView) */ 521 gtk_tree_model_row_deleted (GTK_TREE_MODEL (me), path); 522 gtk_tree_path_free (path); 523 } 504 524 g_ptr_array_remove (me->items, item); 505 /* Letting the observers know about this (the GtkTreeView) */ 506 gtk_tree_model_row_deleted (GTK_TREE_MODEL (me), path); 507 gtk_tree_path_free (path); 508 } 525 } 526 527 g_static_rec_mutex_unlock (me->iterator_lock); 509 528 510 529 g_object_unref (G_OBJECT (item)); 511 530 512 g_static_rec_mutex_unlock (me->iterator_lock);513 531 } 514 532 trunk/tests/c-demo/tny-demoui-summary-view.c
r1677 r1746 264 264 TnyDevice *device = tny_account_store_get_device (account_store); 265 265 266 if (G_UNLIKELY (priv->account_store)) 267 { /* You typically set it once, so unlikely */ 268 266 if (priv->account_store) 267 { 269 268 TnyDevice *odevice = tny_account_store_get_device (priv->account_store); 270 269 … … 434 433 { 435 434 TnyDemouiSummaryViewPriv *priv = user_data; 435 GtkTreeModel *select_model; 436 436 437 437 if (!cancelled) 438 438 { 439 GtkTreeView *header_view = GTK_TREE_VIEW (priv->header_view);440 GtkTreeModel *sortable;441 GtkTreeModel *select_model;442 GtkTreeModel *model = tny_gtk_header_list_model_new ();443 gboolean refresh = FALSE;444 445 #ifndef ASYNC_HEADERS446 refresh = TRUE;447 #endif448 449 tny_gtk_header_list_model_set_folder (TNY_GTK_HEADER_LIST_MODEL (model), folder, refresh);450 sortable = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (model));451 452 gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (sortable),453 TNY_GTK_HEADER_LIST_MODEL_DATE_RECEIVED_COLUMN,454 tny_gtk_header_list_model_received_date_sort_func,455 NULL, NULL);456 457 gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (sortable),458 TNY_GTK_HEADER_LIST_MODEL_DATE_SENT_COLUMN,459 tny_gtk_header_list_model_sent_date_sort_func,460 NULL, NULL);461 462 g_mutex_lock (priv->monitor_lock);463 {464 465 if (priv->monitor)466 {467 tny_folder_monitor_stop (priv->monitor);468 g_object_unref (G_OBJECT (priv->monitor));469 }470 471 priv->monitor = TNY_FOLDER_MONITOR (tny_folder_monitor_new (folder));472 tny_folder_monitor_add_list (priv->monitor, TNY_LIST (model));473 tny_folder_monitor_start (priv->monitor);474 }475 g_mutex_unlock (priv->monitor_lock);476 477 set_header_view_model (header_view, sortable);478 479 439 g_idle_add (cleanup_statusbar, priv); 480 440 … … 525 485 GtkTreeIter iter; 526 486 GtkTreeModel *model; 487 GtkTreeModel *hmodel; 488 GtkTreeView *header_view = GTK_TREE_VIEW (priv->header_view); 489 GtkTreeModel *sortable; 490 gboolean refresh = FALSE; 491 492 #ifndef ASYNC_HEADERS 493 refresh = TRUE; 494 #endif 495 527 496 528 497 if (gtk_tree_selection_get_selected (selection, &model, &iter)) … … 557 526 gtk_widget_show (GTK_WIDGET (priv->progress)); 558 527 gtk_widget_set_sensitive (GTK_WIDGET (priv->header_view), FALSE); 559 528 529 hmodel = tny_gtk_header_list_model_new (); 530 tny_gtk_header_list_model_set_folder (TNY_GTK_HEADER_LIST_MODEL (hmodel), folder, FALSE); 531 532 g_mutex_lock (priv->monitor_lock); 533 { 534 535 if (priv->monitor) 536 { 537 tny_folder_monitor_stop (priv->monitor); 538 g_object_unref (G_OBJECT (priv->monitor)); 539 } 540 541 priv->monitor = TNY_FOLDER_MONITOR (tny_folder_monitor_new (folder)); 542 tny_folder_monitor_add_list (priv->monitor, TNY_LIST (hmodel)); 543 tny_folder_monitor_start (priv->monitor); 544 } 545 g_mutex_unlock (priv->monitor_lock); 546 547 sortable = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (hmodel)); 548 549 gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (sortable), 550 TNY_GTK_HEADER_LIST_MODEL_DATE_RECEIVED_COLUMN, 551 tny_gtk_header_list_model_received_date_sort_func, 552 NULL, NULL); 553 554 gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (sortable), 555 TNY_GTK_HEADER_LIST_MODEL_DATE_SENT_COLUMN, 556 tny_gtk_header_list_model_sent_date_sort_func, 557 NULL, NULL); 558 559 set_header_view_model (header_view, sortable); 560 560 561 #ifdef ASYNC_HEADERS 561 562 562 tny_folder_refresh_async (folder, 563 563 refresh_current_folder, … … 566 566 refresh_current_folder (folder, FALSE, NULL, user_data); 567 567 #endif 568 568 569 569 g_object_unref (G_OBJECT (folder)); 570 570 }
