Changeset 3775

Show
Ignore:
Timestamp:
10/09/08 18:35:07
Author:
pvanhoof
Message:

Approved patches by Rob Taylor

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/ChangeLog

    r3767 r3775  
     12008-09-23  Rob Taylor  <rob.taylor@codethink.co.uk> 
     2 
     3        * libtinymailui-gtk/tny-gtk-folder-store-tree-model.c: 
     4        * tests/c-demo/tny-demoui-summary-view.c: (recurse_poke), 
     5        * tests/functional/account-refresh.c: (recurse_folders), 
     6        * tests/functional/folder-lister-async.c: (callback), (dance): 
     7        * tests/functional/folder-lister.c: (recurse_folders): 
     8        * tests/functional/folder-remove.c: (recurse_folders): 
     9        * tests/functional/folder-transfer.c: (recurse_folders): 
     10        * tests/functional/msg-transfer.c: (find_folders): 
     11        * tests/memory/memory-test.c: (main): 
     12        Change all usage of tny_folder_store_get_folders over to the new api 
     13 
     142008-09-23  Rob Taylor  <rob.taylor@codethink.co.uk> 
     15 
     16        * libtinymail-camel/tny-camel-folder.c: 
     17        * libtinymail-camel/tny-camel-folder.h: 
     18        * libtinymail-camel/tny-camel-store-account.c: 
     19        * libtinymail-camel/tny-camel-store-account.h: 
     20        * libtinymail/tny-combined-account.c: 
     21        * libtinymail/tny-folder-store.c: (tny_folder_store_get_folders), 
     22        * libtinymail/tny-folder-store.h: 
     23        * libtinymail/tny-shared.h: 
     24        Give tny_folder_store_get_folders a refresh parameter, for optionally not refreshing from the server. 
     25        Add tny_folder_store_refresh_async that will asynchronously refresh the store from the server, emitting TnyFolderStoreChanged events to observers. 
     26        Implement it all for camel. 
     27 
     282008-09-23  Rob Taylor  <rob.taylor@codethink.co.uk> 
     29        * libtinymail-camel/tny-camel-folder.c: 
     30        * libtinymail-camel/tny-camel-store-account.c: 
     31        Notify observers about existing folders when they're attached. 
     32 
     332008-09-23  Rob Taylor  <rob.taylor@codethink.co.uk> 
     34 
     35        * libtinymail-camel/tny-camel-folder-priv.h: 
     36        * libtinymail-camel/tny-camel-folder.c: 
     37        * libtinymail-camel/tny-camel-store-account-priv.h: 
     38        * libtinymail-camel/tny-camel-store-account.c: 
     39        * libtinymail/tny-folder-store-change.c: 
     40        * libtinymail/tny-folder-store-change.h: 
     41        New observer behaviour. Observers will get folders_appeared events when a 
     42        tny_folder_store_refresh or tny_folder_store_get_folders occurs and the cache 
     43        is loaded for the first time. They get folders_created events when a new folder 
     44        appears that we didn't know about before. 
     45 
    1462008-09-23  Rob Taylor  <rob.taylor@codethink.co.uk> 
    247 
  • trunk/libtinymail-camel/tny-camel-account.c

    r3726 r3775  
    18721872} 
    18731873 
     1874 
     1875/** 
     1876 * tny_camel_account_stop: 
     1877 * @self: a #TnyCamelAccount object 
     1878 * @callback: a callback when the account has stopped all operations 
     1879 * @user_data: user data for the callback 
     1880 * 
     1881 * Request a stop of all operations on an account 
     1882 * @callback will be called with @user_data when all operations have stopped. 
     1883 * The account will be unusable after calling this function. 
     1884 **/ 
     1885void 
     1886tny_camel_account_stop (TnyCamelAccount *self, TnyCamelAccountStopCallback callback, gpointer user_data) 
     1887{ 
     1888        TNY_CAMEL_ACCOUNT_GET_CLASS (self)->stop(self, callback, user_data); 
     1889} 
     1890 
     1891void 
     1892tny_camel_account_stop_default (TnyCamelAccount *self, TnyCamelAccountStopCallback callback, gpointer user_data) 
     1893{ 
     1894        TnyCamelAccountPriv *priv = TNY_CAMEL_ACCOUNT_GET_PRIVATE (self); 
     1895        _tny_camel_queue_stop (priv->queue, callback, user_data); 
     1896} 
     1897 
    18741898static gboolean 
    18751899tny_camel_account_is_ready (TnyAccount *self) 
     
    21992223        g_static_rec_mutex_unlock (priv->service_lock); 
    22002224 
     2225        _tny_camel_queue_stop (priv->queue, NULL, NULL); 
    22012226        g_object_unref (priv->queue); 
    22022227        g_object_unref (priv->con_strat); 
     
    23192344 
    23202345        class->set_online= tny_camel_account_set_online_default; 
     2346        class->stop = tny_camel_account_stop_default; 
    23212347 
    23222348        object_class->finalize = tny_camel_account_finalize; 
  • trunk/libtinymail-camel/tny-camel-account.h

    r3610 r3775  
    3333#define TNY_CAMEL_ACCOUNT_CLASS(vtable)    (G_TYPE_CHECK_CLASS_CAST ((vtable), TNY_TYPE_CAMEL_ACCOUNT, TnyCamelAccountClass)) 
    3434#define TNY_IS_CAMEL_ACCOUNT(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TNY_TYPE_CAMEL_ACCOUNT)) 
    35 #define TNY_IS_ACAMEL_CCOUNT_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE ((vtable), TNY_TYPE_CAMEL_ACCOUNT)) 
     35#define TNY_IS_CAMEL_ACCOUNT_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE ((vtable), TNY_TYPE_CAMEL_ACCOUNT)) 
    3636#define TNY_CAMEL_ACCOUNT_GET_CLASS(inst)  (G_TYPE_INSTANCE_GET_CLASS ((inst), TNY_TYPE_CAMEL_ACCOUNT, TnyCamelAccountClass)) 
    3737 
     
    5151typedef void (*TnyCamelSetOnlineCallback) (TnyCamelAccount *account, gboolean canceled, GError *err, gpointer user_data); 
    5252 
     53typedef void (*TnyCamelAccountStopCallback) (gpointer user_data); 
    5354 
    5455struct _TnyCamelAccount 
     
    9596 
    9697        void (*set_online) (TnyCamelAccount *self, gboolean online, TnyCamelSetOnlineCallback callback, gpointer user_data); 
     98        void (*stop) (TnyCamelAccount *self, TnyCamelAccountStopCallback callback, gpointer user_data); 
    9799 
    98100        /* Abstract methods */ 
     
    116118void tny_camel_account_get_supported_secure_authentication(TnyCamelAccount *self, TnyCamelGetSupportedSecureAuthCallback callback, TnyStatusCallback status_callback, gpointer user_data); 
    117119 
     120void tny_camel_account_stop (TnyCamelAccount *self, TnyCamelAccountStopCallback callback, gpointer user_data); 
    118121G_END_DECLS 
    119122 
  • trunk/libtinymail-camel/tny-camel-folder-priv.h

    r3687 r3775  
    5555        GList *obs, *sobs; 
    5656        gboolean cant_reuse_iter; 
     57        GHashTable *known_folders; 
    5758}; 
    5859 
  • trunk/libtinymail-camel/tny-camel-folder.c

    r3754 r3775  
    15331533} 
    15341534#endif 
     1535 
     1536static void 
     1537known_folder_del (gpointer user_data, GObject *folder) 
     1538{ 
     1539        TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (user_data); 
     1540        g_hash_table_remove (priv->known_folders, folder); 
     1541} 
     1542 
     1543 
     1544static gboolean 
     1545known_folder_remover (GObject *folder, 
     1546                      gpointer value, 
     1547                      TnyCamelFolder *self) 
     1548{ 
     1549        g_object_weak_unref (folder, known_folder_del, self); 
     1550        return TRUE; 
     1551} 
    15351552 
    15361553void 
     
    31773194                TnyIterator *iter; 
    31783195 
    3179                 tny_folder_store_get_folders (TNY_FOLDER_STORE (folder), folders, NULL, &nerr); 
     3196                tny_folder_store_get_folders (TNY_FOLDER_STORE (folder), folders, NULL, TRUE, &nerr); 
    31803197 
    31813198                if (nerr != NULL) 
     
    33493366 
    33503367        list = func (list, cpy_event_new (TNY_FOLDER_STORE (into), folder)); 
    3351         tny_folder_store_get_folders (TNY_FOLDER_STORE (folder), folders, NULL, NULL); 
     3368        tny_folder_store_get_folders (TNY_FOLDER_STORE (folder), folders, NULL, TRUE, NULL); 
    33523369        iter = tny_list_create_iterator (folders); 
    33533370        while (!tny_iterator_is_done (iter)) 
     
    48854902                TnyIterator *iter; 
    48864903 
    4887                 tny_folder_store_get_folders (TNY_FOLDER_STORE (folder),  
    4888                                 folders, NULL, &nerr); 
     4904                tny_folder_store_get_folders (TNY_FOLDER_STORE (folder), 
     4905                                folders, NULL, TRUE, &nerr); 
    48894906 
    48904907                if (nerr != NULL) 
     
    50335050 
    50345051        _tny_camel_folder_set_name (folder, info->name); 
    5035         _tny_camel_folder_set_iter (folder, info); 
    50365052 
    50375053        if (TNY_IS_CAMEL_FOLDER (self)) { 
     
    50425058        } 
    50435059 
     5060        _tny_camel_folder_set_iter (folder, info); 
    50445061        _tny_camel_folder_set_parent (folder, self); 
    50455062} 
     
    53105327} 
    53115328 
    5312 void  
    5313 _tny_camel_folder_set_iter (TnyCamelFolder *folder, CamelFolderInfo *iter) 
    5314 { 
    5315         TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (folder); 
     5329void 
     5330_tny_camel_folder_set_iter (TnyCamelFolder *self, CamelFolderInfo *iter) 
     5331{ 
     5332        TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (self); 
    53165333 
    53175334        priv->cant_reuse_iter = FALSE; 
     
    53255342        priv->iter_parented = TRUE; 
    53265343 
    5327         return; 
    5328 
    5329  
    5330 static void 
    5331 tny_camel_folder_get_folders (TnyFolderStore *self, TnyList *list, TnyFolderStoreQuery *query, GError **err) 
    5332 
    5333         TNY_CAMEL_FOLDER_GET_CLASS (self)->get_folders(self, list, query, err); 
    5334 
    5335  
    5336 static void  
    5337 tny_camel_folder_get_folders_default (TnyFolderStore *self, TnyList *list, TnyFolderStoreQuery *query, GError **err) 
    5338 
    5339         gboolean cant_reuse_iter = TRUE; 
    5340         TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (self); 
    5341         CamelFolderInfo *iter; 
    5342         TnyAccount *account = NULL; 
    5343  
    5344         if (!_tny_session_check_operation (TNY_FOLDER_PRIV_GET_SESSION(priv),  
    5345                         priv->account, err, TNY_ERROR_DOMAIN, 
    5346                         TNY_SERVICE_ERROR_GET_FOLDERS)) 
    5347                 return; 
    5348  
    5349         account = tny_folder_get_account (TNY_FOLDER (self)); 
    5350  
    5351         if (account) { 
    5352                 TnyCamelStoreAccountPriv *aspriv = TNY_CAMEL_STORE_ACCOUNT_GET_PRIVATE (account); 
    5353                 if (aspriv) 
    5354                         cant_reuse_iter = aspriv->cant_reuse_iter; 
    5355                 g_object_unref (account); 
    5356         } 
    5357  
    5358         if (!cant_reuse_iter) 
    5359                 cant_reuse_iter = cant_reuse_iter; 
    5360  
    5361         if ((!priv->iter && priv->iter_parented) || cant_reuse_iter) 
    5362         { 
    5363                 CamelStore *store = priv->store; 
    5364                 CamelException ex = CAMEL_EXCEPTION_INITIALISER; 
    5365  
    5366                 g_return_if_fail (priv->folder_name != NULL); 
    5367  
    5368                 priv->iter = camel_store_get_folder_info (store, priv->folder_name, 0, &ex); 
    5369  
    5370                 priv->cant_reuse_iter = FALSE; 
    5371  
    5372                 if (camel_exception_is_set (&ex)) 
    5373                 { 
    5374                         _tny_camel_exception_to_tny_error (&ex, err); 
    5375                         camel_exception_clear (&ex); 
    5376                         _tny_session_stop_operation (TNY_FOLDER_PRIV_GET_SESSION (priv)); 
    5377  
    5378                         if (priv->iter == NULL) 
    5379                                 return; 
    5380                 } 
    5381  
    5382                 priv->iter_parented = FALSE; 
    5383         }  
    5384  
    5385         iter = priv->iter; 
    5386   
     5344        //fill up known-folders with the folders we know about from this iter. 
    53875345        if (iter) 
    53885346        { 
     
    53915349          { 
    53925350                /* Also take a look at camel-maildir-store.c:525 */ 
    5393                 if (!(iter->flags & CAMEL_FOLDER_VIRTUAL) && _tny_folder_store_query_passes (query, iter) && priv->account
     5351                if (!(iter->flags & CAMEL_FOLDER_VIRTUAL)
    53945352                { 
    53955353                        gboolean was_new = FALSE; 
    53965354                        TnyCamelFolder *folder = (TnyCamelFolder *) tny_camel_store_account_factor_folder ( 
    5397                                 TNY_CAMEL_STORE_ACCOUNT (priv->account),  
     5355                                TNY_CAMEL_STORE_ACCOUNT (priv->account), 
    53985356                                iter->full_name, &was_new); 
     5357 
    53995358                        if (was_new) 
    5400                                 _tny_camel_folder_set_folder_info (self, folder, iter); 
    5401                         tny_list_prepend (list, G_OBJECT (folder)); 
     5359                                _tny_camel_folder_set_folder_info (TNY_FOLDER_STORE(self), folder, iter); 
     5360 
     5361                        if (folder && !g_hash_table_lookup_extended (priv->known_folders, folder, NULL, NULL)) { 
     5362                                g_hash_table_insert(priv->known_folders, folder, NULL); 
     5363                                g_object_weak_ref (G_OBJECT(folder), known_folder_del, self); 
     5364                        } 
    54025365                        g_object_unref (folder); 
    54035366                } 
    54045367                iter = iter->next; 
     5368          } 
     5369        } 
     5370        return; 
     5371} 
     5372 
     5373static void 
     5374tny_camel_folder_get_folders (TnyFolderStore *self, TnyList *list, TnyFolderStoreQuery *query, gboolean refresh, GError **err) 
     5375{ 
     5376        TNY_CAMEL_FOLDER_GET_CLASS (self)->get_folders(self, list, query, refresh, err); 
     5377} 
     5378 
     5379static void  
     5380tny_camel_folder_get_folders_default (TnyFolderStore *self, TnyList *list, TnyFolderStoreQuery *query, gboolean refresh, GError **err) 
     5381{ 
     5382        gboolean cant_reuse_iter = TRUE; 
     5383        TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (self); 
     5384        CamelFolderInfo *iter; 
     5385        TnyAccount *account = NULL; 
     5386        gboolean first_time = FALSE; 
     5387 
     5388        if (!_tny_session_check_operation (TNY_FOLDER_PRIV_GET_SESSION(priv),  
     5389                        priv->account, err, TNY_ERROR_DOMAIN, 
     5390                        TNY_SERVICE_ERROR_GET_FOLDERS)) 
     5391                return; 
     5392 
     5393        account = tny_folder_get_account (TNY_FOLDER (self)); 
     5394 
     5395        if (account) { 
     5396                TnyCamelStoreAccountPriv *aspriv = TNY_CAMEL_STORE_ACCOUNT_GET_PRIVATE (account); 
     5397                if (aspriv) 
     5398                        cant_reuse_iter = aspriv->cant_reuse_iter; 
     5399                g_object_unref (account); 
     5400        } 
     5401 
     5402        if (!cant_reuse_iter) 
     5403                cant_reuse_iter = cant_reuse_iter; 
     5404 
     5405        if ((!priv->iter && priv->iter_parented) || cant_reuse_iter) 
     5406        { 
     5407                CamelStore *store = priv->store; 
     5408                CamelException ex = CAMEL_EXCEPTION_INITIALISER; 
     5409 
     5410                g_return_if_fail (priv->folder_name != NULL); 
     5411 
     5412                if (!refresh && CAMEL_IS_DISCO_STORE(store)) { 
     5413                        iter = CAMEL_DISCO_STORE_CLASS(CAMEL_OBJECT_GET_CLASS(store))->get_folder_info_offline(store,  priv->folder_name, 0, &ex); 
     5414                } else { 
     5415                        iter = camel_store_get_folder_info (store, priv->folder_name, 0, &ex); 
     5416                } 
     5417 
     5418                if (iter && priv->iter == NULL)  { 
     5419                        first_time = TRUE; 
     5420                } 
     5421                priv->iter = iter; 
     5422                priv->cant_reuse_iter = FALSE; 
     5423 
     5424                if (camel_exception_is_set (&ex)) 
     5425                { 
     5426                        _tny_camel_exception_to_tny_error (&ex, err); 
     5427                        camel_exception_clear (&ex); 
     5428                        _tny_session_stop_operation (TNY_FOLDER_PRIV_GET_SESSION (priv)); 
     5429 
     5430                        if (priv->iter == NULL) 
     5431                                return; 
     5432                } 
     5433 
     5434                priv->iter_parented = FALSE; 
     5435        }  
     5436 
     5437        iter = priv->iter; 
     5438  
     5439        if (iter && priv->account) 
     5440        { 
     5441          TnyFolderStoreChange *change = NULL; 
     5442 
     5443          iter = iter->child; 
     5444          while (iter) 
     5445          { 
     5446                /* Also take a look at camel-maildir-store.c:525 */ 
     5447                if (!(iter->flags & CAMEL_FOLDER_VIRTUAL)) 
     5448                { 
     5449                        gboolean was_new = FALSE; 
     5450                        TnyCamelFolder *folder = (TnyCamelFolder *) tny_camel_store_account_factor_folder ( 
     5451                                TNY_CAMEL_STORE_ACCOUNT (priv->account), 
     5452                                iter->full_name, &was_new); 
     5453 
     5454                        if (was_new) 
     5455                                _tny_camel_folder_set_folder_info (self, folder, iter); 
     5456 
     5457                        if (folder && !g_hash_table_lookup_extended (priv->known_folders, folder, NULL, NULL)) { 
     5458                                g_hash_table_insert(priv->known_folders, folder, NULL); 
     5459                                g_object_weak_ref (G_OBJECT(folder), known_folder_del, self); 
     5460 
     5461                                if (!change) 
     5462                                        change = tny_folder_store_change_new (TNY_FOLDER_STORE(self)); 
     5463 
     5464 
     5465                                if (first_time) { 
     5466                                        tny_folder_store_change_add_appeared_folder (change, TNY_FOLDER(folder)); 
     5467                                } else { 
     5468                                        tny_folder_store_change_add_created_folder (change, TNY_FOLDER(folder)); 
     5469                                } 
     5470 
     5471                        } 
     5472 
     5473                        if (_tny_folder_store_query_passes (query, iter)) { 
     5474                                tny_list_prepend (list, G_OBJECT (folder)); 
     5475                        } 
     5476                        g_object_unref (folder); 
     5477                } 
     5478                iter = iter->next; 
     5479          } 
     5480          if (change) { 
     5481                notify_folder_store_observers_about_in_idle (self, change, 
     5482                        TNY_FOLDER_PRIV_GET_SESSION (priv)); 
     5483                g_object_unref(change); 
    54055484          } 
    54065485        } 
     
    54305509} 
    54315510 
    5432  
    54335511typedef struct  
    54345512{ 
     
    54405518        TnyGetFoldersCallback callback; 
    54415519        TnyFolderStoreQuery *query; 
     5520        gboolean refresh; 
    54425521        gpointer user_data; 
    54435522        TnySessionCamel *session; 
     
    54905569 
    54915570        tny_folder_store_get_folders (TNY_FOLDER_STORE (info->self), 
    5492                 info->list, info->query, &info->err); 
     5571                info->list, info->query, info->refresh, &info->err); 
    54935572 
    54945573        info->cancelled = FALSE; 
     
    55375616 
    55385617static void  
    5539 tny_camel_folder_get_folders_async (TnyFolderStore *self, TnyList *list, TnyFolderStoreQuery *query, TnyGetFoldersCallback callback, TnyStatusCallback status_callback, gpointer user_data) 
    5540 { 
    5541         TNY_CAMEL_FOLDER_GET_CLASS (self)->get_folders_async(self, list, query, callback, status_callback, user_data); 
     5618tny_camel_folder_get_folders_async (TnyFolderStore *self, TnyList *list, TnyFolderStoreQuery *query, gboolean refresh, TnyGetFoldersCallback callback, TnyStatusCallback status_callback, gpointer user_data) 
     5619{ 
     5620        TNY_CAMEL_FOLDER_GET_CLASS (self)->get_folders_async(self, list, query, refresh, callback, status_callback, user_data); 
    55425621} 
    55435622 
    55445623 
    55455624static void  
    5546 tny_camel_folder_get_folders_async_default (TnyFolderStore *self, TnyList *list, TnyFolderStoreQuery *query, TnyGetFoldersCallback callback, TnyStatusCallback status_callback, gpointer user_data) 
     5625tny_camel_folder_get_folders_async_default (TnyFolderStore *self, TnyList *list, TnyFolderStoreQuery *query, gboolean refresh, TnyGetFoldersCallback callback, TnyStatusCallback status_callback, gpointer user_data) 
    55475626{ 
    55485627        GetFoldersInfo *info; 
     
    55585637        info->user_data = user_data; 
    55595638        info->query = query; 
     5639        info->refresh = refresh; 
    55605640        info->err = NULL; 
    55615641 
     
    55805660} 
    55815661 
     5662static void 
     5663tny_camel_folder_store_refresh (TnyFolderStore *self, GError **err) 
     5664{ 
     5665        TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (self); 
     5666        CamelFolderInfo *iter; 
     5667        TnyAccount *account = NULL; 
     5668        CamelStore *store = priv->store; 
     5669        CamelException ex = CAMEL_EXCEPTION_INITIALISER; 
     5670        gboolean first_time = FALSE; 
     5671 
     5672        if (!_tny_session_check_operation (TNY_FOLDER_PRIV_GET_SESSION(priv),  
     5673                        priv->account, err, TNY_ERROR_DOMAIN, 
     5674                        TNY_SERVICE_ERROR_GET_FOLDERS)) 
     5675                return; 
     5676 
     5677        g_return_if_fail (priv->folder_name != NULL); 
     5678 
     5679        iter = camel_store_get_folder_info (store, priv->folder_name, 0, &ex); 
     5680 
     5681        if (camel_exception_is_set (&ex)) 
     5682        { 
     5683                _tny_camel_exception_to_tny_error (&ex, err); 
     5684                camel_exception_clear (&ex); 
     5685                _tny_session_stop_operation (TNY_FOLDER_PRIV_GET_SESSION (priv)); 
     5686 
     5687                if (priv->iter == NULL) 
     5688                        return; 
     5689        } 
     5690 
     5691        priv->cant_reuse_iter = FALSE; 
     5692        priv->iter_parented = FALSE; 
     5693 
     5694        if (iter && priv->iter == NULL)  { 
     5695                first_time = TRUE; 
     5696        } 
     5697 
     5698        priv->iter = iter; 
     5699 
     5700        if (iter && priv->account) 
     5701        { 
     5702          TnyFolderStoreChange *change = NULL; 
     5703          iter = iter->child; 
     5704          while (iter) 
     5705          { 
     5706                /* Also take a look at camel-maildir-store.c:525 */ 
     5707                if (!(iter->flags & CAMEL_FOLDER_VIRTUAL)) 
     5708                { 
     5709                        gboolean was_new = FALSE; 
     5710                        TnyCamelFolder *folder = (TnyCamelFolder *) tny_camel_store_account_factor_folder ( 
     5711                                TNY_CAMEL_STORE_ACCOUNT (priv->account), 
     5712                                iter->full_name, &was_new); 
     5713                        if (was_new) 
     5714                                _tny_camel_folder_set_folder_info (self, folder, iter); 
     5715 
     5716                        if (was_new) 
     5717                                _tny_camel_folder_set_folder_info (self, folder, iter); 
     5718 
     5719                        if (folder && !g_hash_table_lookup_extended (priv->known_folders, folder, NULL, NULL)) { 
     5720                                g_hash_table_insert(priv->known_folders, folder, NULL); 
     5721                                g_object_weak_ref (G_OBJECT(folder), known_folder_del, self); 
     5722 
     5723                                if (!change) 
     5724                                        change = tny_folder_store_change_new (TNY_FOLDER_STORE(self)); 
     5725 
     5726 
     5727                                if (first_time) { 
     5728                                        tny_folder_store_change_add_appeared_folder (change, TNY_FOLDER(folder)); 
     5729                                } else { 
     5730                                        tny_folder_store_change_add_created_folder (change, TNY_FOLDER(folder)); 
     5731                                } 
     5732 
     5733                        } 
     5734                        g_object_unref (folder); 
     5735                } 
     5736                iter = iter->next; 
     5737          } 
     5738          if (change) { 
     5739                notify_folder_store_observers_about_in_idle (self, change, 
     5740                        TNY_FOLDER_PRIV_GET_SESSION (priv)); 
     5741                g_object_unref(change); 
     5742          } 
     5743 
     5744        } 
     5745 
     5746 
     5747        _tny_session_stop_operation (TNY_FOLDER_PRIV_GET_SESSION (priv)); 
     5748 
     5749        return; 
     5750} 
     5751 
     5752typedef struct 
     5753{ 
     5754        TnyCamelQueueable parent; 
     5755 
     5756        GError *err; 
     5757        TnyFolderStore *self; 
     5758        TnyFolderStoreCallback callback; 
     5759        gpointer user_data; 
     5760        TnySessionCamel *session; 
     5761        gboolean cancelled; 
     5762} StoreRefreshInfo; 
     5763 
     5764 
     5765static void 
     5766tny_camel_folder_store_refresh_async_destroyer (gpointer thr_user_data) 
     5767{ 
     5768        StoreRefreshInfo *info = thr_user_data; 
     5769        TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (info->self); 
     5770 
     5771        /* thread reference */ 
     5772        _tny_camel_folder_unreason (priv); 
     5773        g_object_unref (info->self); 
     5774 
     5775        if (info->err) 
     5776                g_error_free (info->err); 
     5777 
     5778        _tny_session_stop_operation (info->session); 
     5779 
     5780        camel_object_unref (info->session); 
     5781 
     5782        return; 
     5783} 
     5784 
     5785static gboolean 
     5786tny_camel_folder_store_refresh_async_callback (gpointer thr_user_data) 
     5787{ 
     5788        StoreRefreshInfo *info = thr_user_data; 
     5789        if (info->callback) { 
     5790                tny_lockable_lock (info->session->priv->ui_lock); 
     5791                info->callback (info->self, info->cancelled, info->err, info->user_data); 
     5792                tny_lockable_unlock (info->session->priv->ui_lock); 
     5793        } 
     5794        return FALSE; 
     5795} 
     5796 
     5797 
     5798static gpointer  
     5799tny_camel_folder_store_refresh_async_thread (gpointer thr_user_data) 
     5800{ 
     5801        StoreRefreshInfo *info = (StoreRefreshInfo*) thr_user_data; 
     5802 
     5803        tny_camel_folder_store_refresh (TNY_FOLDER_STORE (info->self), &info->err); 
     5804 
     5805        info->cancelled = FALSE; 
     5806        if (info->err != NULL) { 
     5807                if (camel_strstrcase (info->err->message, "cancel") != NULL) 
     5808                        info->cancelled = TRUE; 
     5809        } 
     5810 
     5811        return NULL; 
     5812} 
     5813 
     5814static void 
     5815tny_camel_folder_store_refresh_async_cancelled_destroyer (gpointer thr_user_data) 
     5816{ 
     5817        StoreRefreshInfo *info = thr_user_data; 
     5818        TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (info->self); 
     5819 
     5820        /* thread reference */ 
     5821        _tny_camel_folder_unreason (priv); 
     5822        g_object_unref (info->self); 
     5823 
     5824        if (info->err) 
     5825                g_error_free (info->err); 
     5826 
     5827        /**/ 
     5828 
     5829        camel_object_unref (info->session); 
     5830 
     5831        return; 
     5832} 
     5833 
     5834static gboolean 
     5835tny_camel_folder_store_refresh_async_cancelled_callback (gpointer thr_user_data) 
     5836{ 
     5837        StoreRefreshInfo *info = thr_user_data; 
     5838        if (info->callback) { 
     5839                tny_lockable_lock (info->session->priv->ui_lock); 
     5840                info->callback (info->self, TRUE, info->err, info->user_data); 
     5841                tny_lockable_unlock (info->session->priv->ui_lock); 
     5842        } 
     5843        return FALSE; 
     5844} 
     5845 
     5846static void 
     5847tny_camel_folder_store_refresh_async (TnyFolderStore *self, TnyFolderStoreCallback callback, TnyStatusCallback status_callback, gpointer user_data) 
     5848{ 
     5849        StoreRefreshInfo *info; 
     5850        TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (self); 
     5851 
     5852        /* Idle info for the callbacks */ 
     5853        info = g_slice_new (StoreRefreshInfo); 
     5854        info->session = TNY_FOLDER_PRIV_GET_SESSION (priv); 
     5855        camel_object_ref (info->session); 
     5856        info->self = self; 
     5857        info->callback = callback; 
     5858        info->user_data = user_data; 
     5859        info->err = NULL; 
     5860 
     5861        /* thread reference */ 
     5862        _tny_camel_folder_reason (priv); 
     5863        g_object_ref (info->self); 
     5864 
     5865        _tny_camel_queue_launch (TNY_FOLDER_PRIV_GET_QUEUE (priv), 
     5866                tny_camel_folder_store_refresh_async_thread, 
     5867                tny_camel_folder_store_refresh_async_callback, 
     5868                tny_camel_folder_store_refresh_async_destroyer, 
     5869                tny_camel_folder_store_refresh_async_cancelled_callback, 
     5870                tny_camel_folder_store_refresh_async_cancelled_destroyer, 
     5871                &info->cancelled, 
     5872                info, sizeof (StoreRefreshInfo), 
     5873                __FUNCTION__); 
     5874 
     5875        return; 
     5876} 
    55825877 
    55835878void 
     
    58966191} 
    58976192 
     6193static void build_appeared_change (gpointer key, 
     6194                                   gpointer value, 
     6195                                   gpointer user_data) 
     6196{ 
     6197        TnyFolder *folder = key; 
     6198        TnyFolderStoreChange *change = user_data; 
     6199        tny_folder_store_change_add_appeared_folder (change, folder); 
     6200} 
     6201 
    58986202static void 
    58996203tny_camel_folder_store_add_observer_default (TnyFolderStore *self, TnyFolderStoreObserver *observer) 
    59006204{ 
    59016205        TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (self); 
     6206        TnyFolderStoreChange *change = tny_folder_store_change_new (self); 
    59026207 
    59036208        g_assert (TNY_IS_FOLDER_STORE_OBSERVER (observer)); 
     
    59096214        } 
    59106215        g_static_rec_mutex_unlock (priv->obs_lock); 
     6216 
     6217        g_hash_table_foreach (priv->known_folders, build_appeared_change, change); 
     6218        if (tny_folder_store_change_get_changed (change) != 0)  
     6219                notify_folder_store_observers_about_in_idle (self, change, TNY_FOLDER_PRIV_GET_SESSION (priv)); 
     6220        g_object_unref (change); 
    59116221 
    59126222        return; 
     
    60586368        TnyCamelFolder *self = (TnyCamelFolder*) object; 
    60596369        TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (self); 
     6370 
     6371        g_hash_table_foreach_remove (priv->known_folders, (GHRFunc) known_folder_remover, self); 
     6372        g_hash_table_unref(priv->known_folders); 
    60606373 
    60616374        if (priv->store) 
     
    62316544        klass->add_observer= tny_camel_folder_store_add_observer; 
    62326545        klass->remove_observer= tny_camel_folder_store_remove_observer; 
     6546        klass->refresh_async = tny_camel_folder_store_refresh_async; 
    62336547 
    62346548        return; 
     
    63496663        priv->cached_name = NULL; 
    63506664        priv->cached_folder_type = TNY_FOLDER_TYPE_UNKNOWN; 
     6665        priv->known_folders = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, NULL); 
    63516666        priv->remove_strat = tny_camel_msg_remove_strategy_new (); 
    63526667        priv->receive_strat = tny_camel_full_msg_receive_strategy_new (); 
  • trunk/libtinymail-camel/tny-camel-folder.h

    r3634 r3775  
    9393        void (*remove_msgs_async) (TnyFolder *self, TnyList *headers, TnyFolderCallback callback, TnyStatusCallback status_callback, gpointer user_data); 
    9494 
    95         void (*get_folders_async) (TnyFolderStore *self, TnyList *list, TnyFolderStoreQuery *query, TnyGetFoldersCallback callback, TnyStatusCallback status_callback, gpointer user_data); 
    96         void (*get_folders) (TnyFolderStore *self, TnyList *list, TnyFolderStoreQuery *query, GError **err); 
     95        void (*get_folders_async) (TnyFolderStore *self, TnyList *list, TnyFolderStoreQuery *query, gboolean refresh, TnyGetFoldersCallback callback, TnyStatusCallback status_callback, gpointer user_data); 
     96        void (*get_folders) (TnyFolderStore *self, TnyList *list, TnyFolderStoreQuery *query, gboolean refresh, GError **err); 
    9797        void (*remove_folder) (TnyFolderStore *self, TnyFolder *folder, GError **err); 
    9898        TnyFolder* (*create_folder) (TnyFolderStore *self, const gchar *name, GError **err); 
  • trunk/libtinymail-camel/tny-camel-queue-priv.h

    r3754 r3775  
    3838typedef struct _TnyCamelQueueable TnyCamelQueueable; 
    3939typedef struct _TnyCamelQueueClass TnyCamelQueueClass; 
     40typedef void (*TnyCamelQueueStopCb)(gpointer); 
    4041 
    4142struct _TnyCamelQueue 
     
    5051        gboolean is_waiting; 
    5152        GStaticRecMutex *lock; 
    52         gboolean stopped, next_uncancel; 
     53        gboolean stop; 
     54        gboolean running; 
     55        gboolean dead; 
     56        gboolean next_uncancel; 
    5357        gpointer current; 
     58        TnyCamelQueueStopCb stop_callback; 
     59        gpointer stop_user_data; 
    5460}; 
    5561 
     
    8692void _tny_camel_queue_cancel_remove_items (TnyCamelQueue *queue, TnyCamelQueueItemFlags flags); 
    8793gboolean _tny_camel_queue_has_items (TnyCamelQueue *queue, TnyCamelQueueItemFlags flags); 
     94void _tny_camel_queue_stop (TnyCamelQueue *queue, TnyCamelQueueStopCb stop_cb, gpointer user_data); 
    8895 
    8996G_END_DECLS 
  • trunk/libtinymail-camel/tny-camel-queue.c

    r3754 r3775  
    4747        TnyCamelQueue *self = (TnyCamelQueue*) object; 
    4848 
    49         self->stopped = TRUE; 
     49        self->stop = TRUE; 
    5050 
    5151        g_mutex_lock (self->mutex); 
     
    7676        g_mutex_lock (queue->mutex); 
    7777        queue->account = NULL; 
    78         queue->stopped = TRUE; 
     78        queue->stop = TRUE; 
    7979        if (queue->is_waiting) { 
    8080                g_cond_broadcast (queue->condition); 
     
    101101        return TNY_CAMEL_QUEUE (self); 
    102102} 
     103 
     104typedef struct _StopCallbackData StopCallbackData; 
     105struct _StopCallbackData 
     106{ 
     107        TnyCamelQueueStopCb cb; 
     108        gpointer data; 
     109}; 
     110 
     111static gboolean 
     112call_stop_callback (gpointer user_data) 
     113{ 
     114        StopCallbackData *data = user_data; 
     115        data->cb(data->data); 
     116        g_slice_free (StopCallbackData, data); 
     117        return FALSE; 
     118} 
     119 
     120static void 
     121idle_add_stop_callback (TnyCamelQueueStopCb cb, gpointer data) 
     122{ 
     123        StopCallbackData *scd = g_slice_new (StopCallbackData); 
     124        scd->cb = cb; 
     125        scd->data = data; 
     126        g_idle_add (call_stop_callback, scd); 
     127} 
     128 
    103129 
    104130typedef struct 
     
    185211        TnyCamelQueue *queue = user_data; 
    186212 
    187         while (!queue->stopped
     213        while (!queue->stop || queue->list
    188214        { 
    189215                GList *first = NULL; 
     
    271297                        g_slice_free (QueueItem, item); 
    272298 
    273                 if (wait) { 
     299                if (wait && !queue->stop) { 
     300                        g_object_ref (queue); 
    274301                        g_mutex_lock (queue->mutex); 
    275302                        queue->is_waiting = TRUE; 
     
    277304                        queue->is_waiting = FALSE; 
    278305                        g_mutex_unlock (queue->mutex); 
    279                 } 
    280         } 
    281  
    282         queue->thread = NULL; 
    283         queue->stopped = TRUE; 
     306                        g_object_unref (queue); 
     307                } 
     308        } 
     309 
     310        queue->running = FALSE; 
     311 
     312        g_static_rec_mutex_lock (queue->lock); 
     313        if (queue->stop_callback) { 
     314                g_debug("Calling stop callback"); 
     315                idle_add_stop_callback (queue->stop_callback, queue->stop_user_data); 
     316        } 
     317        g_static_rec_mutex_unlock (queue->lock); 
    284318 
    285319        g_object_unref (queue); 
    286  
    287         return NULL; 
     320        g_thread_exit (NULL); 
    288321} 
    289322 
     
    397430_tny_camel_queue_launch_wflags (TnyCamelQueue *queue, GThreadFunc func, GSourceFunc callb