Changeset 1886

Show
Ignore:
Timestamp:
05/04/07 15:05:25
Author:
pvanhoof
Message:

API changes and tny_folder_get_msg_async status-callbacks

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/ChangeLog

    r1885 r1886  
     12007-05-04  Philip Van Hoof  <pvanhoof@gnome.org> 
     2 
     3        * Changed the TnyGetMsgCallback function signature to have a cancelled  
     4        property. 
     5        * Implemented support for status-callbacks for tny_folder_get_msg_async 
     6        * Changed the demoui to use the get_msg_async functionality for testing 
     7        recent changes 
     8 
     9        * This was a major API change 
     10 
    1112007-05-04  Murray Cumming  <murrayc@murrayc.com> 
    212 
    313        * libtinymail/Makefile.am: 
    414        * libtinymail/tny-idle-stopper-priv.c: 
    5         * libtinymail/tny-idle-stopper-priv.h: Added a helper API to allow 2 or more  
    6         idle handler callbacks to cooperate, so that one can stop the other one, in  
    7         case they are called in an unexpected sequence, which happens when they  
    8         have different idle priorities. 
    9         See the API documentation here fore more details. 
     15        * libtinymail/tny-idle-stopper-priv.h: Added a helper API to allow 2 or 
     16        more idle handler callbacks to cooperate, so that one can stop the other 
     17        one, in case they are called in an unexpected sequence, which happens  
     18        when they have different idle priorities. See the API documentation here 
     19        for more details. 
    1020 
    1121        * libtinymail-camel/tny-camel-folder.c: 
     
    1323        (tny_camel_folder_refresh_async_callback), (destroy_progress_idle), 
    1424        (progress_func), (tny_camel_folder_refresh_async_status), 
    15         (tny_camel_folder_refresh_async_default): Use shared TnyIdleHandler instances,  
    16         so that the main idle callback can stop the progress idle callback from calling  
    17         the status callback after the main callback, which causes freed memory to be used,  
    18         crashing modest. See the comments here fore more details. 
    19  
    20         * libtinymail/tny-folder.c: Added some text to the tny_folder_refresh_async()  
    21         callbacks to make the sequence clearer. I think that language bindings will  
    22         actually need one or more destroy callbacks eventually. 
     25        (tny_camel_folder_refresh_async_default): Use shared TnyIdleHandler  
     26        instances, so that the main idle callback can stop the progress idle  
     27        callback from calling the status callback after the main callback,  
     28        which causes freed memory to be used, crashing modest. See the comments 
     29        here fore more details. 
     30 
     31        * libtinymail/tny-folder.c: Added some text to the  
     32        tny_folder_refresh_async() callbacks to make the sequence clearer.  
     33        I think that language bindings will actually need one or more destroy  
     34        callbacks eventually. 
    2335 
    24362007-05-04  Philip Van Hoof  <pvanhoof@gnome.org> 
  • trunk/libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-folder.c

    r1843 r1886  
    38863886        } 
    38873887 
     3888        camel_operation_start (NULL, _("Preparing to get message")); 
     3889 
    38883890        /* amcon = camel_imap_service_connect (CAMEL_SERVICE (store), ex); */ 
    38893891        amcon = camel_service_connect (CAMEL_SERVICE (store), ex); 
     
    38993901        } 
    39003902        camel_exception_clear (ex); 
     3903 
     3904        camel_operation_end (NULL); 
     3905 
     3906        camel_operation_start (NULL, _("Getting message")); 
    39013907 
    39023908  CAMEL_SERVICE_REC_LOCK(store, connect_lock);  
     
    39984004                                        rec += hread; 
    39994005                                } 
     4006                                camel_operation_progress (NULL, rec, length); 
    40004007                        } 
    40014008                        camel_stream_reset (stream); 
     
    40254032                        guint taglen; 
    40264033                        gboolean isnextdone = FALSE, hadr = FALSE; 
     4034                        guint tread = 0, exread = 0; 
    40274035 
    40284036                        nread = 0; 
     
    40504058                          while (nread = camel_stream_buffer_gets (server_stream, line, MAX_LINE_LEN) > 0) 
    40514059                          { 
     4060                                tread += nread; 
    40524061 
    40534062                                /* It might be the line before the last line */ 
     
    40644073                                        { err=TRUE; break; }  
    40654074                                else if (linenum == 0)  
    4066                                         { linenum++; continue; } 
     4075                                {  
     4076                                        char *pos, *ppos; 
     4077                                        pos = strchr (line, '{'); 
     4078                                        if (pos) {  
     4079                                                ppos = strchr (pos, '}'); 
     4080                                                if (ppos) { 
     4081                                                        *ppos = '\0'; 
     4082                                                        exread = strtol (pos + 1, NULL, 10); 
     4083                                                } 
     4084                                        } 
     4085                                        linenum++;  
     4086                                        continue;  
     4087                                } 
    40674088 
    40684089                                /* It's the last line (isnextdone will be ignored if that is the case) */ 
     
    40864107 
    40874108                                linenum++; 
     4109 
     4110                                camel_operation_progress (NULL, tread, exread); 
     4111 
    40884112                                memset (line, 0, MAX_LINE_LEN); 
    40894113                          } 
     
    41294153                        guint taglen; 
    41304154                        gboolean isnextdone = FALSE; 
     4155                        guint tread = 0, exread = 0; 
    41314156 
    41324157                        nread = 0; 
     
    41674192                          while (nread = camel_stream_buffer_gets (server_stream, line, MAX_LINE_LEN) > 0) 
    41684193                          { 
     4194                                tread += nread; 
    41694195 
    41704196                                /* It might be the line before the last line */ 
     
    41764202                                        { err=TRUE; break; }  
    41774203                                else if (linenum == 0)  
    4178                                         { linenum++; continue; } 
     4204                                {  
     4205                                        char *pos, *ppos; 
     4206                                        pos = strchr (line, '{'); 
     4207                                        if (pos) {  
     4208                                                ppos = strchr (pos, '}'); 
     4209                                                if (ppos) { 
     4210                                                        *ppos = '\0'; 
     4211                                                        exread = strtol (pos + 1, NULL, 10); 
     4212                                                } 
     4213                                        } 
     4214                                        linenum++;  
     4215                                        continue;  
     4216                                } 
     4217 
    41794218 
    41804219                                /* It's the last line */ 
     
    42334272                                camel_stream_write (stream, line, strlen (line)); 
    42344273 
     4274                                camel_operation_progress (NULL, tread, exread); 
     4275 
    42354276                                linenum++; 
    42364277                                memset (line, 0, MAX_LINE_LEN); 
     
    42704311        camel_object_unref (CAMEL_OBJECT (store)); 
    42714312 
     4313        camel_operation_end (NULL); 
     4314 
    42724315        return stream; 
    42734316 
     
    42954338        camel_object_unref (CAMEL_OBJECT (store)); 
    42964339  } 
     4340 
     4341        camel_operation_end (NULL); 
     4342 
    42974343        return NULL; 
    42984344} 
  • trunk/libtinymail-camel/tny-camel-account-priv.h

    r1498 r1886  
    4848const gchar* _tny_camel_account_get_url_string (TnyCamelAccount *self); 
    4949void _tny_camel_account_start_camel_operation (TnyCamelAccount *self, CamelOperationStatusFunc func, gpointer user_data, const gchar *what); 
     50void _tny_camel_account_start_camel_operation_n (TnyCamelAccount *self, CamelOperationStatusFunc func, gpointer user_data, const gchar *what, gboolean cancel); 
    5051void _tny_camel_account_stop_camel_operation (TnyCamelAccount *self); 
    5152void _tny_camel_account_try_connect (TnyCamelAccount *self, GError **err); 
  • trunk/libtinymail-camel/tny-camel-account.c

    r1866 r1886  
    284284 
    285285void  
    286 _tny_camel_account_start_camel_operation (TnyCamelAccount *self, CamelOperationStatusFunc func, gpointer user_data, const gchar *what
     286_tny_camel_account_start_camel_operation_n (TnyCamelAccount *self, CamelOperationStatusFunc func, gpointer user_data, const gchar *what, gboolean cancel
    287287{ 
    288288        TnyCamelAccountPriv *priv = TNY_CAMEL_ACCOUNT_GET_PRIVATE (self); 
     
    292292        g_mutex_lock (priv->cancel_lock); 
    293293 
    294         /* I know this isn't polite. But it works ;-) */ 
    295         /* camel_operation_cancel (NULL); */ 
    296         thread = g_thread_create (camel_cancel_hack_thread, NULL, TRUE, &err); 
    297         if (err == NULL) 
    298                 g_thread_join (thread); 
    299         else 
    300                 g_error_free (err); 
    301  
    302         if (priv->cancel) 
     294        if (cancel) 
    303295        { 
    304                 while (!camel_operation_cancel_check (priv->cancel))  
    305                 {  
    306                        g_warning (_("Cancellation failed, retrying\n")); 
    307                        thread = g_thread_create (camel_cancel_hack_thread, NULL, TRUE, NULL); 
     296                /* I know this isn't polite. But it works ;-) */ 
     297                /* camel_operation_cancel (NULL); */ 
     298                thread = g_thread_create (camel_cancel_hack_thread, NULL, TRUE, &err); 
     299                if (err == NULL) 
    308300                        g_thread_join (thread); 
     301                else 
     302                        g_error_free (err); 
     303         
     304 
     305                if (priv->cancel) 
     306                { 
     307                        while (!camel_operation_cancel_check (priv->cancel))  
     308                        {  
     309                                g_warning (_("Cancellation failed, retrying\n")); 
     310                                thread = g_thread_create (camel_cancel_hack_thread, NULL, TRUE, NULL); 
     311                                g_thread_join (thread); 
     312                        } 
     313                        tny_camel_account_stop_camel_operation_priv (priv); 
    309314                } 
    310                 tny_camel_account_stop_camel_operation_priv (priv); 
    311         } 
    312  
    313         camel_operation_uncancel (NULL); 
     315 
     316                camel_operation_uncancel (NULL); 
     317        } 
    314318 
    315319        while (priv->inuse_spin);  
     
    317321        priv->inuse_spin = TRUE; 
    318322 
    319  
    320323        priv->cancel = camel_operation_new (func, user_data); 
    321          
     324 
    322325        camel_operation_ref (priv->cancel); 
    323326        camel_operation_register (priv->cancel); 
     
    327330 
    328331        return; 
     332} 
     333 
     334void  
     335_tny_camel_account_start_camel_operation (TnyCamelAccount *self, CamelOperationStatusFunc func, gpointer user_data, const gchar *what) 
     336{ 
     337        _tny_camel_account_start_camel_operation_n (self, func, user_data, what, TRUE); 
    329338} 
    330339 
  • trunk/libtinymail-camel/tny-camel-folder.c

    r1885 r1886  
    703703 
    704704 
     705 
     706 
     707 
     708 
     709typedef struct 
     710{ 
     711        TnyFolder *self; 
     712        gpointer user_data; 
     713        TnyStatusCallback status_callback; 
     714        gchar *what; 
     715        gint sofar, oftotal; 
     716        TnyIdleStopper* stopper; 
     717} ProgressInfo; 
     718 
     719static void 
     720destroy_progress_idle (gpointer data) 
     721{ 
     722        ProgressInfo *info = data; 
     723        TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (info->self); 
     724 
     725        /* gidle reference */ 
     726        _tny_camel_folder_unreason (priv); 
     727        g_object_unref (G_OBJECT (info->self)); 
     728        g_free (info->what); 
     729 
     730        tny_idle_stopper_destroy (info->stopper); 
     731        info->stopper = NULL; 
     732 
     733        g_slice_free (ProgressInfo, data); 
     734 
     735        return; 
     736} 
     737 
     738static gboolean 
     739progress_func (gpointer data) 
     740{ 
     741        ProgressInfo *info = data; 
     742 
     743        /* Do not call the status callback after the main callback  
     744         * has already been called, because we should assume that  
     745         * the user_data is invalid after that time: */ 
     746        if (tny_idle_stopper_is_stopped (info->stopper)) 
     747                return FALSE; 
     748 
     749        if (info && info->status_callback) 
     750        { 
     751                TnyStatus *status = tny_status_new (TNY_FOLDER_STATUS,  
     752                        TNY_FOLDER_STATUS_CODE_REFRESH, 
     753                        info->sofar, info->oftotal, info->what); 
     754 
     755                info->status_callback (G_OBJECT (info->self), status,  
     756                        info->user_data); 
     757 
     758                tny_status_free (status); 
     759        } 
     760 
     761        return FALSE; 
     762}  
     763 
     764 
    705765typedef struct  
    706766{ 
     
    710770        gpointer user_data; 
    711771        gboolean cancelled; 
    712          
    713772        /* This stops us from calling a status callback after the operation has  
    714773         * finished. */ 
    715774        TnyIdleStopper* stopper; 
    716          
    717775        guint depth; 
    718776        GError *err; 
     
    763821         * by causing tny_idle_stopper_is_stopped() to return TRUE. */ 
    764822        tny_idle_stopper_stop (info->stopper); 
    765          
     823 
    766824        tny_folder_change_set_new_all_count (change, priv->cached_length); 
    767825        tny_folder_change_set_new_unread_count (change, priv->unread_length); 
     
    771829        return FALSE; 
    772830} 
    773  
    774  
    775 typedef struct 
    776 { 
    777         RefreshFolderInfo *minfo; 
    778         gchar *what; 
    779         gint sofar, oftotal; 
    780 } ProgressInfo; 
    781  
    782 static void 
    783 destroy_progress_idle (gpointer data) 
    784 { 
    785         ProgressInfo *info = data; 
    786         TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (info->minfo->self); 
    787  
    788         /* gidle reference */ 
    789         _tny_camel_folder_unreason (priv); 
    790         g_object_unref (G_OBJECT (info->minfo->self)); 
    791         g_free (info->what); 
    792  
    793         tny_idle_stopper_destroy (info->minfo->stopper); 
    794         info->minfo->stopper = NULL; 
    795      
    796         g_slice_free (RefreshFolderInfo, info->minfo); 
    797         g_slice_free (ProgressInfo, data); 
    798  
    799         return; 
    800 } 
    801  
    802 static gboolean 
    803 progress_func (gpointer data) 
    804 { 
    805         ProgressInfo *info = data; 
    806         RefreshFolderInfo *minfo = info->minfo; 
    807          
    808         /* Do not call the status callback after the main callback  
    809          * has already been called, because we should assume that  
    810          * the user_data is invalid after that time: */ 
    811         if (tny_idle_stopper_is_stopped (minfo->stopper)) 
    812                 return FALSE; 
    813          
    814         if (minfo && minfo->status_callback) 
    815         { 
    816                 TnyStatus *status = tny_status_new (TNY_FOLDER_STATUS,  
    817                         TNY_FOLDER_STATUS_CODE_REFRESH, 
    818                         info->sofar, info->oftotal, info->what); 
    819  
    820                 minfo->status_callback (G_OBJECT (minfo->self), status,  
    821                         minfo->user_data); 
    822  
    823                 tny_status_free (status); 
    824         } 
    825  
    826         return FALSE; 
    827 }  
    828831 
    829832 
     
    851854 
    852855        info->what = g_strdup (what); 
    853         info->minfo = g_slice_new (RefreshFolderInfo); 
    854         info->minfo->callback = oinfo->callback; 
    855         info->minfo->cancelled = oinfo->cancelled; 
    856         info->minfo->self = oinfo->self; 
    857         info->minfo->status_callback = oinfo->status_callback; 
    858         info->minfo->user_data = oinfo->user_data; 
     856        /* gidle reference */ 
     857        info->self = TNY_FOLDER (g_object_ref (oinfo->self)); 
     858        _tny_camel_folder_reason (priv); 
     859        info->status_callback = oinfo->status_callback; 
     860        info->user_data = oinfo->user_data; 
    859861        info->oftotal = oftotal; 
    860          
     862 
    861863        /* Share the TnyIdleStopper, so one callback can tell the other to stop, 
    862864         * because they may be called in an unexpected sequence: */ 
    863865        /* This is destroyed in the idle GDestroyNotify callback. */ 
    864         info->minfo->stopper = tny_idle_stopper_copy(oinfo->stopper); 
     866        info->stopper = tny_idle_stopper_copy(oinfo->stopper); 
    865867 
    866868        if (info->oftotal < 1) 
     
    875877                        info->sofar = sofar; 
    876878 
    877         /* gidle reference */ 
    878         g_object_ref (G_OBJECT (info->minfo->self)); 
    879         _tny_camel_folder_reason (priv); 
    880879 
    881880        if (oinfo->depth > 0) 
     
    959958                g_object_unref (G_OBJECT (self)); 
    960959                _tny_camel_folder_unreason (priv); 
    961  
    962960        } 
    963961        g_thread_exit (NULL); 
     
    12131211        TnyStatusCallback status_callback; 
    12141212        TnySessionCamel *session; 
     1213        TnyIdleStopper *stopper; 
     1214        gboolean cancelled; 
    12151215} GetMsgInfo; 
    12161216 
     
    12291229                notify_folder_observers_about (info->self, change); 
    12301230                g_object_unref (G_OBJECT (change)); 
    1231  
    12321231                g_object_unref (G_OBJECT (info->msg)); 
    12331232        } 
     
    12421241        _tny_session_stop_operation (info->session); 
    12431242 
     1243        tny_idle_stopper_destroy (info->stopper); 
     1244        info->stopper = NULL; 
     1245 
    12441246        g_slice_free (GetMsgInfo, info); 
    12451247} 
     
    12521254 
    12531255        if (info->callback) 
    1254                 info->callback (info->self, info->msg, &info->err, info->user_data); 
     1256                info->callback (info->self, info->cancelled, info->msg, &info->err, info->user_data); 
     1257 
     1258        /* Prevent status callbacks from being called after this 
     1259         * (can happen because the 2 idle callbacks have different priorities) 
     1260         * by causing tny_idle_stopper_is_stopped() to return TRUE. */ 
     1261        tny_idle_stopper_stop (info->stopper); 
    12551262 
    12561263        return FALSE; 
     1264} 
     1265 
     1266 
     1267static void 
     1268tny_camel_folder_get_msg_async_status (struct _CamelOperation *op, const char *what, int sofar, int oftotal, void *thr_user_data) 
     1269{ 
     1270        GetMsgInfo *oinfo = thr_user_data; 
     1271        ProgressInfo *info = g_slice_new (ProgressInfo); 
     1272        TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (oinfo->self); 
     1273 
     1274        /* Camel will shredder what and thr_user_data, so we need to copy it */ 
     1275 
     1276        info->what = g_strdup (what); 
     1277        /* gidle reference */ 
     1278        info->self = TNY_FOLDER (g_object_ref (oinfo->self)); 
     1279        _tny_camel_folder_reason (priv); 
     1280        info->status_callback = oinfo->status_callback; 
     1281        info->user_data = oinfo->user_data; 
     1282        info->oftotal = oftotal; 
     1283 
     1284        /* Share the TnyIdleStopper, so one callback can tell the other to stop, 
     1285         * because they may be called in an unexpected sequence: */ 
     1286        /* This is destroyed in the idle GDestroyNotify callback. */ 
     1287        info->stopper = tny_idle_stopper_copy (oinfo->stopper); 
     1288 
     1289        if (info->oftotal < 1) 
     1290                info->oftotal = 1; 
     1291 
     1292        if (sofar < 1) 
     1293                info->sofar = 1; 
     1294        else  
     1295                if (sofar > info->oftotal) 
     1296                        info->sofar = info->oftotal; 
     1297                else 
     1298                        info->sofar = sofar; 
     1299 
     1300 
     1301        if (oinfo->depth > 0) 
     1302        { 
     1303                g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, 
     1304                        progress_func, info, destroy_progress_idle); 
     1305        } else { 
     1306                progress_func (info); 
     1307                destroy_progress_idle (info); 
     1308        } 
     1309 
     1310        return; 
    12571311} 
    12581312 
     
    12631317        TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (info->self); 
    12641318        GError *err = NULL; 
     1319        CamelOperation *cancel; 
     1320 
     1321        /* This one doesn't use the _tny_camel_account_start_camel_operation  
     1322         * infrastructure because it doesn't need to cancel existing operations 
     1323         * due to a patch to camel-lite allowing messages to be fetched while 
     1324         * other operations are happening */ 
     1325 
     1326        cancel = camel_operation_new (tny_camel_folder_get_msg_async_status, info); 
     1327 
     1328        camel_operation_ref (cancel); 
     1329        camel_operation_register (cancel); 
     1330        camel_operation_start (cancel, (char *) "Getting message"); 
    12651331 
    12661332        info->msg = tny_folder_get_msg (info->self, info->header, &err); 
     1333 
     1334        info->cancelled = camel_operation_cancel_check (cancel); 
     1335 
     1336        camel_operation_unregister (cancel); 
     1337        camel_operation_end (cancel); 
     1338        if (cancel) 
     1339                camel_operation_unref (cancel); 
    12671340 
    12681341        if (err != NULL) 
     
    13051378 
    13061379 
    1307 static TnyMsgReceiveStrategy*  
    1308 tny_camel_folder_get_msg_receive_strategy (TnyFolder *self) 
    1309 { 
    1310         return TNY_CAMEL_FOLDER_GET_CLASS (self)->get_msg_receive_strategy_func (self); 
    1311 } 
    1312  
    1313 static TnyMsgReceiveStrategy*  
    1314 tny_camel_folder_get_msg_receive_strategy_default (TnyFolder *self) 
    1315 { 
    1316         TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (self); 
    1317  
    1318         return TNY_MSG_RECEIVE_STRATEGY (g_object_ref (G_OBJECT (priv->receive_strat))); 
    1319 } 
    1320  
    1321 static void  
    1322 tny_camel_folder_set_msg_receive_strategy (TnyFolder *self, TnyMsgReceiveStrategy *st) 
    1323 { 
    1324         TNY_CAMEL_FOLDER_GET_CLASS (self)->set_msg_receive_strategy_func (self, st); 
    1325         return; 
    1326 } 
    1327  
    1328 static void  
    1329 tny_camel_folder_set_msg_receive_strategy_default (TnyFolder *self, TnyMsgReceiveStrategy *st) 
    1330 { 
    1331         TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (self); 
    1332  
    1333         if (priv->receive_strat) 
    1334                 g_object_unref (G_OBJECT (priv->receive_strat)); 
    1335  
    1336         priv->receive_strat = TNY_MSG_RECEIVE_STRATEGY (g_object_ref (G_OBJECT (st))); 
    1337  
    1338         return; 
    1339 } 
    1340  
    13411380static void 
    13421381tny_camel_folder_get_msg_async_default (TnyFolder *self, TnyHeader *header, TnyGetMsgCallback callback, TnyStatusCallback status_callback, gpointer user_data) 
     
    13511390        { 
    13521391                if (callback) 
    1353                         callback (self, NULL, &err, user_data); 
     1392                        callback (self, TRUE, NULL, &err, user_data); 
    13541393                g_error_free (err); 
    13551394                return; 
     
    13571396 
    13581397        info = g_slice_new (GetMsgInfo); 
     1398        info->cancelled = FALSE; 
    13591399        info->session = TNY_FOLDER_PRIV_GET_SESSION (priv); 
    13601400        info->self = self; 
     
    13651405        info->depth = g_main_depth (); 
    13661406 
     1407        /* Use a ref count because we do not know which of the 2 idle callbacks  
     1408         * will be the last, and we can only unref self in the last callback: 
     1409         * This is destroyed in the idle GDestroyNotify callback. 
     1410         */ 
     1411        info->stopper = tny_idle_stopper_new(); 
     1412 
    13671413        /* thread reference */ 
    13681414        _tny_camel_folder_reason (priv); 
     
    13721418        thread = g_thread_create (tny_camel_folder_get_msg_async_thread, 
    13731419                        info, FALSE, NULL); 
     1420 
     1421        return; 
     1422} 
     1423 
     1424 
     1425 
     1426static TnyMsgReceiveStrategy*  
     1427tny_camel_folder_get_msg_receive_strategy (TnyFolder *self) 
     1428{ 
     1429        return TNY_CAMEL_FOLDER_GET_CLASS (self)->get_msg_receive_strategy_func (self); 
     1430} 
     1431 
     1432static TnyMsgReceiveStrategy*  
     1433tny_camel_folder_get_msg_receive_strategy_default (TnyFolder *self) 
     1434{ 
     1435        TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (self); 
     1436 
     1437        return TNY_MSG_RECEIVE_STRATEGY (g_object_ref (G_OBJECT (priv->receive_strat))); 
     1438} 
     1439 
     1440static void  
     1441tny_camel_folder_set_msg_receive_strategy (TnyFolder *self, TnyMsgReceiveStrategy *st) 
     1442{ 
     1443        TNY_CAMEL_FOLDER_GET_CLASS (self)->set_msg_receive_strategy_func (self, st); 
     1444        return; 
     1445} 
     1446 
     1447static void  
     1448tny_camel_folder_set_msg_receive_strategy_default (TnyFolder *self, TnyMsgReceiveStrategy *st) 
     1449{ 
     1450        TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (self); 
     1451 
     1452        if (priv->receive_strat) 
     1453                g_object_unref (G_OBJECT (priv->receive_strat)); 
     1454 
     1455        priv->receive_strat = TNY_MSG_RECEIVE_STRATEGY (g_object_ref (G_OBJECT (st))); 
    13741456 
    13751457        return; 
  • trunk/libtinymail-queues/tny-get-msg-queue.c

    r1884 r1886  
    9696 
    9797        if (info->callback) 
    98                 info->callback (folder, msg, &info->err, info->user_data); 
     98                info->callback (folder, FALSE, msg, &info->err, info->user_data); 
    9999 
    100100        if (msg) 
  • trunk/libtinymail/tny-merge-folder.c

    r1879 r1886  
    232232        GetMsgInfo *info = (GetMsgInfo *) thr_user_data; 
    233233 
    234         if (info->callback) 
    235                 info->callback (info->self, info->msg, &info->err, info->user_data); 
     234        if (info->callback) /* TODO: the cancelled field */ 
     235                info->callback (info->self, FALSE, info->msg, &info->err, info->user_data); 
    236236 
    237237        return FALSE; 
  • trunk/libtinymail/tny-shared.h

    r1869 r1886  
    5454typedef void (*TnyForgetPassFunc) (TnyAccount *self); 
    5555typedef void (*TnyRefreshFolderCallback) (TnyFolder *self, gboolean cancelled, GError **err, gpointer user_data); 
    56 typedef void (*TnyGetMsgCallback) (TnyFolder *folder, TnyMsg *msg, GError **err, gpointer user_data); 
     56typedef void (*TnyGetMsgCallback) (TnyFolder *folder, gboolean cancelled, TnyMsg *msg, GError **err, gpointer user_data); 
    5757typedef void (*TnyTransferMsgsCallback) (TnyFolder *folder, GError **err, gpointer user_data); 
    5858typedef void (*TnyStatusCallback) (GObject *self, TnyStatus *status, gpointer user_data); 
  • trunk/tests/c-demo/tny-demoui-summary-view.c

    r1884 r1886  
    109109 
    110110 
     111static gboolean 
     112cleanup_statusbar (gpointer data) 
     113{ 
     114        TnyDemouiSummaryViewPriv *priv = data; 
     115 
     116        gtk_widget_hide (GTK_WIDGET (priv->progress)); 
     117        gtk_statusbar_pop (GTK_STATUSBAR (priv->status), priv->status_id); 
     118 
     119        return FALSE; 
     120} 
     121 
     122 
     123static void 
     124status_update (GObject *sender, TnyStatus *status, gpointer user_data) 
     125{ 
     126        TnySummaryView *self = user_data; 
     127        TnyDemouiSummaryViewPriv *priv = TNY_DEMOUI_SUMMARY_VIEW_GET_PRIVATE (self); 
     128 
     129        gchar *new_what; 
     130 
     131        if (!user_data) 
     132                return; 
     133 
     134        gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (priv->progress),  
     135                tny_status_get_fraction (status)); 
     136        gtk_statusbar_pop (GTK_STATUSBAR (priv->status), priv->status_id); 
     137 
     138        new_what = g_strdup_printf ("%s (%d/%d)", status->message, status->position,  
     139                status->of_total); 
     140 
     141        gtk_statusbar_push (GTK_STATUSBAR (priv->status), priv->status_id, new_what); 
     142        g_free (new_what); 
     143 
     144        return; 
     145} 
     146 
    111147static void 
    112148set_header_view_model (GtkTreeView *header_view, GtkTreeModel *model) 
     
    356392 
    357393static void 
     394on_get_msg (TnyFolder *folder, gboolean cancelled, TnyMsg *msg, GError **err, gpointer user_data) 
     395{ 
     396        TnyDemouiSummaryView *self  = user_data; 
     397        TnyDemouiSummaryViewPriv *priv = TNY_DEMOUI_SUMMARY_VIEW_GET_PRIVATE (self); 
     398        GError *merr = *err; 
     399 
     400        g_idle_add (cleanup_statusbar, priv); 
     401 
     402        if (cancelled) 
     403                return; 
     404 
     405        if (msg) 
     406                tny_msg_view_set_msg (priv->msg_view, msg); 
     407        else  
     408                tny_msg_view_set_unavailable (priv->msg_view); 
     409 
     410        if (merr != NULL) 
     411        { 
     412                GtkWidget *edialog; 
     413 
     414                edialog = gtk_message_dialog_new ( 
     415                                  GTK_WINDOW (gtk_widget_get_parent (GTK_WIDGET (self))), 
     416                                  GTK_DIALOG_DESTROY_WITH_PARENT, 
     417                                  GTK_MESSAGE_ERROR, 
     418                                  GTK_BUTTONS_CLOSE, 
     419                                  merr->message); 
     420                g_signal_connect_swapped (edialog, "response", 
     421                        G_CALLBACK (gtk_widget_destroy), edialog); 
     422                gtk_widget_show_all (edialog); 
     423                g_error_free (merr); 
     424        } 
     425} 
     426 
     427static void 
    358428on_header_view_tree_selection_changed (GtkTreeSelection *selection,  
    359429                gpointer user_data) 
     
    375445                { 
    376446                        TnyFolder *folder; 
    377                         TnyMsg *msg; 
    378  
    379447                        folder = tny_header_get_folder (header); 
    380                         if (G_LIKELY (folder)
     448                        if (folder
    381449                        { 
    382                                 GError *err = NULL; 
    383  
    384                                 msg = tny_folder_get_msg (folder, header, &err); 
    385                                 if (G_LIKELY (msg)) 
    386                                 { 
    387                                         tny_msg_view_set_msg (priv->msg_view, msg); 
    388                                         g_object_unref (G_OBJECT (msg)); 
    389                                 } else {  
    390                                         tny_msg_view_set_unavailable (priv->msg_view); 
    391                                 } 
    392  
    393                                 if (err != NULL) 
    394                                 { 
    395                                         GtkWidget *edialog; 
    396  
    397                                         edialog = gtk_message_dialog_new ( 
    398                                                           GTK_WINDOW (gtk_widget_get_parent (GTK_WIDGET (self))), 
    399                                                           GTK_DIALOG_DESTROY_WITH_PARENT, 
    400                                                           GTK_MESSAGE_ERROR, 
    401                                                           GTK_BUTTONS_CLOSE, 
    402                                                           err->message); 
    403                                         g_signal_connect_swapped (edialog, "response", 
    404                                                 G_CALLBACK (gtk_widget_destroy), edialog); 
    405                                         gtk_widget_show_all (edialog); 
    406                                         g_error_free (err); 
    407                                 } 
    408  
     450                                gtk_widget_show (GTK_WIDGET (priv->progress)); 
     451 
     452                                tny_folder_get_msg_async (folder, header,  
     453                                        on_get_msg, status_update, self); 
    409454                                g_object_unref (G_OBJECT (folder)); 
    410455                        } 
     
    420465} 
    421466 
    422 static gboolean 
    423 cleanup_statusbar (gpointer data) 
    424 { 
    425         TnyDemouiSummaryViewPriv *priv = data; 
    426  
    427         gtk_widget_hide (GTK_WIDGET (priv->progress)); 
    428         gtk_statusbar_pop (GTK_STATUSBAR (priv->status), priv->status_id); 
    429  
    430         return FALSE; 
    431 } 
    432  
    433467 
    434468static void 
    435469refresh_current_folder (TnyFolder *folder, gboolean cancelled, GError **err, gpointer user_data) 
    436470{ 
    437         TnyDemouiSummaryViewPriv *priv = user_data; 
     471        TnySummaryView *self = user_data; 
     472        TnyDemouiSummaryViewPriv *priv = TNY_DEMOUI_SUMMARY_VIEW_GET_PRIVATE (self); 
     473 
    438474        GtkTreeModel *select_model; 
    439475 
     
    469505 
    470506 
    471 static void 
    472 refresh_current_folder_status_update (GObject *sender, TnyStatus *status, gpointer user_data) 
    473 { 
    474         gchar *new_what; 
    475  
    476         TnyDemouiSummaryViewPriv *priv = user_data; 
    477  
    478         if (!user_data) 
    479                 return; 
    480  
    481         gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (priv->progress),  
    482                 tny_status_get_fraction (status)); 
    483         gtk_statusbar_pop (GTK_STATUSBAR (priv->status), priv->status_id); 
    484  
    485         new_what = g_strdup_printf ("%s (%d/%d)", status->message, status->position,  
    486                 status->of_total); 
    487  
    488         gtk_statusbar_push (GTK_STATUSBAR (priv->status), priv->status_id, new_what); 
    489         g_free (new_what); 
    490  
    491         return; 
    492 } 
    493507 
    494508static void 
     
    496510                gpointer user_data) 
    497511{ 
    498         TnyDemouiSummaryViewPriv *priv = user_data; 
     512        TnySummaryView *self = user_data; 
     513        TnyDemouiSummaryViewPriv *priv = TNY_DEMOUI_SUMMARY_VIEW_GET_PRIVATE (self); 
     514 
    499515        GtkTreeIter iter; 
    500516        GtkTreeModel *model; 
     
    576592                        tny_folder_refresh_async (folder,  
    577593                                refresh_current_folder,  
    578                                 refresh_current_folder_status_update, user_data); 
     594                                status_update, self); 
    579595 
    580596                        g_object_unref (G_OBJECT (folder)); 
     
    641657                tny_folder_refresh_async (merge,  
    642658                        refresh_current_folder,  
    643                         refresh_current_folder_status_update, user_data); 
     659