Changeset 1886
- Timestamp:
- 05/04/07 15:05:25
- Files:
-
- trunk/ChangeLog (modified) (2 diffs)
- trunk/libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-folder.c (modified) (13 diffs)
- trunk/libtinymail-camel/tny-camel-account-priv.h (modified) (1 diff)
- trunk/libtinymail-camel/tny-camel-account.c (modified) (4 diffs)
- trunk/libtinymail-camel/tny-camel-folder.c (modified) (17 diffs)
- trunk/libtinymail-queues/tny-get-msg-queue.c (modified) (1 diff)
- trunk/libtinymail/tny-merge-folder.c (modified) (1 diff)
- trunk/libtinymail/tny-shared.h (modified) (1 diff)
- trunk/tests/c-demo/tny-demoui-summary-view.c (modified) (10 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/ChangeLog
r1885 r1886 1 2007-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 1 11 2007-05-04 Murray Cumming <murrayc@murrayc.com> 2 12 3 13 * libtinymail/Makefile.am: 4 14 * libtinymail/tny-idle-stopper-priv.c: 5 * libtinymail/tny-idle-stopper-priv.h: Added a helper API to allow 2 or more6 idle handler callbacks to cooperate, so that one can stop the other one, in7 case they are called in an unexpected sequence, which happens when they8 have different idle priorities.9 See the API documentation here foremore 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. 10 20 11 21 * libtinymail-camel/tny-camel-folder.c: … … 13 23 (tny_camel_folder_refresh_async_callback), (destroy_progress_idle), 14 24 (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. 23 35 24 36 2007-05-04 Philip Van Hoof <pvanhoof@gnome.org> trunk/libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-folder.c
r1843 r1886 3886 3886 } 3887 3887 3888 camel_operation_start (NULL, _("Preparing to get message")); 3889 3888 3890 /* amcon = camel_imap_service_connect (CAMEL_SERVICE (store), ex); */ 3889 3891 amcon = camel_service_connect (CAMEL_SERVICE (store), ex); … … 3899 3901 } 3900 3902 camel_exception_clear (ex); 3903 3904 camel_operation_end (NULL); 3905 3906 camel_operation_start (NULL, _("Getting message")); 3901 3907 3902 3908 CAMEL_SERVICE_REC_LOCK(store, connect_lock); … … 3998 4004 rec += hread; 3999 4005 } 4006 camel_operation_progress (NULL, rec, length); 4000 4007 } 4001 4008 camel_stream_reset (stream); … … 4025 4032 guint taglen; 4026 4033 gboolean isnextdone = FALSE, hadr = FALSE; 4034 guint tread = 0, exread = 0; 4027 4035 4028 4036 nread = 0; … … 4050 4058 while (nread = camel_stream_buffer_gets (server_stream, line, MAX_LINE_LEN) > 0) 4051 4059 { 4060 tread += nread; 4052 4061 4053 4062 /* It might be the line before the last line */ … … 4064 4073 { err=TRUE; break; } 4065 4074 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 } 4067 4088 4068 4089 /* It's the last line (isnextdone will be ignored if that is the case) */ … … 4086 4107 4087 4108 linenum++; 4109 4110 camel_operation_progress (NULL, tread, exread); 4111 4088 4112 memset (line, 0, MAX_LINE_LEN); 4089 4113 } … … 4129 4153 guint taglen; 4130 4154 gboolean isnextdone = FALSE; 4155 guint tread = 0, exread = 0; 4131 4156 4132 4157 nread = 0; … … 4167 4192 while (nread = camel_stream_buffer_gets (server_stream, line, MAX_LINE_LEN) > 0) 4168 4193 { 4194 tread += nread; 4169 4195 4170 4196 /* It might be the line before the last line */ … … 4176 4202 { err=TRUE; break; } 4177 4203 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 4179 4218 4180 4219 /* It's the last line */ … … 4233 4272 camel_stream_write (stream, line, strlen (line)); 4234 4273 4274 camel_operation_progress (NULL, tread, exread); 4275 4235 4276 linenum++; 4236 4277 memset (line, 0, MAX_LINE_LEN); … … 4270 4311 camel_object_unref (CAMEL_OBJECT (store)); 4271 4312 4313 camel_operation_end (NULL); 4314 4272 4315 return stream; 4273 4316 … … 4295 4338 camel_object_unref (CAMEL_OBJECT (store)); 4296 4339 } 4340 4341 camel_operation_end (NULL); 4342 4297 4343 return NULL; 4298 4344 } trunk/libtinymail-camel/tny-camel-account-priv.h
r1498 r1886 48 48 const gchar* _tny_camel_account_get_url_string (TnyCamelAccount *self); 49 49 void _tny_camel_account_start_camel_operation (TnyCamelAccount *self, CamelOperationStatusFunc func, gpointer user_data, const gchar *what); 50 void _tny_camel_account_start_camel_operation_n (TnyCamelAccount *self, CamelOperationStatusFunc func, gpointer user_data, const gchar *what, gboolean cancel); 50 51 void _tny_camel_account_stop_camel_operation (TnyCamelAccount *self); 51 52 void _tny_camel_account_try_connect (TnyCamelAccount *self, GError **err); trunk/libtinymail-camel/tny-camel-account.c
r1866 r1886 284 284 285 285 void 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) 287 287 { 288 288 TnyCamelAccountPriv *priv = TNY_CAMEL_ACCOUNT_GET_PRIVATE (self); … … 292 292 g_mutex_lock (priv->cancel_lock); 293 293 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) 303 295 { 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) 308 300 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); 309 314 } 310 tny_camel_account_stop_camel_operation_priv (priv); 311 } 312 313 camel_operation_uncancel (NULL); 315 316 camel_operation_uncancel (NULL); 317 } 314 318 315 319 while (priv->inuse_spin); … … 317 321 priv->inuse_spin = TRUE; 318 322 319 320 323 priv->cancel = camel_operation_new (func, user_data); 321 324 322 325 camel_operation_ref (priv->cancel); 323 326 camel_operation_register (priv->cancel); … … 327 330 328 331 return; 332 } 333 334 void 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); 329 338 } 330 339 trunk/libtinymail-camel/tny-camel-folder.c
r1885 r1886 703 703 704 704 705 706 707 708 709 typedef 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 719 static void 720 destroy_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 738 static gboolean 739 progress_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 705 765 typedef struct 706 766 { … … 710 770 gpointer user_data; 711 771 gboolean cancelled; 712 713 772 /* This stops us from calling a status callback after the operation has 714 773 * finished. */ 715 774 TnyIdleStopper* stopper; 716 717 775 guint depth; 718 776 GError *err; … … 763 821 * by causing tny_idle_stopper_is_stopped() to return TRUE. */ 764 822 tny_idle_stopper_stop (info->stopper); 765 823 766 824 tny_folder_change_set_new_all_count (change, priv->cached_length); 767 825 tny_folder_change_set_new_unread_count (change, priv->unread_length); … … 771 829 return FALSE; 772 830 } 773 774 775 typedef struct776 {777 RefreshFolderInfo *minfo;778 gchar *what;779 gint sofar, oftotal;780 } ProgressInfo;781 782 static void783 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 gboolean803 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 callback809 * has already been called, because we should assume that810 * 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 }828 831 829 832 … … 851 854 852 855 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; 859 861 info->oftotal = oftotal; 860 862 861 863 /* Share the TnyIdleStopper, so one callback can tell the other to stop, 862 864 * because they may be called in an unexpected sequence: */ 863 865 /* 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); 865 867 866 868 if (info->oftotal < 1) … … 875 877 info->sofar = sofar; 876 878 877 /* gidle reference */878 g_object_ref (G_OBJECT (info->minfo->self));879 _tny_camel_folder_reason (priv);880 879 881 880 if (oinfo->depth > 0) … … 959 958 g_object_unref (G_OBJECT (self)); 960 959 _tny_camel_folder_unreason (priv); 961 962 960 } 963 961 g_thread_exit (NULL); … … 1213 1211 TnyStatusCallback status_callback; 1214 1212 TnySessionCamel *session; 1213 TnyIdleStopper *stopper; 1214 gboolean cancelled; 1215 1215 } GetMsgInfo; 1216 1216 … … 1229 1229 notify_folder_observers_about (info->self, change); 1230 1230 g_object_unref (G_OBJECT (change)); 1231 1232 1231 g_object_unref (G_OBJECT (info->msg)); 1233 1232 } … … 1242 1241 _tny_session_stop_operation (info->session); 1243 1242 1243 tny_idle_stopper_destroy (info->stopper); 1244 info->stopper = NULL; 1245 1244 1246 g_slice_free (GetMsgInfo, info); 1245 1247 } … … 1252 1254 1253 1255 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); 1255 1262 1256 1263 return FALSE; 1264 } 1265 1266 1267 static void 1268 tny_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; 1257 1311 } 1258 1312 … … 1263 1317 TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (info->self); 1264 1318 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"); 1265 1331 1266 1332 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); 1267 1340 1268 1341 if (err != NULL) … … 1305 1378 1306 1379 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 void1322 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 void1329 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 1341 1380 static void 1342 1381 tny_camel_folder_get_msg_async_default (TnyFolder *self, TnyHeader *header, TnyGetMsgCallback callback, TnyStatusCallback status_callback, gpointer user_data) … … 1351 1390 { 1352 1391 if (callback) 1353 callback (self, NULL, &err, user_data);1392 callback (self, TRUE, NULL, &err, user_data); 1354 1393 g_error_free (err); 1355 1394 return; … … 1357 1396 1358 1397 info = g_slice_new (GetMsgInfo); 1398 info->cancelled = FALSE; 1359 1399 info->session = TNY_FOLDER_PRIV_GET_SESSION (priv); 1360 1400 info->self = self; … … 1365 1405 info->depth = g_main_depth (); 1366 1406 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 1367 1413 /* thread reference */ 1368 1414 _tny_camel_folder_reason (priv); … … 1372 1418 thread = g_thread_create (tny_camel_folder_get_msg_async_thread, 1373 1419 info, FALSE, NULL); 1420 1421 return; 1422 } 1423 1424 1425 1426 static TnyMsgReceiveStrategy* 1427 tny_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 1432 static TnyMsgReceiveStrategy* 1433 tny_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 1440 static void 1441 tny_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 1447 static void 1448 tny_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))); 1374 1456 1375 1457 return; trunk/libtinymail-queues/tny-get-msg-queue.c
r1884 r1886 96 96 97 97 if (info->callback) 98 info->callback (folder, msg, &info->err, info->user_data);98 info->callback (folder, FALSE, msg, &info->err, info->user_data); 99 99 100 100 if (msg) trunk/libtinymail/tny-merge-folder.c
r1879 r1886 232 232 GetMsgInfo *info = (GetMsgInfo *) thr_user_data; 233 233 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); 236 236 237 237 return FALSE; trunk/libtinymail/tny-shared.h
r1869 r1886 54 54 typedef void (*TnyForgetPassFunc) (TnyAccount *self); 55 55 typedef void (*TnyRefreshFolderCallback) (TnyFolder *self, gboolean cancelled, GError **err, gpointer user_data); 56 typedef void (*TnyGetMsgCallback) (TnyFolder *folder, TnyMsg *msg, GError **err, gpointer user_data);56 typedef void (*TnyGetMsgCallback) (TnyFolder *folder, gboolean cancelled, TnyMsg *msg, GError **err, gpointer user_data); 57 57 typedef void (*TnyTransferMsgsCallback) (TnyFolder *folder, GError **err, gpointer user_data); 58 58 typedef void (*TnyStatusCallback) (GObject *self, TnyStatus *status, gpointer user_data); trunk/tests/c-demo/tny-demoui-summary-view.c
r1884 r1886 109 109 110 110 111 static gboolean 112 cleanup_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 123 static void 124 status_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 111 147 static void 112 148 set_header_view_model (GtkTreeView *header_view, GtkTreeModel *model) … … 356 392 357 393 static void 394 on_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 427 static void 358 428 on_header_view_tree_selection_changed (GtkTreeSelection *selection, 359 429 gpointer user_data) … … 375 445 { 376 446 TnyFolder *folder; 377 TnyMsg *msg;378 379 447 folder = tny_header_get_folder (header); 380 if ( G_LIKELY (folder))448 if (folder) 381 449 { 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); 409 454 g_object_unref (G_OBJECT (folder)); 410 455 } … … 420 465 } 421 466 422 static gboolean423 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 433 467 434 468 static void 435 469 refresh_current_folder (TnyFolder *folder, gboolean cancelled, GError **err, gpointer user_data) 436 470 { 437 TnyDemouiSummaryViewPriv *priv = user_data; 471 TnySummaryView *self = user_data; 472 TnyDemouiSummaryViewPriv *priv = TNY_DEMOUI_SUMMARY_VIEW_GET_PRIVATE (self); 473 438 474 GtkTreeModel *select_model; 439 475 … … 469 505 470 506 471 static void472 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 }493 507 494 508 static void … … 496 510 gpointer user_data) 497 511 { 498 TnyDemouiSummaryViewPriv *priv = user_data; 512 TnySummaryView *self = user_data; 513 TnyDemouiSummaryViewPriv *priv = TNY_DEMOUI_SUMMARY_VIEW_GET_PRIVATE (self); 514 499 515 GtkTreeIter iter; 500 516 GtkTreeModel *model; … … 576 592 tny_folder_refresh_async (folder, 577 593 refresh_current_folder, 578 refresh_current_folder_status_update, user_data);594 status_update, self); 579 595 580 596 g_object_unref (G_OBJECT (folder)); … … 641 657 tny_folder_refresh_async (merge, 642 658 refresh_current_folder, 643 refresh_current_folder_status_update, user_data);659
