Changeset 1806

Show
Ignore:
Timestamp:
04/20/07 12:41:13
Author:
pvanhoof
Message:

Further implementing tnymergefolder

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/ChangeLog

    r1805 r1806  
     12007-04-20  Philip Van Hoof  <pvanhoof@gnome.org> 
     2 
     3        * Further implementing of TnyMergeFolder 
     4 
    152007-04-18  Philip Van Hoof  <pvanhoof@gnome.org> 
    26 
  • trunk/libtinymail/tny-merge-folder.c

    r1801 r1806  
    4242 
    4343 
     44 
     45 
     46static void 
     47notify_folder_observers_about (TnyFolder *self, TnyFolderChange *change) 
     48{ 
     49        TnyMergeFolderPriv *priv = TNY_MERGE_FOLDER_GET_PRIVATE (self); 
     50        TnyIterator *iter; 
     51 
     52        if (!priv->observers) 
     53                return; 
     54 
     55        g_static_rec_mutex_lock (priv->lock); 
     56 
     57        iter = tny_list_create_iterator (priv->observers); 
     58        while (!tny_iterator_is_done (iter)) 
     59        { 
     60                TnyFolderObserver *observer = TNY_FOLDER_OBSERVER (tny_iterator_get_current (iter)); 
     61                tny_folder_observer_update (observer, change); 
     62                g_object_unref (G_OBJECT (observer)); 
     63                tny_iterator_next (iter); 
     64        } 
     65        g_object_unref (G_OBJECT (iter)); 
     66 
     67        g_static_rec_mutex_unlock (priv->lock); 
     68} 
     69 
     70 
    4471static void 
    4572tny_merge_folder_remove_msg (TnyFolder *self, TnyHeader *header, GError **err) 
     
    171198} 
    172199 
     200/* get_msg & get_msg_async */ 
     201typedef struct  
     202{ 
     203        TnyFolder *self; 
     204        TnyMsg *msg; 
     205        TnyHeader *header; 
     206        GError *err; 
     207        gpointer user_data; 
     208        guint depth; 
     209        TnyGetMsgCallback callback; 
     210} GetMsgInfo; 
     211 
     212static void 
     213get_msg_async_destroyer (gpointer thr_user_data) 
     214{ 
     215        GetMsgInfo *info = (GetMsgInfo *) thr_user_data; 
     216 
     217        /* thread reference */ 
     218        g_object_unref (G_OBJECT (info->self)); 
     219        if (info->msg) 
     220                g_object_unref (G_OBJECT (info->msg)); 
     221 
     222        if (info->err) 
     223                g_error_free (info->err); 
     224 
     225        g_slice_free (GetMsgInfo, info); 
     226} 
     227 
     228static gboolean 
     229get_msg_async_callback (gpointer thr_user_data) 
     230{ 
     231        GetMsgInfo *info = (GetMsgInfo *) thr_user_data; 
     232 
     233        if (info->callback) 
     234                info->callback (info->self, info->msg, &info->err, info->user_data); 
     235 
     236        return FALSE; 
     237} 
     238 
     239 
     240static gpointer  
     241get_msg_async_thread (gpointer thr_user_data) 
     242{ 
     243        GetMsgInfo *info = (GetMsgInfo *) thr_user_data; 
     244        GError *err = NULL; 
     245 
     246        info->msg = tny_folder_get_msg (info->self, info->header, &err); 
     247 
     248        if (err != NULL) 
     249        { 
     250                info->err = g_error_copy ((const GError *) err); 
     251                if (info->msg && G_IS_OBJECT (info->msg)) 
     252                        g_object_unref (G_OBJECT (info->msg)); 
     253                info->msg = NULL; 
     254        } else 
     255                info->err = NULL; 
     256 
     257        g_object_unref (G_OBJECT (info->header)); 
     258 
     259        if (info->callback) 
     260        { 
     261                if (info->depth > 0) 
     262                { 
     263                        g_idle_add_full (G_PRIORITY_HIGH,  
     264                                get_msg_async_callback,  
     265                                info, get_msg_async_destroyer); 
     266                } else { 
     267                        get_msg_async_callback (info); 
     268                        get_msg_async_destroyer (info); 
     269                } 
     270        } else /* thread reference */ 
     271                g_object_unref (G_OBJECT (info->self)); 
     272 
     273        g_thread_exit (NULL); 
     274 
     275        return NULL; 
     276 
     277} 
     278 
    173279static void 
    174280tny_merge_folder_get_msg_async (TnyFolder *self, TnyHeader *header, TnyGetMsgCallback callback, gpointer user_data) 
    175281{ 
     282        GetMsgInfo *info; 
     283        GThread *thread; 
    176284        GError *err = NULL; 
    177         TnyMsg *msg; 
    178  
    179         /* TODO: do this is a thread */ 
    180         msg = tny_merge_folder_get_msg (self, header, &err); 
    181  
    182         if (callback) /* TODO: this is not always on the gmainloop */ 
    183                 callback (self, msg, &err, user_data); 
     285 
     286        info = g_slice_new (GetMsgInfo); 
     287        info->self = self; 
     288        info->header = header; 
     289        info->callback = callback; 
     290        info->user_data = user_data; 
     291        info->depth = g_main_depth (); 
     292 
     293        /* thread reference */ 
     294        g_object_ref (G_OBJECT (info->self)); 
     295        g_object_ref (G_OBJECT (info->header)); 
     296 
     297        thread = g_thread_create (get_msg_async_thread, info, FALSE, NULL); 
     298 
     299        return; 
    184300} 
    185301 
     
    345461} 
    346462 
     463/* refresh & refresh_async */ 
    347464static void 
    348465tny_merge_folder_refresh (TnyFolder *self, GError **err) 
     
    372489} 
    373490 
     491 
     492typedef struct  
     493{ 
     494        TnyFolder *self; 
     495        TnyRefreshFolderCallback callback; 
     496        TnyRefreshFolderStatusCallback status_callback; 
     497        gpointer user_data; 
     498        gboolean cancelled; 
     499        guint depth; 
     500        GError *err; 
     501} RefreshFolderInfo; 
     502 
     503 
     504static void 
     505refresh_async_destroyer (gpointer thr_user_data) 
     506{ 
     507        RefreshFolderInfo *info = thr_user_data; 
     508        TnyFolder *self = info->self; 
     509 
     510        /* thread reference */ 
     511        g_object_unref (G_OBJECT (self)); 
     512        if (info->err) 
     513                g_error_free (info->err); 
     514 
     515        g_slice_free (RefreshFolderInfo, thr_user_data); 
     516 
     517        return; 
     518} 
     519 
     520static gboolean 
     521refresh_async_callback (gpointer thr_user_data) 
     522{ 
     523        RefreshFolderInfo *info = thr_user_data; 
     524        TnyFolder *self = info->self; 
     525 
     526        if (info->callback) 
     527                info->callback (info->self, info->cancelled, &info->err, info->user_data); 
     528 
     529        /* TODO: trigger this change notification 
     530        if (info->oldlen != priv->cached_length || info->oldurlen != priv->unread_length) 
     531        { 
     532                TnyFolderChange *change = tny_folder_change_new (self); 
     533                if (info->oldlen != priv->cached_length) 
     534                        tny_folder_change_set_new_all_count (change, priv->cached_length); 
     535                if (info->oldurlen != priv->unread_length) 
     536                        tny_folder_change_set_new_unread_count (change, priv->unread_length); 
     537                notify_folder_observers_about (self, change); 
     538                g_object_unref (change); 
     539        } */ 
     540 
     541        return FALSE; 
     542} 
     543 
     544 
     545static gpointer  
     546refresh_async_thread (gpointer thr_user_data) 
     547{ 
     548        RefreshFolderInfo *info = thr_user_data; 
     549        TnyFolder *self = info->self; 
     550        TnyMergeFolderPriv *priv = TNY_MERGE_FOLDER_GET_PRIVATE (self); 
     551        TnyIterator *iter; 
     552        GError *err = NULL; 
     553 
     554        g_static_rec_mutex_lock (priv->lock); 
     555 
     556        info->cancelled = FALSE; 
     557 
     558        iter = tny_list_create_iterator (priv->mothers); 
     559        while (!tny_iterator_is_done (iter)) 
     560        { 
     561                TnyFolder *cur = TNY_FOLDER (tny_iterator_get_current (iter)); 
     562 
     563                tny_folder_refresh (cur, &err); 
     564 
     565                /* TODO: Handler err */ 
     566 
     567                /* TODO: Handle progress status callbacks ( info->status_callback ) 
     568                 * you might have to start using refresh_async for that (in a  
     569                 * serialized way, else you'd launch a buch of concurrent threads 
     570                 * and ain't going to be nice, perhaps). */ 
     571 
     572                g_object_unref (cur); 
     573                tny_iterator_next (iter); 
     574        } 
     575        g_object_unref (iter); 
     576 
     577        info->err = NULL; 
     578 
     579        g_static_rec_mutex_unlock (priv->lock); 
     580 
     581        if (info->callback) 
     582        { 
     583                if (info->depth > 0) 
     584                { 
     585                        g_idle_add_full (G_PRIORITY_HIGH,  
     586                                refresh_async_callback,  
     587                                info, refresh_async_destroyer); 
     588                } else { 
     589                        refresh_async_callback (info); 
     590                        refresh_async_destroyer (info); 
     591                } 
     592        } else /* Thread reference */ 
     593                g_object_unref (G_OBJECT (self)); 
     594 
     595        g_thread_exit (NULL); 
     596 
     597        return NULL; 
     598} 
     599 
     600 
    374601static void 
    375602tny_merge_folder_refresh_async (TnyFolder *self, TnyRefreshFolderCallback callback, TnyRefreshFolderStatusCallback status_callback, gpointer user_data) 
    376603{ 
     604        RefreshFolderInfo *info; 
     605        GThread *thread; 
    377606        GError *err = NULL; 
    378607 
    379         /* TODO: do this is a thread */ 
    380         tny_merge_folder_refresh (self, &err); 
    381  
    382         if (callback) /* TODO: this is not always on the gmainloop */ 
    383                 callback (self, FALSE, &err, user_data); 
    384 
    385  
     608        info = g_slice_new (RefreshFolderInfo); 
     609        info->err = NULL; 
     610        info->self = self; 
     611        info->callback = callback; 
     612        info->status_callback = status_callback; 
     613        info->user_data = user_data; 
     614        info->depth = g_main_depth (); 
     615 
     616        /* thread reference */ 
     617        g_object_ref (G_OBJECT (self)); 
     618 
     619        thread = g_thread_create (refresh_async_thread, info, FALSE, NULL); 
     620 
     621        return; 
     622
     623 
     624/* transfer_msgs & transfer_msgs_async */ 
    386625static void 
    387626tny_merge_folder_transfer_msgs (TnyFolder *self, TnyList *header_list, TnyFolder *folder_dst, gboolean delete_originals, GError **err) 
     
    418657} 
    419658 
     659typedef struct 
     660{ 
     661        TnyFolder *self; 
     662        TnyList *header_list; 
     663        TnyFolder *folder_dst; 
     664        gboolean delete_originals; 
     665        TnyTransferMsgsCallback callback; 
     666        gpointer user_data; 
     667        gint depth; 
     668        GError *err; 
     669} TransferMsgsInfo; 
     670 
     671 
     672static void 
     673transfer_msgs_async_destroyer (gpointer thr_user_data) 
     674{ 
     675        TransferMsgsInfo *info = thr_user_data; 
     676 
     677        /* thread reference */ 
     678        g_object_unref (G_OBJECT (info->self)); 
     679        g_object_unref (G_OBJECT (info->folder_dst)); 
     680        g_object_unref (G_OBJECT (info->header_list)); 
     681 
     682        if (info->err) 
     683                g_error_free (info->err); 
     684 
     685        g_slice_free (TransferMsgsInfo, thr_user_data); 
     686 
     687        return; 
     688} 
     689 
     690static gboolean 
     691transfer_msgs_async_callback (gpointer thr_user_data) 
     692{ 
     693        TransferMsgsInfo *info = thr_user_data; 
     694        TnyFolder *self = info->self; 
     695 
     696        if (info->callback) 
     697                info->callback (info->self, &info->err, info->user_data); 
     698 
     699        return FALSE; 
     700} 
     701 
     702 
     703static gpointer  
     704transfer_msgs_async_thread (gpointer thr_user_data) 
     705{ 
     706        TransferMsgsInfo *info = thr_user_data; 
     707        TnyFolder *self = info->self; 
     708        TnyMergeFolderPriv *priv = TNY_MERGE_FOLDER_GET_PRIVATE (self); 
     709        TnyIterator *iter; 
     710 
     711        g_static_rec_mutex_lock (priv->lock); 
     712        tny_merge_folder_transfer_msgs (info->self, info->header_list, info->folder_dst, info->delete_originals, &info->err); 
     713        g_static_rec_mutex_unlock (priv->lock); 
     714 
     715        if (info->callback) 
     716        { 
     717                if (info->depth > 0) 
     718                { 
     719                        g_idle_add_full (G_PRIORITY_HIGH,  
     720                                transfer_msgs_async_callback,  
     721                                info, transfer_msgs_async_destroyer); 
     722                } else { 
     723                        transfer_msgs_async_callback (info); 
     724                        transfer_msgs_async_destroyer (info); 
     725                } 
     726        } else  { /* Thread reference */ 
     727                g_object_unref (G_OBJECT (info->self)); 
     728                g_object_unref (G_OBJECT (info->folder_dst)); 
     729                g_object_unref (G_OBJECT (info->header_list)); 
     730        } 
     731 
     732        g_thread_exit (NULL); 
     733 
     734        return NULL; 
     735} 
     736 
    420737static void 
    421738tny_merge_folder_transfer_msgs_async (TnyFolder *self, TnyList *header_list, TnyFolder *folder_dst, gboolean delete_originals, TnyTransferMsgsCallback callback, gpointer user_data) 
    422739{ 
    423         GError *err = NULL; 
    424  
    425         /* TODO: do this is a thread */ 
    426         tny_merge_folder_transfer_msgs (self, header_list, folder_dst, delete_originals, &err); 
    427  
    428         if (callback)   /* TODO call the callback in gmainloop */ 
    429                 callback (self, &err, user_data); 
    430  
    431 
    432  
     740        TransferMsgsInfo *info; 
     741        GThread *thread; 
     742 
     743        info = g_slice_new (TransferMsgsInfo); 
     744        info->err = NULL; 
     745        info->self = self; 
     746        info->callback = callback; 
     747        info->header_list = header_list; 
     748        info->user_data = user_data; 
     749        info->depth = g_main_depth (); 
     750        info->delete_originals = delete_originals; 
     751        info->folder_dst = folder_dst; 
     752        info->err = NULL; 
     753 
     754        /* thread reference */ 
     755        g_object_ref (G_OBJECT (self)); 
     756        g_object_ref (G_OBJECT (folder_dst)); 
     757        g_object_ref (G_OBJECT (header_list)); 
     758 
     759        thread = g_thread_create (transfer_msgs_async_thread, info, FALSE, NULL); 
     760 
     761        return; 
     762
     763 
     764 
     765/* copy */ 
    433766static TnyFolder* 
    434767tny_merge_folder_copy (TnyFolder *self, TnyFolderStore *into, const gchar *new_name, gboolean del, GError **err) 
     
    591924tny_merge_folder_update (TnyFolderObserver *self, TnyFolderChange *change) 
    592925{ 
    593         TnyMergeFolderPriv *priv = TNY_MERGE_FOLDER_GET_PRIVATE (self); 
    594  
    595         g_static_rec_mutex_lock (priv->lock); 
    596  
    597         if (priv->observers) 
    598         { 
    599                 TnyIterator *iter = tny_list_create_iterator (priv->observers); 
    600                 while (!tny_iterator_is_done (iter)) 
    601                 { 
    602                         TnyFolderObserver *observer = TNY_FOLDER_OBSERVER (tny_iterator_get_current (iter)); 
    603                         tny_folder_observer_update (observer, change); 
    604                         g_object_unref (observer); 
    605                         tny_iterator_next (iter); 
    606                 } 
    607                 g_object_unref (iter); 
    608         } 
    609  
    610         g_static_rec_mutex_unlock (priv->lock); 
     926        notify_folder_observers_about (TNY_FOLDER (self), change); 
    611927} 
    612928 
  • trunk/tests/c-demo/tny-demoui-summary-view.c

    r1789 r1806  
    434434        if (!cancelled) 
    435435        { 
     436                GtkSelectionMode mode; 
     437 
    436438                g_idle_add (cleanup_statusbar, priv); 
    437439 
    438                 gtk_tree_selection_get_selected (priv->mailbox_select, &select_model,  
    439                         &priv->last_mailbox_correct_select); 
    440                 priv->last_mailbox_correct_select_set = TRUE; 
     440                mode = gtk_tree_selection_get_mode (priv->mailbox_select); 
     441 
     442                if (mode == GTK_SELECTION_SINGLE) 
     443                { 
     444                        gtk_tree_selection_get_selected (priv->mailbox_select, &select_model,  
     445                                &priv->last_mailbox_correct_select); 
     446                        priv->last_mailbox_correct_select_set = TRUE; 
     447                } 
    441448 
    442449                gtk_widget_set_sensitive (GTK_WIDGET (priv->header_view), TRUE); 
     
    444451        } else { 
    445452                /* Restore selection */ 
    446  
    447453                g_signal_handler_block (G_OBJECT (priv->mailbox_select),  
    448454                        priv->mailbox_select_sid); 
     
    493499 
    494500        mode = gtk_tree_selection_get_mode (selection); 
     501 
     502        g_mutex_lock (priv->monitor_lock); 
     503        { 
     504                if (priv->monitor) 
     505                { 
     506                        tny_folder_monitor_stop (priv->monitor); 
     507                        g_object_unref (G_OBJECT (priv->monitor)); 
     508                } 
     509        } 
     510        g_mutex_unlock (priv->monitor_lock); 
    495511 
    496512        if (mode == GTK_SELECTION_SINGLE) 
     
    533549                        g_mutex_lock (priv->monitor_lock); 
    534550                        { 
    535  
    536                                 if (priv->monitor) 
    537                                 { 
    538                                         tny_folder_monitor_stop (priv->monitor); 
    539                                         g_object_unref (G_OBJECT (priv->monitor)); 
    540                                 } 
    541  
    542551                                priv->monitor = TNY_FOLDER_MONITOR (tny_folder_monitor_new (folder)); 
    543552                                tny_folder_monitor_add_list (priv->monitor, TNY_LIST (hmodel)); 
     
    560569                        set_header_view_model (header_view, sortable); 
    561570 
    562 #ifdef ASYNC_HEADERS 
    563571                        tny_folder_refresh_async (folder,  
    564572                                refresh_current_folder,  
    565573                                refresh_current_folder_status_update, user_data); 
    566 #else 
    567                         refresh_current_folder (folder, FALSE, NULL, user_data); 
    568 #endif 
     574 
    569575 
    570576                        g_object_unref (G_OBJECT (folder)); 
     
    603609                        merge, FALSE); 
    604610 
     611                g_mutex_lock (priv->monitor_lock); 
     612                { 
     613                        priv->monitor = TNY_FOLDER_MONITOR (tny_folder_monitor_new (merge)); 
     614                        tny_folder_monitor_add_list (priv->monitor, TNY_LIST (hmodel)); 
     615                        tny_folder_monitor_start (priv->monitor); 
     616                } 
     617                g_mutex_unlock (priv->monitor_lock); 
    605618 
    606619                sortable = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (hmodel)); 
     
    617630 
    618631                set_header_view_model (header_view, sortable); 
     632 
     633                tny_folder_refresh_async (merge,  
     634                        refresh_current_folder,  
     635                        refresh_current_folder_status_update, user_data); 
    619636 
    620637                g_list_free (list);