Mercurial > pidgin
comparison src/protocols/sametime/sametime.c @ 11943:0110fc7c6a8a
[gaim-migrate @ 14234]
Bringing things up to date with the last Meanwhile release, 0.5.0 and the last
gaim-meanwhile plugin release, 1.2.5 (which should be the last plugin release
against oldstatus, if all goes well with HEAD and no major bugs crop up)
It builds, so that's a start. The status bits that have been empty since the
first import of the sametime stuff are still empty, but I'm going to try and
fill those in tomorrow. I've decided to try and start using HEAD actively, to
encourage me to get this freaking prpl fully functional.
committer: Tailor Script <tailor@pidgin.im>
| author | Christopher O'Brien <siege@pidgin.im> |
|---|---|
| date | Wed, 02 Nov 2005 03:39:03 +0000 |
| parents | fa742ad8068c |
| children | 47e1723a89d7 |
comparison
equal
deleted
inserted
replaced
| 11942:a24cfe32961a | 11943:0110fc7c6a8a |
|---|---|
| 19 along with this program; if not, write to the Free Software | 19 along with this program; if not, write to the Free Software |
| 20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, | 20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
| 21 USA. | 21 USA. |
| 22 */ | 22 */ |
| 23 | 23 |
| 24 | |
| 25 /* system includes */ | |
| 24 #include <stdlib.h> | 26 #include <stdlib.h> |
| 25 | 27 #include <time.h> |
| 28 | |
| 29 /* glib includes */ | |
| 30 #include <glib.h> | |
| 31 #include <glib/ghash.h> | |
| 32 #include <glib/glist.h> | |
| 33 | |
| 34 /* gaim includes */ | |
| 26 #include <internal.h> | 35 #include <internal.h> |
| 27 #include <gaim.h> | 36 #include <gaim.h> |
| 28 #include <config.h> | 37 #include <config.h> |
| 29 | 38 |
| 30 #include <account.h> | 39 #include <account.h> |
| 40 #include <prpl.h> | 49 #include <prpl.h> |
| 41 #include <request.h> | 50 #include <request.h> |
| 42 #include <util.h> | 51 #include <util.h> |
| 43 #include <version.h> | 52 #include <version.h> |
| 44 | 53 |
| 45 #include <glib.h> | 54 /* meanwhile includes */ |
| 46 #include <glib/ghash.h> | |
| 47 #include <glib/glist.h> | |
| 48 | |
| 49 #include <mw_cipher.h> | 55 #include <mw_cipher.h> |
| 50 #include <mw_common.h> | 56 #include <mw_common.h> |
| 51 #include <mw_error.h> | 57 #include <mw_error.h> |
| 52 #include <mw_service.h> | 58 #include <mw_service.h> |
| 53 #include <mw_session.h> | 59 #include <mw_session.h> |
| 54 #include <mw_srvc_aware.h> | 60 #include <mw_srvc_aware.h> |
| 55 #include <mw_srvc_conf.h> | 61 #include <mw_srvc_conf.h> |
| 56 #include <mw_srvc_ft.h> | 62 #include <mw_srvc_ft.h> |
| 57 #include <mw_srvc_im.h> | 63 #include <mw_srvc_im.h> |
| 64 #include <mw_srvc_place.h> | |
| 58 #include <mw_srvc_resolve.h> | 65 #include <mw_srvc_resolve.h> |
| 59 #include <mw_srvc_store.h> | 66 #include <mw_srvc_store.h> |
| 60 #include <mw_st_list.h> | 67 #include <mw_st_list.h> |
| 61 | 68 |
| 69 /* project includes */ | |
| 62 #include "sametime.h" | 70 #include "sametime.h" |
| 63 | 71 |
| 64 | 72 |
| 65 /* considering that there's no display of this information for prpls, | 73 /* considering that there's no display of this information for prpls, |
| 66 I don't know why I even bother providing these. Oh valiant reader, | 74 I don't know why I even bother providing these. Oh valiant reader, |
| 81 #define MW_PRPL_OPT_FORCE_LOGIN MW_PRPL_OPT_BASE "/force_login" | 89 #define MW_PRPL_OPT_FORCE_LOGIN MW_PRPL_OPT_BASE "/force_login" |
| 82 #define MW_PRPL_OPT_SAVE_DYNAMIC MW_PRPL_OPT_BASE "/save_dynamic" | 90 #define MW_PRPL_OPT_SAVE_DYNAMIC MW_PRPL_OPT_BASE "/save_dynamic" |
| 83 | 91 |
| 84 | 92 |
| 85 /* stages of connecting-ness */ | 93 /* stages of connecting-ness */ |
| 86 #define MW_CONNECT_STEPS 10 | 94 #define MW_CONNECT_STEPS 9 |
| 87 | 95 |
| 88 | 96 |
| 89 /* stages of conciousness */ | 97 /* stages of conciousness */ |
| 90 #define MW_STATE_OFFLINE "offline" | 98 #define MW_STATE_OFFLINE "offline" |
| 91 #define MW_STATE_ACTIVE "available" | 99 #define MW_STATE_ACTIVE "active" |
| 92 #define MW_STATE_AWAY "away" | 100 #define MW_STATE_AWAY "away" |
| 93 #define MW_STATE_BUSY "busy" | 101 #define MW_STATE_BUSY "dnd" |
| 94 #define MW_STATE_IDLE "idle" | 102 #define MW_STATE_MESSAGE "message" |
| 95 #define MW_STATE_UNKNOWN "unknown" | 103 #define MW_STATE_ENLIGHTENED "buddha" |
| 96 #define MW_STATE_BUDHA "enlightened" | |
| 97 | |
| 98 #define MW_STATE_MESSAGE "message" | |
| 99 | 104 |
| 100 | 105 |
| 101 /* keys to get/set chat information */ | 106 /* keys to get/set chat information */ |
| 102 #define CHAT_KEY_CREATOR "chat.creator" | 107 #define CHAT_KEY_CREATOR "chat.creator" |
| 103 #define CHAT_KEY_NAME "chat.name" | 108 #define CHAT_KEY_NAME "chat.name" |
| 104 #define CHAT_KEY_TOPIC "chat.topic" | 109 #define CHAT_KEY_TOPIC "chat.topic" |
| 105 #define CHAT_KEY_INVITE "chat.invite" | 110 #define CHAT_KEY_INVITE "chat.invite" |
| 111 #define CHAT_KEY_IS_PLACE "chat.is_place" | |
| 106 | 112 |
| 107 | 113 |
| 108 /* key for associating a mwLoginType with a buddy */ | 114 /* key for associating a mwLoginType with a buddy */ |
| 109 #define BUDDY_KEY_CLIENT "meanwhile.client" | 115 #define BUDDY_KEY_CLIENT "meanwhile.client" |
| 110 | 116 |
| 138 #define MW_KEY_ACTIVE_MSG "active_msg" | 144 #define MW_KEY_ACTIVE_MSG "active_msg" |
| 139 #define MW_KEY_AWAY_MSG "away_msg" | 145 #define MW_KEY_AWAY_MSG "away_msg" |
| 140 #define MW_KEY_BUSY_MSG "busy_msg" | 146 #define MW_KEY_BUSY_MSG "busy_msg" |
| 141 #define MW_KEY_MSG_PROMPT "msg_prompt" | 147 #define MW_KEY_MSG_PROMPT "msg_prompt" |
| 142 #define MW_KEY_INVITE "conf_invite" | 148 #define MW_KEY_INVITE "conf_invite" |
| 149 #define MW_KEY_ENCODING "encoding" | |
| 150 #define MW_KEY_FORCE "force_login" | |
| 143 | 151 |
| 144 | 152 |
| 145 /** number of seconds from the first blist change before a save to the | 153 /** number of seconds from the first blist change before a save to the |
| 146 storage service occurs. */ | 154 storage service occurs. */ |
| 147 #define BLIST_SAVE_SECONDS 15 | 155 #define BLIST_SAVE_SECONDS 15 |
| 148 | 156 |
| 149 | 157 |
| 150 /** blist storage option, local only */ | 158 /** the possible buddy list storage settings */ |
| 151 #define BLIST_CHOICE_NONE 1 | 159 enum blist_choice { |
| 152 | 160 blist_choice_LOCAL = 1, /**< local only */ |
| 153 /** blist storage option, load from server */ | 161 blist_choice_MERGE = 2, /**< merge from server */ |
| 154 #define BLIST_CHOICE_LOAD 2 | 162 blist_choice_STORE = 3, /**< merge from and save to server */ |
| 155 | 163 blist_choice_SYNCH = 4, /**< sync with server */ |
| 156 /** blist storage option, load and save to server */ | 164 }; |
| 157 #define BLIST_CHOICE_SAVE 3 | |
| 158 | |
| 159 /** blist storage option, server only */ | |
| 160 #define BLIST_CHOICE_SERVER 4 | |
| 161 | 165 |
| 162 | 166 |
| 163 /** the default blist storage option */ | 167 /** the default blist storage option */ |
| 164 #define BLIST_CHOICE_DEFAULT BLIST_CHOICE_SAVE | 168 #define BLIST_CHOICE_DEFAULT blist_choice_SYNCH |
| 165 | 169 |
| 166 | 170 |
| 167 /* testing for the above */ | 171 /* testing for the above */ |
| 168 #define BLIST_CHOICE_IS(n) (gaim_prefs_get_int(MW_PRPL_OPT_BLIST_ACTION)==(n)) | 172 #define BLIST_PREF_IS(n) (gaim_prefs_get_int(MW_PRPL_OPT_BLIST_ACTION)==(n)) |
| 169 #define BLIST_CHOICE_IS_NONE() BLIST_CHOICE_IS(BLIST_CHOICE_NONE) | 173 #define BLIST_PREF_IS_LOCAL() BLIST_PREF_IS(blist_choice_LOCAL) |
| 170 #define BLIST_CHOICE_IS_LOAD() BLIST_CHOICE_IS(BLIST_CHOICE_LOAD) | 174 #define BLIST_PREF_IS_MERGE() BLIST_PREF_IS(blist_choice_MERGE) |
| 171 #define BLIST_CHOICE_IS_SAVE() BLIST_CHOICE_IS(BLIST_CHOICE_SAVE) | 175 #define BLIST_PREF_IS_STORE() BLIST_PREF_IS(blist_choice_STORE) |
| 176 #define BLIST_PREF_IS_SYNCH() BLIST_PREF_IS(blist_choice_SYNCH) | |
| 172 | 177 |
| 173 | 178 |
| 174 /* debugging output */ | 179 /* debugging output */ |
| 175 #define DEBUG_ERROR(a...) gaim_debug_error(G_LOG_DOMAIN, a) | 180 #define DEBUG_ERROR(a...) gaim_debug_error(G_LOG_DOMAIN, a) |
| 176 #define DEBUG_INFO(a...) gaim_debug_info(G_LOG_DOMAIN, a) | 181 #define DEBUG_INFO(a...) gaim_debug_info(G_LOG_DOMAIN, a) |
| 204 | 209 |
| 205 struct mwServiceAware *srvc_aware; | 210 struct mwServiceAware *srvc_aware; |
| 206 struct mwServiceConference *srvc_conf; | 211 struct mwServiceConference *srvc_conf; |
| 207 struct mwServiceFileTransfer *srvc_ft; | 212 struct mwServiceFileTransfer *srvc_ft; |
| 208 struct mwServiceIm *srvc_im; | 213 struct mwServiceIm *srvc_im; |
| 214 struct mwServicePlace *srvc_place; | |
| 209 struct mwServiceResolve *srvc_resolve; | 215 struct mwServiceResolve *srvc_resolve; |
| 210 struct mwServiceStorage *srvc_store; | 216 struct mwServiceStorage *srvc_store; |
| 211 | 217 |
| 212 /** map of GaimGroup:mwAwareList and mwAwareList:GaimGroup */ | 218 /** map of GaimGroup:mwAwareList and mwAwareList:GaimGroup */ |
| 213 GHashTable *group_list_map; | 219 GHashTable *group_list_map; |
| 228 | 234 |
| 229 static void blist_store(struct mwGaimPluginData *pd); | 235 static void blist_store(struct mwGaimPluginData *pd); |
| 230 | 236 |
| 231 static void blist_schedule(struct mwGaimPluginData *pd); | 237 static void blist_schedule(struct mwGaimPluginData *pd); |
| 232 | 238 |
| 233 static void blist_import(GaimConnection *gc, struct mwSametimeList *stlist); | 239 static void blist_merge(GaimConnection *gc, struct mwSametimeList *stlist); |
| 240 | |
| 241 static void blist_sync(GaimConnection *gc, struct mwSametimeList *stlist); | |
| 242 | |
| 243 static gboolean buddy_is_external(GaimBuddy *b); | |
| 234 | 244 |
| 235 static void buddy_add(struct mwGaimPluginData *pd, GaimBuddy *buddy); | 245 static void buddy_add(struct mwGaimPluginData *pd, GaimBuddy *buddy); |
| 236 | 246 |
| 237 static GaimBuddy * | 247 static GaimBuddy * |
| 238 buddy_ensure(GaimConnection *gc, GaimGroup *group, | 248 buddy_ensure(GaimConnection *gc, GaimGroup *group, |
| 289 struct resolved_id { | 299 struct resolved_id { |
| 290 char *id; | 300 char *id; |
| 291 char *name; | 301 char *name; |
| 292 }; | 302 }; |
| 293 | 303 |
| 304 static struct resolved_id *resolved_id_new(const char *id, const char *name); | |
| 305 | |
| 306 static void resolved_id_free(struct resolved_id *rid); | |
| 307 | |
| 308 | |
| 309 /* connection functions */ | |
| 310 | |
| 311 static void connect_cb(gpointer data, gint source, GaimInputCondition cond); | |
| 312 | |
| 294 | 313 |
| 295 /* ----- session ------ */ | 314 /* ----- session ------ */ |
| 296 | 315 |
| 297 | 316 |
| 298 /** resolves a mwSession from a GaimConnection */ | 317 /** resolves a mwSession from a GaimConnection */ |
| 338 len -= ret; | 357 len -= ret; |
| 339 } | 358 } |
| 340 | 359 |
| 341 if(len > 0) { | 360 if(len > 0) { |
| 342 DEBUG_ERROR("write returned %i, %i bytes left unwritten\n", ret, len); | 361 DEBUG_ERROR("write returned %i, %i bytes left unwritten\n", ret, len); |
| 343 gaim_connection_error(pd->gc, "Connection closed (writing)"); | 362 gaim_connection_error(pd->gc, _("Connection closed (writing)")); |
| 344 | 363 |
| 345 #if 0 | 364 #if 0 |
| 346 close(pd->socket); | 365 close(pd->socket); |
| 347 pd->socket = 0; | 366 pd->socket = 0; |
| 348 #endif | 367 #endif |
| 406 static void mw_aware_list_on_aware(struct mwAwareList *list, | 425 static void mw_aware_list_on_aware(struct mwAwareList *list, |
| 407 struct mwAwareSnapshot *aware) { | 426 struct mwAwareSnapshot *aware) { |
| 408 | 427 |
| 409 GaimConnection *gc; | 428 GaimConnection *gc; |
| 410 GaimAccount *acct; | 429 GaimAccount *acct; |
| 430 | |
| 411 struct mwGaimPluginData *pd; | 431 struct mwGaimPluginData *pd; |
| 412 const char *status_id = MW_STATE_ACTIVE; | 432 time_t idle; |
| 413 gboolean idle = FALSE; | 433 guint stat; |
| 414 | 434 const char *id; |
| 415 guint stat = aware->status.status; | 435 const char *status = MW_STATE_ACTIVE; |
| 416 | |
| 417 const char *id = aware->id.user; | |
| 418 | 436 |
| 419 gc = mwAwareList_getClientData(list); | 437 gc = mwAwareList_getClientData(list); |
| 438 acct = gaim_connection_get_account(gc); | |
| 439 | |
| 420 pd = gc->proto_data; | 440 pd = gc->proto_data; |
| 421 acct = gaim_connection_get_account(gc); | 441 idle = aware->status.time; |
| 422 | 442 stat = aware->status.status; |
| 443 id = aware->id.user; | |
| 444 | |
| 445 /* not sure which client sends this yet */ | |
| 446 if(idle == 0xdeadbeef) { | |
| 447 /* knock knock! | |
| 448 who's there? | |
| 449 rude interrupting cow. | |
| 450 rude interr... | |
| 451 MOO! */ | |
| 452 idle = -1; | |
| 453 } | |
| 454 | |
| 423 switch(stat) { | 455 switch(stat) { |
| 456 case mwStatus_ACTIVE: | |
| 457 status = MW_STATE_ACTIVE; | |
| 458 idle = 0; | |
| 459 break; | |
| 460 | |
| 424 case mwStatus_IDLE: | 461 case mwStatus_IDLE: |
| 425 idle = TRUE; | 462 if(! idle) idle = -1; |
| 426 break; | 463 break; |
| 427 | 464 |
| 428 case mwStatus_AWAY: | 465 case mwStatus_AWAY: |
| 429 status_id = MW_STATE_AWAY; | 466 status = MW_STATE_AWAY; |
| 430 break; | 467 break; |
| 468 | |
| 431 case mwStatus_BUSY: | 469 case mwStatus_BUSY: |
| 432 status_id = MW_STATE_BUSY; | 470 status = MW_STATE_BUSY; |
| 433 break; | 471 break; |
| 434 } | 472 } |
| 435 | 473 |
| 474 /* NAB group members */ | |
| 436 if(aware->group) { | 475 if(aware->group) { |
| 437 GaimGroup *group; | 476 GaimGroup *group; |
| 438 GaimBuddy *buddy; | 477 GaimBuddy *buddy; |
| 439 GaimBlistNode *bnode; | 478 GaimBlistNode *bnode; |
| 440 | 479 |
| 449 buddy = gaim_buddy_new(acct, id, NULL); | 488 buddy = gaim_buddy_new(acct, id, NULL); |
| 450 gaim_blist_add_buddy(buddy, NULL, group, NULL); | 489 gaim_blist_add_buddy(buddy, NULL, group, NULL); |
| 451 | 490 |
| 452 bnode = (GaimBlistNode *) buddy; | 491 bnode = (GaimBlistNode *) buddy; |
| 453 | 492 |
| 454 /* mark buddy as transient if preferences do not indicate that | |
| 455 we should save the buddy between gaim sessions */ | |
| 456 if(! gaim_prefs_get_bool(MW_PRPL_OPT_SAVE_DYNAMIC)) | |
| 457 bnode->flags |= GAIM_BLIST_NODE_FLAG_NO_SAVE; | |
| 458 | |
| 459 srvc = pd->srvc_resolve; | 493 srvc = pd->srvc_resolve; |
| 460 query = g_list_append(NULL, (char *) id); | 494 query = g_list_append(NULL, (char *) id); |
| 461 | 495 |
| 462 mwServiceResolve_resolve(srvc, query, mwResolveFlag_USERS, | 496 mwServiceResolve_resolve(srvc, query, mwResolveFlag_USERS, |
| 463 blist_resolve_alias_cb, buddy, NULL); | 497 blist_resolve_alias_cb, buddy, NULL); |
| 498 g_list_free(query); | |
| 464 } | 499 } |
| 465 | 500 |
| 466 gaim_blist_node_set_int(bnode, BUDDY_KEY_TYPE, mwSametimeUser_NORMAL); | 501 gaim_blist_node_set_int(bnode, BUDDY_KEY_TYPE, mwSametimeUser_NORMAL); |
| 467 } | 502 } |
| 468 | 503 |
| 469 gaim_prpl_got_user_status(acct, id, status_id, NULL); | 504 gaim_prpl_got_user_status(acct, id, status, NULL); |
| 470 gaim_prpl_got_user_login_time(acct, id, aware->online - time(NULL)); | 505 gaim_prpl_got_user_idle(acct, id, !!idle, idle); |
| 471 | |
| 472 if (idle) | |
| 473 gaim_prpl_got_user_idle(acct, id, TRUE, -1); | |
| 474 else | |
| 475 gaim_prpl_got_user_idle(acct, id, FALSE, 0); | |
| 476 } | 506 } |
| 477 | 507 |
| 478 | 508 |
| 479 static void mw_aware_list_on_attrib(struct mwAwareList *list, | 509 static void mw_aware_list_on_attrib(struct mwAwareList *list, |
| 480 struct mwAwareIdBlock *id, | 510 struct mwAwareIdBlock *id, |
| 631 srvc = pd->srvc_store; | 661 srvc = pd->srvc_store; |
| 632 g_return_if_fail(srvc != NULL); | 662 g_return_if_fail(srvc != NULL); |
| 633 | 663 |
| 634 gc = pd->gc; | 664 gc = pd->gc; |
| 635 | 665 |
| 636 /* check if we should do this, according to user prefs */ | 666 if(BLIST_PREF_IS_LOCAL() || BLIST_PREF_IS_MERGE()) { |
| 637 if(! BLIST_CHOICE_IS_SAVE()) { | |
| 638 DEBUG_INFO("preferences indicate not to save remote blist\n"); | 667 DEBUG_INFO("preferences indicate not to save remote blist\n"); |
| 639 return; | 668 return; |
| 640 | 669 |
| 641 } else if(MW_SERVICE_IS_DEAD(srvc)) { | 670 } else if(MW_SERVICE_IS_DEAD(srvc)) { |
| 642 DEBUG_INFO("aborting save of blist: storage service is not alive\n"); | 671 DEBUG_INFO("aborting save of blist: storage service is not alive\n"); |
| 643 return; | 672 return; |
| 644 | 673 |
| 674 } else if(BLIST_PREF_IS_STORE() || BLIST_PREF_IS_SYNCH()) { | |
| 675 DEBUG_INFO("saving remote blist\n"); | |
| 676 | |
| 645 } else { | 677 } else { |
| 646 DEBUG_INFO("saving remote blist\n"); | 678 g_return_if_reached(); |
| 647 } | 679 } |
| 648 | 680 |
| 649 /* create and export to a list object */ | 681 /* create and export to a list object */ |
| 650 stlist = mwSametimeList_new(); | 682 stlist = mwSametimeList_new(); |
| 651 blist_export(gc, stlist); | 683 blist_export(gc, stlist); |
| 678 static void blist_schedule(struct mwGaimPluginData *pd) { | 710 static void blist_schedule(struct mwGaimPluginData *pd) { |
| 679 if(pd->save_event) return; | 711 if(pd->save_event) return; |
| 680 | 712 |
| 681 pd->save_event = gaim_timeout_add(BLIST_SAVE_SECONDS * 1000, | 713 pd->save_event = gaim_timeout_add(BLIST_SAVE_SECONDS * 1000, |
| 682 blist_save_cb, pd); | 714 blist_save_cb, pd); |
| 715 } | |
| 716 | |
| 717 | |
| 718 static gboolean buddy_is_external(GaimBuddy *b) { | |
| 719 g_return_val_if_fail(b != NULL, FALSE); | |
| 720 return g_str_has_prefix(b->name, "@E "); | |
| 683 } | 721 } |
| 684 | 722 |
| 685 | 723 |
| 686 /** Actually add a buddy to the aware service, and schedule the buddy | 724 /** Actually add a buddy to the aware service, and schedule the buddy |
| 687 list to be saved to the server */ | 725 list to be saved to the server */ |
| 800 return group; | 838 return group; |
| 801 } | 839 } |
| 802 | 840 |
| 803 | 841 |
| 804 /** merge the entries from a st list into the gaim blist */ | 842 /** merge the entries from a st list into the gaim blist */ |
| 805 static void blist_import(GaimConnection *gc, struct mwSametimeList *stlist) { | 843 static void blist_merge(GaimConnection *gc, struct mwSametimeList *stlist) { |
| 806 struct mwSametimeGroup *stgroup; | 844 struct mwSametimeGroup *stgroup; |
| 807 struct mwSametimeUser *stuser; | 845 struct mwSametimeUser *stuser; |
| 808 | 846 |
| 809 GaimGroup *group; | 847 GaimGroup *group; |
| 810 GaimBuddy *buddy; | 848 GaimBuddy *buddy; |
| 824 buddy = buddy_ensure(gc, group, stuser); | 862 buddy = buddy_ensure(gc, group, stuser); |
| 825 } | 863 } |
| 826 g_list_free(utl); | 864 g_list_free(utl); |
| 827 } | 865 } |
| 828 g_list_free(gtl); | 866 g_list_free(gtl); |
| 867 } | |
| 868 | |
| 869 | |
| 870 /** remove all buddies on account from group. If del is TRUE and group | |
| 871 is left empty, remove group as well */ | |
| 872 static void group_clear(GaimGroup *group, GaimAccount *acct, gboolean del) { | |
| 873 GaimConnection *gc; | |
| 874 GList *prune = NULL; | |
| 875 GaimBlistNode *gn, *cn, *bn; | |
| 876 | |
| 877 g_return_if_fail(group != NULL); | |
| 878 | |
| 879 DEBUG_INFO("clearing members from pruned group %s\n", NSTR(group->name)); | |
| 880 | |
| 881 gc = gaim_account_get_connection(acct); | |
| 882 g_return_if_fail(gc != NULL); | |
| 883 | |
| 884 gn = (GaimBlistNode *) group; | |
| 885 | |
| 886 for(cn = gn->child; cn; cn = cn->next) { | |
| 887 if(! GAIM_BLIST_NODE_IS_CONTACT(cn)) continue; | |
| 888 | |
| 889 for(bn = cn->child; bn; bn = bn->next) { | |
| 890 GaimBuddy *gb = (GaimBuddy *) bn; | |
| 891 | |
| 892 if(! GAIM_BLIST_NODE_IS_BUDDY(bn)) continue; | |
| 893 | |
| 894 if(gb->account == acct) { | |
| 895 DEBUG_INFO("clearing %s from group\n", NSTR(gb->name)); | |
| 896 prune = g_list_prepend(prune, gb); | |
| 897 } | |
| 898 } | |
| 899 } | |
| 900 | |
| 901 /* quickly unsubscribe from presence for the entire group */ | |
| 902 gaim_account_remove_group(acct, group); | |
| 903 | |
| 904 /* remove blist entries that need to go */ | |
| 905 while(prune) { | |
| 906 gaim_blist_remove_buddy(prune->data); | |
| 907 prune = g_list_delete_link(prune, prune); | |
| 908 } | |
| 909 DEBUG_INFO("cleared buddies\n"); | |
| 910 | |
| 911 /* optionally remove group from blist */ | |
| 912 if(del && !gaim_blist_get_group_size(group, TRUE)) { | |
| 913 DEBUG_INFO("removing empty group\n"); | |
| 914 gaim_blist_remove_group(group); | |
| 915 } | |
| 916 } | |
| 917 | |
| 918 | |
| 919 /** prune out group members that shouldn't be there */ | |
| 920 static void group_prune(GaimConnection *gc, GaimGroup *group, | |
| 921 struct mwSametimeGroup *stgroup) { | |
| 922 | |
| 923 GaimAccount *acct; | |
| 924 GaimBlistNode *gn, *cn, *bn; | |
| 925 | |
| 926 GHashTable *stusers; | |
| 927 GList *prune = NULL; | |
| 928 GList *ul, *utl; | |
| 929 | |
| 930 g_return_if_fail(group != NULL); | |
| 931 | |
| 932 DEBUG_INFO("pruning membership of group %s\n", NSTR(group->name)); | |
| 933 | |
| 934 acct = gaim_connection_get_account(gc); | |
| 935 g_return_if_fail(acct != NULL); | |
| 936 | |
| 937 stusers = g_hash_table_new(g_str_hash, g_str_equal); | |
| 938 | |
| 939 /* build a hash table for quick lookup while pruning the group | |
| 940 contents */ | |
| 941 utl = mwSametimeGroup_getUsers(stgroup); | |
| 942 for(ul = utl; ul; ul = ul->next) { | |
| 943 const char *id = mwSametimeUser_getUser(ul->data); | |
| 944 g_hash_table_insert(stusers, (char *) id, ul->data); | |
| 945 DEBUG_INFO("server copy has %s\n", NSTR(id)); | |
| 946 } | |
| 947 g_list_free(utl); | |
| 948 | |
| 949 gn = (GaimBlistNode *) group; | |
| 950 | |
| 951 for(cn = gn->child; cn; cn = cn->next) { | |
| 952 if(! GAIM_BLIST_NODE_IS_CONTACT(cn)) continue; | |
| 953 | |
| 954 for(bn = cn->child; bn; bn = bn->next) { | |
| 955 GaimBuddy *gb = (GaimBuddy *) bn; | |
| 956 | |
| 957 if(! GAIM_BLIST_NODE_IS_BUDDY(bn)) continue; | |
| 958 | |
| 959 /* if the account is correct and they're not in our table, mark | |
| 960 them for pruning */ | |
| 961 if(gb->account == acct && !g_hash_table_lookup(stusers, gb->name)) { | |
| 962 DEBUG_INFO("marking %s for pruning\n", NSTR(gb->name)); | |
| 963 prune = g_list_prepend(prune, gb); | |
| 964 } | |
| 965 } | |
| 966 } | |
| 967 DEBUG_INFO("done marking\n"); | |
| 968 | |
| 969 g_hash_table_destroy(stusers); | |
| 970 | |
| 971 if(prune) { | |
| 972 gaim_account_remove_buddies(acct, prune, NULL); | |
| 973 while(prune) { | |
| 974 gaim_blist_remove_buddy(prune->data); | |
| 975 prune = g_list_delete_link(prune, prune); | |
| 976 } | |
| 977 } | |
| 978 } | |
| 979 | |
| 980 | |
| 981 /** synch the entries from a st list into the gaim blist, removing any | |
| 982 existing buddies that aren't in the st list */ | |
| 983 static void blist_sync(GaimConnection *gc, struct mwSametimeList *stlist) { | |
| 984 | |
| 985 GaimAccount *acct; | |
| 986 GaimBuddyList *blist; | |
| 987 GaimBlistNode *gn; | |
| 988 | |
| 989 GHashTable *stgroups; | |
| 990 GList *g_prune = NULL; | |
| 991 | |
| 992 GList *gl, *gtl; | |
| 993 | |
| 994 const char *acct_n; | |
| 995 | |
| 996 DEBUG_INFO("synchronizing local buddy list from server list\n"); | |
| 997 | |
| 998 acct = gaim_connection_get_account(gc); | |
| 999 g_return_if_fail(acct != NULL); | |
| 1000 | |
| 1001 acct_n = gaim_account_get_username(acct); | |
| 1002 | |
| 1003 blist = gaim_get_blist(); | |
| 1004 g_return_if_fail(blist != NULL); | |
| 1005 | |
| 1006 /* build a hash table for quick lookup while pruning the local | |
| 1007 list, mapping group name to group structure */ | |
| 1008 stgroups = g_hash_table_new(g_str_hash, g_str_equal); | |
| 1009 | |
| 1010 gtl = mwSametimeList_getGroups(stlist); | |
| 1011 for(gl = gtl; gl; gl = gl->next) { | |
| 1012 const char *name = mwSametimeGroup_getName(gl->data); | |
| 1013 g_hash_table_insert(stgroups, (char *) name, gl->data); | |
| 1014 } | |
| 1015 g_list_free(gtl); | |
| 1016 | |
| 1017 /* find all groups which should be pruned from the local list */ | |
| 1018 for(gn = blist->root; gn; gn = gn->next) { | |
| 1019 GaimGroup *grp = (GaimGroup *) gn; | |
| 1020 const char *gname, *owner; | |
| 1021 struct mwSametimeGroup *stgrp; | |
| 1022 | |
| 1023 if(! GAIM_BLIST_NODE_IS_GROUP(gn)) continue; | |
| 1024 | |
| 1025 /* group not belonging to this account */ | |
| 1026 if(! gaim_group_on_account(grp, acct)) | |
| 1027 continue; | |
| 1028 | |
| 1029 /* dynamic group belonging to this account. don't prune contents */ | |
| 1030 owner = gaim_blist_node_get_string(gn, GROUP_KEY_OWNER); | |
| 1031 if(owner && !strcmp(owner, acct_n)) | |
| 1032 continue; | |
| 1033 | |
| 1034 /* we actually are synching by this key as opposed to the group | |
| 1035 title, which can be different things in the st list */ | |
| 1036 gname = gaim_blist_node_get_string(gn, GROUP_KEY_NAME); | |
| 1037 if(! gname) gname = grp->name; | |
| 1038 | |
| 1039 stgrp = g_hash_table_lookup(stgroups, gname); | |
| 1040 if(! stgrp) { | |
| 1041 /* remove the whole group */ | |
| 1042 DEBUG_INFO("marking group %s for pruning\n", grp->name); | |
| 1043 g_prune = g_list_prepend(g_prune, grp); | |
| 1044 | |
| 1045 } else { | |
| 1046 /* synch the group contents */ | |
| 1047 group_prune(gc, grp, stgrp); | |
| 1048 } | |
| 1049 } | |
| 1050 DEBUG_INFO("done marking groups\n"); | |
| 1051 | |
| 1052 /* don't need this anymore */ | |
| 1053 g_hash_table_destroy(stgroups); | |
| 1054 | |
| 1055 /* prune all marked groups */ | |
| 1056 while(g_prune) { | |
| 1057 GaimGroup *grp = g_prune->data; | |
| 1058 GaimBlistNode *gn = (GaimBlistNode *) grp; | |
| 1059 const char *owner; | |
| 1060 gboolean del = TRUE; | |
| 1061 | |
| 1062 owner = gaim_blist_node_get_string(gn, GROUP_KEY_OWNER); | |
| 1063 if(owner && strcmp(owner, acct_n)) { | |
| 1064 /* it's a specialty group belonging to another account with some | |
| 1065 of our members in it, so don't fully delete it */ | |
| 1066 del = FALSE; | |
| 1067 } | |
| 1068 | |
| 1069 group_clear(g_prune->data, acct, del); | |
| 1070 g_prune = g_list_delete_link(g_prune, g_prune); | |
| 1071 } | |
| 1072 | |
| 1073 /* done with the pruning, let's merge in the additions */ | |
| 1074 blist_merge(gc, stlist); | |
| 829 } | 1075 } |
| 830 | 1076 |
| 831 | 1077 |
| 832 /** callback passed to the storage service when it's told to load the | 1078 /** callback passed to the storage service when it's told to load the |
| 833 st list */ | 1079 st list */ |
| 842 struct mwGetBuffer *b; | 1088 struct mwGetBuffer *b; |
| 843 | 1089 |
| 844 g_return_if_fail(result == ERR_SUCCESS); | 1090 g_return_if_fail(result == ERR_SUCCESS); |
| 845 | 1091 |
| 846 /* check our preferences for loading */ | 1092 /* check our preferences for loading */ |
| 847 if(BLIST_CHOICE_IS_NONE()) { | 1093 if(BLIST_PREF_IS_LOCAL()) { |
| 848 DEBUG_INFO("preferences indicate not to load remote buddy list\n"); | 1094 DEBUG_INFO("preferences indicate not to load remote buddy list\n"); |
| 849 return; | 1095 return; |
| 850 } | 1096 } |
| 851 | 1097 |
| 852 b = mwGetBuffer_wrap(mwStorageUnit_asOpaque(item)); | 1098 b = mwGetBuffer_wrap(mwStorageUnit_asOpaque(item)); |
| 853 | 1099 |
| 854 stlist = mwSametimeList_new(); | 1100 stlist = mwSametimeList_new(); |
| 855 mwSametimeList_get(b, stlist); | 1101 mwSametimeList_get(b, stlist); |
| 856 | 1102 |
| 857 s = mwService_getSession(MW_SERVICE(srvc)); | 1103 s = mwService_getSession(MW_SERVICE(srvc)); |
| 858 blist_import(pd->gc, stlist); | 1104 |
| 1105 /* merge or synch depending on preferences */ | |
| 1106 if(BLIST_PREF_IS_MERGE() || BLIST_PREF_IS_STORE()) { | |
| 1107 blist_merge(pd->gc, stlist); | |
| 1108 | |
| 1109 } else if(BLIST_PREF_IS_SYNCH()) { | |
| 1110 blist_sync(pd->gc, stlist); | |
| 1111 } | |
| 859 | 1112 |
| 860 mwSametimeList_free(stlist); | 1113 mwSametimeList_free(stlist); |
| 861 } | 1114 } |
| 862 | 1115 |
| 863 | 1116 |
| 926 | 1179 |
| 927 g_free(msg); | 1180 g_free(msg); |
| 928 msg = NULL; | 1181 msg = NULL; |
| 929 | 1182 |
| 930 #if 0 | 1183 #if 0 |
| 931 /* XXX */ | 1184 /* XXX resets the status, thus updating the message */ |
| 932 if(!gc->away_state || !strcmp(gc->away_state, MW_STATE_ACTIVE)) { | 1185 if(!gc->away_state || !strcmp(gc->away_state, MW_STATE_ACTIVE)) { |
| 933 msg = MW_STATE_ACTIVE; | 1186 msg = MW_STATE_ACTIVE; |
| 934 } else if(gc->away_state && !strcmp(gc->away_state, MW_STATE_AWAY)) { | 1187 } else if(gc->away_state && !strcmp(gc->away_state, MW_STATE_AWAY)) { |
| 935 msg = MW_STATE_AWAY; | 1188 msg = MW_STATE_AWAY; |
| 936 } else if(gc->away_state && !strcmp(gc->away_state, MW_STATE_BUSY)) { | 1189 } else if(gc->away_state && !strcmp(gc->away_state, MW_STATE_BUSY)) { |
| 937 msg = MW_STATE_BUSY; | 1190 msg = MW_STATE_BUSY; |
| 938 } | 1191 } |
| 939 | 1192 |
| 940 if(msg) | 1193 if(msg) serv_set_away(gc, msg, NULL); |
| 941 serv_set_away(gc, msg, NULL); | |
| 942 #endif | 1194 #endif |
| 943 } | 1195 } |
| 944 | 1196 |
| 945 | 1197 |
| 946 /** signal triggered when a conversation is opened in Gaim */ | 1198 /** signal triggered when a conversation is opened in Gaim */ |
| 952 message is sent before offering NotesBuddy features. Therefore | 1204 message is sent before offering NotesBuddy features. Therefore |
| 953 whenever Gaim creates a conversation, we'll immediately open the | 1205 whenever Gaim creates a conversation, we'll immediately open the |
| 954 channel to the other side and figure out what the target can | 1206 channel to the other side and figure out what the target can |
| 955 handle. Unfortunately, this makes us vulnerable to Psychic Mode, | 1207 handle. Unfortunately, this makes us vulnerable to Psychic Mode, |
| 956 whereas a more lazy negotiation based on the first message | 1208 whereas a more lazy negotiation based on the first message |
| 957 isn't */ | 1209 would not */ |
| 958 | 1210 |
| 959 GaimConnection *gc; | 1211 GaimConnection *gc; |
| 960 struct mwIdBlock who = { 0, 0 }; | 1212 struct mwIdBlock who = { 0, 0 }; |
| 961 struct mwConversation *conv; | 1213 struct mwConversation *conv; |
| 962 | 1214 |
| 995 | 1247 |
| 996 str = g_string_new(NULL); | 1248 str = g_string_new(NULL); |
| 997 | 1249 |
| 998 tmp = (char *) gaim_blist_node_get_string(node, GROUP_KEY_NAME); | 1250 tmp = (char *) gaim_blist_node_get_string(node, GROUP_KEY_NAME); |
| 999 | 1251 |
| 1000 g_string_append_printf(str, "<b>Group Title:</b> %s<br>", group->name); | 1252 g_string_append_printf(str, _("<b>Group Title:</b> %s<br>"), group->name); |
| 1001 g_string_append_printf(str, "<b>Notes Group ID:</b> %s<br>", tmp); | 1253 g_string_append_printf(str, _("<b>Notes Group ID:</b> %s<br>"), tmp); |
| 1002 | 1254 |
| 1003 tmp = g_strdup_printf("Info for Group %s", group->name); | 1255 tmp = g_strdup_printf(_("Info for Group %s"), group->name); |
| 1004 | 1256 |
| 1005 gaim_notify_formatted(gc, tmp, "Notes Address Book Information", | 1257 gaim_notify_formatted(gc, tmp, _("Notes Address Book Information"), |
| 1006 NULL, str->str, NULL, NULL); | 1258 NULL, str->str, NULL, NULL); |
| 1007 | 1259 |
| 1008 g_free(tmp); | 1260 g_free(tmp); |
| 1009 g_string_free(str, TRUE); | 1261 g_string_free(str, TRUE); |
| 1010 } | 1262 } |
| 1027 acct = gaim_accounts_find(owner, PLUGIN_ID); | 1279 acct = gaim_accounts_find(owner, PLUGIN_ID); |
| 1028 if(! acct) return; | 1280 if(! acct) return; |
| 1029 if(! gaim_account_is_connected(acct)) return; | 1281 if(! gaim_account_is_connected(acct)) return; |
| 1030 if(acct != gaim_connection_get_account(pd->gc)) return; | 1282 if(acct != gaim_connection_get_account(pd->gc)) return; |
| 1031 | 1283 |
| 1032 act = gaim_blist_node_action_new("Get Notes Address Book Info", | 1284 act = gaim_blist_node_action_new(_("Get Notes Address Book Info"), |
| 1033 blist_menu_nab, pd, NULL); | 1285 blist_menu_nab, pd, NULL); |
| 1034 | 1286 |
| 1035 *menu = g_list_append(*menu, NULL); | 1287 *menu = g_list_append(*menu, NULL); |
| 1036 *menu = g_list_append(*menu, act); | 1288 *menu = g_list_append(*menu, act); |
| 1037 } | 1289 } |
| 1106 mwServiceAware_setAttributeBoolean(pd->srvc_aware, | 1358 mwServiceAware_setAttributeBoolean(pd->srvc_aware, |
| 1107 mwAttribute_FILE_TRANSFER, TRUE); | 1359 mwAttribute_FILE_TRANSFER, TRUE); |
| 1108 } | 1360 } |
| 1109 | 1361 |
| 1110 | 1362 |
| 1363 static void session_loginRedirect(struct mwSession *session, | |
| 1364 const char *host) { | |
| 1365 struct mwGaimPluginData *pd; | |
| 1366 GaimConnection *gc; | |
| 1367 GaimAccount *account; | |
| 1368 guint port; | |
| 1369 | |
| 1370 pd = mwSession_getClientData(session); | |
| 1371 gc = pd->gc; | |
| 1372 account = gaim_connection_get_account(gc); | |
| 1373 port = gaim_account_get_int(account, MW_KEY_PORT, MW_PLUGIN_DEFAULT_PORT); | |
| 1374 | |
| 1375 if(gaim_account_get_bool(account, MW_KEY_FORCE, FALSE) || | |
| 1376 gaim_proxy_connect(account, host, port, connect_cb, pd)) { | |
| 1377 | |
| 1378 mwSession_forceLogin(session); | |
| 1379 } | |
| 1380 } | |
| 1381 | |
| 1382 | |
| 1111 /** called from mw_session_stateChange when the session's state is | 1383 /** called from mw_session_stateChange when the session's state is |
| 1112 mwSession_STARTED. Any finalizing of start-up stuff should go | 1384 mwSession_STARTED. Any finalizing of start-up stuff should go |
| 1113 here */ | 1385 here */ |
| 1114 static void session_started(struct mwGaimPluginData *pd) { | 1386 static void session_started(struct mwGaimPluginData *pd) { |
| 1115 | 1387 |
| 1119 services_starting(pd); | 1391 services_starting(pd); |
| 1120 } | 1392 } |
| 1121 | 1393 |
| 1122 | 1394 |
| 1123 static void mw_session_stateChange(struct mwSession *session, | 1395 static void mw_session_stateChange(struct mwSession *session, |
| 1124 enum mwSessionState state, guint32 info) { | 1396 enum mwSessionState state, |
| 1397 gpointer info) { | |
| 1125 struct mwGaimPluginData *pd; | 1398 struct mwGaimPluginData *pd; |
| 1126 GaimConnection *gc; | 1399 GaimConnection *gc; |
| 1127 char *msg = NULL; | 1400 char *msg = NULL; |
| 1128 | 1401 |
| 1129 pd = mwSession_getClientData(session); | 1402 pd = mwSession_getClientData(session); |
| 1151 break; | 1424 break; |
| 1152 | 1425 |
| 1153 case mwSession_LOGIN_REDIR: | 1426 case mwSession_LOGIN_REDIR: |
| 1154 msg = _("Login Redirected"); | 1427 msg = _("Login Redirected"); |
| 1155 gaim_connection_update_progress(gc, msg, 6, MW_CONNECT_STEPS); | 1428 gaim_connection_update_progress(gc, msg, 6, MW_CONNECT_STEPS); |
| 1429 session_loginRedirect(session, info); | |
| 1156 break; | 1430 break; |
| 1157 | 1431 |
| 1158 case mwSession_LOGIN_CONT: | 1432 case mwSession_LOGIN_CONT: |
| 1159 msg = _("Forcing Login"); | 1433 msg = _("Forcing Login"); |
| 1160 gaim_connection_update_progress(gc, msg, 7, MW_CONNECT_STEPS); | 1434 gaim_connection_update_progress(gc, msg, 7, MW_CONNECT_STEPS); |
| 1166 | 1440 |
| 1167 case mwSession_STARTED: | 1441 case mwSession_STARTED: |
| 1168 msg = _("Connected to Sametime Community Server"); | 1442 msg = _("Connected to Sametime Community Server"); |
| 1169 gaim_connection_update_progress(gc, msg, 9, MW_CONNECT_STEPS); | 1443 gaim_connection_update_progress(gc, msg, 9, MW_CONNECT_STEPS); |
| 1170 gaim_connection_set_state(gc, GAIM_CONNECTED); | 1444 gaim_connection_set_state(gc, GAIM_CONNECTED); |
| 1171 /* XXX serv_finish_login(gc); */ | |
| 1172 | 1445 |
| 1173 session_started(pd); | 1446 session_started(pd); |
| 1174 break; | 1447 break; |
| 1175 | 1448 |
| 1176 case mwSession_STOPPING: | 1449 case mwSession_STOPPING: |
| 1177 if(info & ERR_FAILURE) { | 1450 if(GPOINTER_TO_UINT(info) & ERR_FAILURE) { |
| 1178 msg = mwError(info); | 1451 msg = mwError(GPOINTER_TO_UINT(info)); |
| 1179 gaim_connection_error(gc, msg); | 1452 gaim_connection_error(gc, msg); |
| 1180 g_free(msg); | 1453 g_free(msg); |
| 1181 } | 1454 } |
| 1182 break; | 1455 break; |
| 1183 | 1456 |
| 1285 GaimInputCondition cond) { | 1558 GaimInputCondition cond) { |
| 1286 | 1559 |
| 1287 struct mwGaimPluginData *pd = data; | 1560 struct mwGaimPluginData *pd = data; |
| 1288 int ret = 0, err = 0; | 1561 int ret = 0, err = 0; |
| 1289 | 1562 |
| 1563 /* How the heck can this happen? Fix submitted to Gaim so that it | |
| 1564 won't happen anymore. */ | |
| 1290 if(! cond) return; | 1565 if(! cond) return; |
| 1291 | 1566 |
| 1292 g_return_if_fail(pd != NULL); | 1567 g_return_if_fail(pd != NULL); |
| 1293 g_return_if_fail(cond & GAIM_INPUT_READ); | 1568 g_return_if_fail(cond & GAIM_INPUT_READ); |
| 1294 | 1569 |
| 1313 pd->gc->inpa = 0; | 1588 pd->gc->inpa = 0; |
| 1314 } | 1589 } |
| 1315 | 1590 |
| 1316 if(! ret) { | 1591 if(! ret) { |
| 1317 DEBUG_INFO("connection reset\n"); | 1592 DEBUG_INFO("connection reset\n"); |
| 1318 gaim_connection_error(pd->gc, "Connection reset"); | 1593 gaim_connection_error(pd->gc, _("Connection reset")); |
| 1319 | 1594 |
| 1320 } else if(ret < 0) { | 1595 } else if(ret < 0) { |
| 1321 char *msg = strerror(err); | 1596 char *msg = strerror(err); |
| 1322 | 1597 |
| 1323 DEBUG_INFO("error in read callback: %s\n", msg); | 1598 DEBUG_INFO("error in read callback: %s\n", msg); |
| 1324 | 1599 |
| 1325 msg = g_strdup_printf("Error reading from socket: %s", msg); | 1600 msg = g_strdup_printf(_("Error reading from socket: %s"), msg); |
| 1326 gaim_connection_error(pd->gc, msg); | 1601 gaim_connection_error(pd->gc, msg); |
| 1327 g_free(msg); | 1602 g_free(msg); |
| 1328 } | 1603 } |
| 1329 } | 1604 } |
| 1330 | 1605 |
| 1349 /* this is a redirect connect, force login on existing socket */ | 1624 /* this is a redirect connect, force login on existing socket */ |
| 1350 mwSession_forceLogin(pd->session); | 1625 mwSession_forceLogin(pd->session); |
| 1351 | 1626 |
| 1352 } else { | 1627 } else { |
| 1353 /* this is a regular connect, error out */ | 1628 /* this is a regular connect, error out */ |
| 1354 gaim_connection_error(pd->gc, "Unable to connect to host"); | 1629 gaim_connection_error(pd->gc, _("Unable to connect to host")); |
| 1355 } | 1630 } |
| 1356 | 1631 |
| 1357 return; | 1632 return; |
| 1358 } | 1633 } |
| 1359 | 1634 |
| 1367 | 1642 |
| 1368 mwSession_start(pd->session); | 1643 mwSession_start(pd->session); |
| 1369 } | 1644 } |
| 1370 | 1645 |
| 1371 | 1646 |
| 1372 static void mw_session_loginRedirect(struct mwSession *session, | 1647 static void mw_session_announce(struct mwSession *s, |
| 1373 const char *host) { | 1648 struct mwLoginInfo *from, |
| 1374 | 1649 gboolean may_reply, |
| 1650 const char *text) { | |
| 1375 struct mwGaimPluginData *pd; | 1651 struct mwGaimPluginData *pd; |
| 1376 GaimConnection *gc; | 1652 GaimAccount *acct; |
| 1377 GaimAccount *account; | 1653 GaimConversation *conv; |
| 1378 guint port; | 1654 GSList *buddies; |
| 1379 | 1655 char *who = from->user_id; |
| 1380 pd = mwSession_getClientData(session); | 1656 char *msg; |
| 1381 gc = pd->gc; | 1657 |
| 1382 account = gaim_connection_get_account(gc); | 1658 pd = mwSession_getClientData(s); |
| 1383 port = gaim_account_get_int(account, "port", MW_PLUGIN_DEFAULT_PORT); | 1659 acct = gaim_connection_get_account(pd->gc); |
| 1384 | 1660 conv = gaim_find_conversation_with_account(GAIM_CONV_TYPE_IM, who, acct); |
| 1385 if(gaim_prefs_get_bool(MW_PRPL_OPT_FORCE_LOGIN) || | 1661 if(! conv) conv = gaim_conversation_new(GAIM_CONV_TYPE_IM, acct, who); |
| 1386 gaim_proxy_connect(account, host, port, connect_cb, pd)) { | 1662 |
| 1387 | 1663 buddies = gaim_find_buddies(acct, who); |
| 1388 mwSession_forceLogin(session); | 1664 if(buddies) { |
| 1389 } | 1665 who = (char *) gaim_buddy_get_contact_alias(buddies->data); |
| 1666 g_slist_free(buddies); | |
| 1667 } | |
| 1668 | |
| 1669 who = g_strdup_printf(_("Announcement from %s"), who); | |
| 1670 msg = gaim_markup_linkify(text); | |
| 1671 | |
| 1672 gaim_conversation_write(conv, who, msg, GAIM_MESSAGE_RECV, time(NULL)); | |
| 1673 g_free(who); | |
| 1674 g_free(msg); | |
| 1390 } | 1675 } |
| 1391 | 1676 |
| 1392 | 1677 |
| 1393 static struct mwSessionHandler mw_session_handler = { | 1678 static struct mwSessionHandler mw_session_handler = { |
| 1394 .io_write = mw_session_io_write, | 1679 .io_write = mw_session_io_write, |
| 1396 .clear = mw_session_clear, | 1681 .clear = mw_session_clear, |
| 1397 .on_stateChange = mw_session_stateChange, | 1682 .on_stateChange = mw_session_stateChange, |
| 1398 .on_setPrivacyInfo = mw_session_setPrivacyInfo, | 1683 .on_setPrivacyInfo = mw_session_setPrivacyInfo, |
| 1399 .on_setUserStatus = mw_session_setUserStatus, | 1684 .on_setUserStatus = mw_session_setUserStatus, |
| 1400 .on_admin = mw_session_admin, | 1685 .on_admin = mw_session_admin, |
| 1401 .on_loginRedirect = mw_session_loginRedirect, | 1686 .on_announce = mw_session_announce, |
| 1402 }; | 1687 }; |
| 1403 | 1688 |
| 1404 | 1689 |
| 1405 static void mw_aware_on_attrib(struct mwServiceAware *srvc, | 1690 static void mw_aware_on_attrib(struct mwServiceAware *srvc, |
| 1406 struct mwAwareAttribute *attrib) { | 1691 struct mwAwareAttribute *attrib) { |
| 1550 pd = mwSession_getClientData(session); | 1835 pd = mwSession_getClientData(session); |
| 1551 gc = pd->gc; | 1836 gc = pd->gc; |
| 1552 | 1837 |
| 1553 serv_got_chat_left(gc, CONF_TO_ID(conf)); | 1838 serv_got_chat_left(gc, CONF_TO_ID(conf)); |
| 1554 | 1839 |
| 1555 gaim_notify_error(gc, "Conference Closed", NULL, msg); | 1840 gaim_notify_error(gc, _("Conference Closed"), NULL, msg); |
| 1556 g_free(msg); | 1841 g_free(msg); |
| 1557 } | 1842 } |
| 1558 | 1843 |
| 1559 | 1844 |
| 1560 static void mw_conf_peer_joined(struct mwConference *conf, | 1845 static void mw_conf_peer_joined(struct mwConference *conf, |
| 1969 gc = pd->gc; | 2254 gc = pd->gc; |
| 1970 acct = gaim_connection_get_account(gc); | 2255 acct = gaim_connection_get_account(gc); |
| 1971 | 2256 |
| 1972 idb = mwConversation_getTarget(conv); | 2257 idb = mwConversation_getTarget(conv); |
| 1973 | 2258 |
| 1974 return gaim_find_conversation_with_account(GAIM_CONV_TYPE_IM,idb->user, acct); | 2259 return gaim_find_conversation_with_account(GAIM_CONV_TYPE_IM, |
| 2260 idb->user, acct); | |
| 1975 } | 2261 } |
| 1976 | 2262 |
| 1977 | 2263 |
| 1978 static void convo_queue(struct mwConversation *conv, | 2264 static void convo_queue(struct mwConversation *conv, |
| 1979 enum mwImSendType type, gconstpointer data) { | 2265 enum mwImSendType type, gconstpointer data) { |
| 2010 struct mwIdBlock *idb; | 2296 struct mwIdBlock *idb; |
| 2011 | 2297 |
| 2012 idb = mwConversation_getTarget(conv); | 2298 idb = mwConversation_getTarget(conv); |
| 2013 | 2299 |
| 2014 tmp = mwError(err); | 2300 tmp = mwError(err); |
| 2015 text = g_strconcat("Unable to send message: ", tmp, NULL); | 2301 text = g_strconcat(_("Unable to send message: "), tmp, NULL); |
| 2016 | 2302 |
| 2017 gconv = convo_get_gconv(conv); | 2303 gconv = convo_get_gconv(conv); |
| 2018 if(gconv && !gaim_conv_present_error(idb->user, gconv->account, text)) { | 2304 if(gconv && !gaim_conv_present_error(idb->user, gconv->account, text)) { |
| 2019 | 2305 |
| 2020 g_free(text); | 2306 g_free(text); |
| 2021 text = g_strdup_printf("Unable to send message to %s:", | 2307 text = g_strdup_printf(_("Unable to send message to %s:"), |
| 2022 (idb->user)? idb->user: "(unknown)"); | 2308 (idb->user)? idb->user: "(unknown)"); |
| 2023 gaim_notify_error(gaim_account_get_connection(gconv->account), | 2309 gaim_notify_error(gaim_account_get_connection(gconv->account), |
| 2024 NULL, text, tmp); | 2310 NULL, text, tmp); |
| 2025 } | 2311 } |
| 2026 | 2312 |
| 2097 convo_nofeatures(conv); | 2383 convo_nofeatures(conv); |
| 2098 } | 2384 } |
| 2099 } | 2385 } |
| 2100 | 2386 |
| 2101 | 2387 |
| 2388 #if 0 | |
| 2102 /** triggered from mw_conversation_opened if the appropriate plugin | 2389 /** triggered from mw_conversation_opened if the appropriate plugin |
| 2103 preference is set. This will open a window for the conversation | 2390 preference is set. This will open a window for the conversation |
| 2104 before the first message is sent. */ | 2391 before the first message is sent. */ |
| 2105 static void convo_do_psychic(struct mwConversation *conv) { | 2392 static void convo_do_psychic(struct mwConversation *conv) { |
| 2106 struct mwServiceIm *srvc; | 2393 struct mwServiceIm *srvc; |
| 2110 GaimAccount *acct; | 2397 GaimAccount *acct; |
| 2111 | 2398 |
| 2112 struct mwIdBlock *idb; | 2399 struct mwIdBlock *idb; |
| 2113 | 2400 |
| 2114 GaimConversation *gconv; | 2401 GaimConversation *gconv; |
| 2402 GaimConvWindow *win; | |
| 2115 | 2403 |
| 2116 srvc = mwConversation_getService(conv); | 2404 srvc = mwConversation_getService(conv); |
| 2117 session = mwService_getSession(MW_SERVICE(srvc)); | 2405 session = mwService_getSession(MW_SERVICE(srvc)); |
| 2118 pd = mwSession_getClientData(session); | 2406 pd = mwSession_getClientData(session); |
| 2119 gc = pd->gc; | 2407 gc = pd->gc; |
| 2120 acct = gaim_connection_get_account(gc); | 2408 acct = gaim_connection_get_account(gc); |
| 2121 | 2409 |
| 2122 idb = mwConversation_getTarget(conv); | 2410 idb = mwConversation_getTarget(conv); |
| 2123 | 2411 |
| 2124 gconv = gaim_find_conversation_with_account(GAIM_CONV_TYPE_IM, idb->user, acct); | 2412 gconv = gaim_find_conversation_with_account(GAIM_CONV_TYPE_IM, |
| 2413 idb->user, acct); | |
| 2125 if(! gconv) { | 2414 if(! gconv) { |
| 2126 gconv = gaim_conversation_new(GAIM_CONV_TYPE_IM, acct, idb->user); | 2415 gconv = gaim_conversation_new(GAIM_CONV_TYPE_IM, acct, idb->user); |
| 2127 } | 2416 } |
| 2128 | 2417 |
| 2129 g_return_if_fail(gconv != NULL); | 2418 g_return_if_fail(gconv != NULL); |
| 2130 | 2419 |
| 2131 | |
| 2132 #if 0 | |
| 2133 GaimConvWindow *win; | |
| 2134 win = gaim_conversation_get_window(gconv); | 2420 win = gaim_conversation_get_window(gconv); |
| 2135 g_return_if_fail(win != NULL); | 2421 g_return_if_fail(win != NULL); |
| 2136 | 2422 |
| 2137 gaim_conv_window_show(win); | 2423 gaim_conv_window_show(win); |
| 2424 } | |
| 2138 #endif | 2425 #endif |
| 2139 } | |
| 2140 | 2426 |
| 2141 | 2427 |
| 2142 static void mw_conversation_opened(struct mwConversation *conv) { | 2428 static void mw_conversation_opened(struct mwConversation *conv) { |
| 2143 struct mwServiceIm *srvc; | 2429 struct mwServiceIm *srvc; |
| 2144 struct mwSession *session; | 2430 struct mwSession *session; |
| 2165 } | 2451 } |
| 2166 | 2452 |
| 2167 } else { | 2453 } else { |
| 2168 convo_data_new(conv); | 2454 convo_data_new(conv); |
| 2169 | 2455 |
| 2456 #if 0 | |
| 2170 if(gaim_prefs_get_bool(MW_PRPL_OPT_PSYCHIC)) { | 2457 if(gaim_prefs_get_bool(MW_PRPL_OPT_PSYCHIC)) { |
| 2171 convo_do_psychic(conv); | 2458 convo_do_psychic(conv); |
| 2172 } | 2459 } |
| 2460 #endif | |
| 2173 } | 2461 } |
| 2174 | 2462 |
| 2175 { /* record the client key for the buddy */ | 2463 { /* record the client key for the buddy */ |
| 2176 GaimBuddy *buddy; | 2464 GaimBuddy *buddy; |
| 2177 struct mwLoginInfo *info; | 2465 struct mwLoginInfo *info; |
| 2193 | 2481 |
| 2194 struct convo_data *cd; | 2482 struct convo_data *cd; |
| 2195 | 2483 |
| 2196 g_return_if_fail(conv != NULL); | 2484 g_return_if_fail(conv != NULL); |
| 2197 | 2485 |
| 2198 /* if there's a error code and a non-typing message in the queue, | 2486 /* if there's an error code and a non-typing message in the queue, |
| 2199 print an error message to the conversation */ | 2487 print an error message to the conversation */ |
| 2200 cd = mwConversation_getClientData(conv); | 2488 cd = mwConversation_getClientData(conv); |
| 2201 if(reason && cd && cd->queue) { | 2489 if(reason && cd && cd->queue) { |
| 2202 GList *l; | 2490 GList *l; |
| 2203 for(l = cd->queue; l; l = l->next) { | 2491 for(l = cd->queue; l; l = l->next) { |
| 2218 | 2506 |
| 2219 mwConversation_removeClientData(conv); | 2507 mwConversation_removeClientData(conv); |
| 2220 } | 2508 } |
| 2221 | 2509 |
| 2222 | 2510 |
| 2511 | |
| 2512 static char *im_decode(GaimConnection *gc, const char *msg) { | |
| 2513 return gaim_utf8_try_convert(msg); | |
| 2514 } | |
| 2515 | |
| 2516 | |
| 2223 static void im_recv_text(struct mwConversation *conv, | 2517 static void im_recv_text(struct mwConversation *conv, |
| 2224 struct mwGaimPluginData *pd, | 2518 struct mwGaimPluginData *pd, |
| 2225 const char *msg) { | 2519 const char *msg) { |
| 2226 | 2520 |
| 2227 struct mwIdBlock *idb; | 2521 struct mwIdBlock *idb; |
| 2228 char *txt, *esc; | 2522 char *txt, *esc, *t; |
| 2229 | 2523 |
| 2230 idb = mwConversation_getTarget(conv); | 2524 idb = mwConversation_getTarget(conv); |
| 2231 txt = gaim_utf8_try_convert(msg); | 2525 txt = im_decode(pd->gc, msg); |
| 2232 esc = g_markup_escape_text(txt, -1); | 2526 |
| 2233 | 2527 t = txt? txt: (char *) msg; |
| 2528 | |
| 2529 esc = g_markup_escape_text(t, -1); | |
| 2234 serv_got_im(pd->gc, idb->user, esc, 0, time(NULL)); | 2530 serv_got_im(pd->gc, idb->user, esc, 0, time(NULL)); |
| 2531 g_free(esc); | |
| 2235 | 2532 |
| 2236 g_free(txt); | 2533 g_free(txt); |
| 2237 g_free(esc); | |
| 2238 } | 2534 } |
| 2239 | 2535 |
| 2240 | 2536 |
| 2241 static void im_recv_typing(struct mwConversation *conv, | 2537 static void im_recv_typing(struct mwConversation *conv, |
| 2242 struct mwGaimPluginData *pd, | 2538 struct mwGaimPluginData *pd, |
| 2253 static void im_recv_html(struct mwConversation *conv, | 2549 static void im_recv_html(struct mwConversation *conv, |
| 2254 struct mwGaimPluginData *pd, | 2550 struct mwGaimPluginData *pd, |
| 2255 const char *msg) { | 2551 const char *msg) { |
| 2256 | 2552 |
| 2257 struct mwIdBlock *idb; | 2553 struct mwIdBlock *idb; |
| 2258 char *txt; | 2554 char *txt, *t; |
| 2259 | 2555 |
| 2260 idb = mwConversation_getTarget(conv); | 2556 idb = mwConversation_getTarget(conv); |
| 2261 txt = gaim_utf8_try_convert(msg); | 2557 txt = im_decode(pd->gc, msg); |
| 2262 | 2558 |
| 2263 serv_got_im(pd->gc, idb->user, txt, 0, time(NULL)); | 2559 t = txt? txt: (char *) msg; |
| 2560 | |
| 2561 serv_got_im(pd->gc, idb->user, t, 0, time(NULL)); | |
| 2264 | 2562 |
| 2265 g_free(txt); | 2563 g_free(txt); |
| 2266 } | 2564 } |
| 2267 | 2565 |
| 2268 | 2566 |
| 2363 char *txt; | 2661 char *txt; |
| 2364 gsize len; | 2662 gsize len; |
| 2365 | 2663 |
| 2366 gaim_mime_part_get_data_decoded(part, &data, &len); | 2664 gaim_mime_part_get_data_decoded(part, &data, &len); |
| 2367 | 2665 |
| 2368 txt = gaim_utf8_try_convert((const char *)data); | 2666 txt = im_decode(pd->gc, data); |
| 2667 g_string_append(str, txt?txt:(char *)data); | |
| 2668 | |
| 2369 g_free(data); | 2669 g_free(data); |
| 2370 | |
| 2371 g_string_append(str, txt); | |
| 2372 g_free(txt); | 2670 g_free(txt); |
| 2373 } | 2671 } |
| 2374 } | 2672 } |
| 2375 | 2673 |
| 2376 gaim_mime_document_free(doc); | 2674 gaim_mime_document_free(doc); |
| 2377 | 2675 |
| 2676 /* @todo should put this in its own function */ | |
| 2378 { /* replace each IMG tag's SRC attribute with an ID attribute. This | 2677 { /* replace each IMG tag's SRC attribute with an ID attribute. This |
| 2379 actually modifies the contents of str */ | 2678 actually modifies the contents of str */ |
| 2380 GData *attribs; | 2679 GData *attribs; |
| 2381 char *start, *end; | 2680 char *start, *end; |
| 2382 char *tmp = str->str; | 2681 char *tmp = str->str; |
| 2467 ; /* erm... */ | 2766 ; /* erm... */ |
| 2468 } | 2767 } |
| 2469 } | 2768 } |
| 2470 | 2769 |
| 2471 | 2770 |
| 2472 #if 0 | |
| 2473 /* this will be appropriate when meanwhile supports the Place service */ | |
| 2474 static void mw_place_invite(struct mwConversation *conv, | 2771 static void mw_place_invite(struct mwConversation *conv, |
| 2475 const char *message, | 2772 const char *message, |
| 2476 const char *title, const char *name) { | 2773 const char *title, const char *name) { |
| 2477 struct mwServiceIm *srvc; | 2774 struct mwServiceIm *srvc; |
| 2478 struct mwSession *session; | 2775 struct mwSession *session; |
| 2490 ht = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, g_free); | 2787 ht = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, g_free); |
| 2491 g_hash_table_insert(ht, CHAT_KEY_CREATOR, g_strdup(idb->user)); | 2788 g_hash_table_insert(ht, CHAT_KEY_CREATOR, g_strdup(idb->user)); |
| 2492 g_hash_table_insert(ht, CHAT_KEY_NAME, g_strdup(name)); | 2789 g_hash_table_insert(ht, CHAT_KEY_NAME, g_strdup(name)); |
| 2493 g_hash_table_insert(ht, CHAT_KEY_TOPIC, g_strdup(title)); | 2790 g_hash_table_insert(ht, CHAT_KEY_TOPIC, g_strdup(title)); |
| 2494 g_hash_table_insert(ht, CHAT_KEY_INVITE, g_strdup(message)); | 2791 g_hash_table_insert(ht, CHAT_KEY_INVITE, g_strdup(message)); |
| 2792 g_hash_table_insert(ht, CHAT_KEY_IS_PLACE, g_strdup("")); /* ugh */ | |
| 2495 | 2793 |
| 2496 serv_got_chat_invite(pd->gc, title, idb->user, message, ht); | 2794 serv_got_chat_invite(pd->gc, title, idb->user, message, ht); |
| 2497 } | 2795 |
| 2498 #endif | 2796 mwConversation_close(conv, ERR_SUCCESS); |
| 2797 mwConversation_free(conv); | |
| 2798 } | |
| 2499 | 2799 |
| 2500 | 2800 |
| 2501 static void mw_im_clear(struct mwServiceIm *srvc) { | 2801 static void mw_im_clear(struct mwServiceIm *srvc) { |
| 2502 ; | 2802 ; |
| 2503 } | 2803 } |
| 2505 | 2805 |
| 2506 static struct mwImHandler mw_im_handler = { | 2806 static struct mwImHandler mw_im_handler = { |
| 2507 .conversation_opened = mw_conversation_opened, | 2807 .conversation_opened = mw_conversation_opened, |
| 2508 .conversation_closed = mw_conversation_closed, | 2808 .conversation_closed = mw_conversation_closed, |
| 2509 .conversation_recv = mw_conversation_recv, | 2809 .conversation_recv = mw_conversation_recv, |
| 2510 .place_invite = NULL, /* = mw_place_invite, */ | 2810 .place_invite = mw_place_invite, |
| 2511 .clear = mw_im_clear, | 2811 .clear = mw_im_clear, |
| 2512 }; | 2812 }; |
| 2513 | 2813 |
| 2514 | 2814 |
| 2515 static struct mwServiceIm *mw_srvc_im_new(struct mwSession *s) { | 2815 static struct mwServiceIm *mw_srvc_im_new(struct mwSession *s) { |
| 2516 struct mwServiceIm *srvc; | 2816 struct mwServiceIm *srvc; |
| 2517 srvc = mwServiceIm_new(s, &mw_im_handler); | 2817 srvc = mwServiceIm_new(s, &mw_im_handler); |
| 2518 mwServiceIm_setClientType(srvc, mwImClient_NOTESBUDDY); | 2818 mwServiceIm_setClientType(srvc, mwImClient_NOTESBUDDY); |
| 2819 return srvc; | |
| 2820 } | |
| 2821 | |
| 2822 | |
| 2823 /* The following helps us relate a mwPlace to a GaimConvChat in the | |
| 2824 various forms by which either may be indicated. Uses some of | |
| 2825 the similar macros from the conference service above */ | |
| 2826 | |
| 2827 #define PLACE_TO_ID(place) (GPOINTER_TO_INT(place)) | |
| 2828 #define ID_TO_PLACE(pd, id) (place_find_by_id((pd), (id))) | |
| 2829 | |
| 2830 #define CHAT_TO_PLACE(pd, chat) (ID_TO_PLACE((pd), CHAT_TO_ID(chat))) | |
| 2831 #define PLACE_TO_CHAT(place) (ID_TO_CHAT(PLACE_TO_ID(place))) | |
| 2832 | |
| 2833 | |
| 2834 static struct mwPlace * | |
| 2835 place_find_by_id(struct mwGaimPluginData *pd, int id) { | |
| 2836 struct mwServicePlace *srvc = pd->srvc_place; | |
| 2837 struct mwPlace *place = NULL; | |
| 2838 GList *l; | |
| 2839 | |
| 2840 l = (GList *) mwServicePlace_getPlaces(srvc); | |
| 2841 for(; l; l = l->next) { | |
| 2842 struct mwPlace *p = l->data; | |
| 2843 GaimConvChat *h = GAIM_CONV_CHAT(mwPlace_getClientData(p)); | |
| 2844 | |
| 2845 if(CHAT_TO_ID(h) == id) { | |
| 2846 place = p; | |
| 2847 break; | |
| 2848 } | |
| 2849 } | |
| 2850 | |
| 2851 return place; | |
| 2852 } | |
| 2853 | |
| 2854 | |
| 2855 static void mw_place_opened(struct mwPlace *place) { | |
| 2856 struct mwServicePlace *srvc; | |
| 2857 struct mwSession *session; | |
| 2858 struct mwGaimPluginData *pd; | |
| 2859 GaimConnection *gc; | |
| 2860 GaimConversation *gconf; | |
| 2861 | |
| 2862 GList *members, *l; | |
| 2863 | |
| 2864 const char *n = mwPlace_getName(place); | |
| 2865 | |
| 2866 srvc = mwPlace_getService(place); | |
| 2867 session = mwService_getSession(MW_SERVICE(srvc)); | |
| 2868 pd = mwSession_getClientData(session); | |
| 2869 gc = pd->gc; | |
| 2870 | |
| 2871 members = mwPlace_getMembers(place); | |
| 2872 | |
| 2873 DEBUG_INFO("place %s opened, %u initial members\n", | |
| 2874 NSTR(n), g_list_length(members)); | |
| 2875 | |
| 2876 gconf = serv_got_joined_chat(gc, PLACE_TO_ID(place), | |
| 2877 mwPlace_getTitle(place)); | |
| 2878 | |
| 2879 mwPlace_setClientData(place, gconf, NULL); | |
| 2880 | |
| 2881 for(l = members; l; l = l->next) { | |
| 2882 struct mwIdBlock *idb = l->data; | |
| 2883 gaim_conv_chat_add_user(GAIM_CONV_CHAT(gconf), idb->user, | |
| 2884 NULL, GAIM_CBFLAGS_NONE, FALSE); | |
| 2885 } | |
| 2886 g_list_free(members); | |
| 2887 } | |
| 2888 | |
| 2889 | |
| 2890 static void mw_place_closed(struct mwPlace *place, guint32 code) { | |
| 2891 struct mwServicePlace *srvc; | |
| 2892 struct mwSession *session; | |
| 2893 struct mwGaimPluginData *pd; | |
| 2894 GaimConnection *gc; | |
| 2895 | |
| 2896 const char *n = mwPlace_getName(place); | |
| 2897 char *msg = mwError(code); | |
| 2898 | |
| 2899 DEBUG_INFO("place %s closed, 0x%08x\n", NSTR(n), code); | |
| 2900 | |
| 2901 srvc = mwPlace_getService(place); | |
| 2902 session = mwService_getSession(MW_SERVICE(srvc)); | |
| 2903 pd = mwSession_getClientData(session); | |
| 2904 gc = pd->gc; | |
| 2905 | |
| 2906 serv_got_chat_left(gc, PLACE_TO_ID(place)); | |
| 2907 | |
| 2908 gaim_notify_error(gc, _("Place Closed"), NULL, msg); | |
| 2909 g_free(msg); | |
| 2910 } | |
| 2911 | |
| 2912 | |
| 2913 static void mw_place_peerJoined(struct mwPlace *place, | |
| 2914 const struct mwIdBlock *peer) { | |
| 2915 struct mwServicePlace *srvc; | |
| 2916 struct mwSession *session; | |
| 2917 struct mwGaimPluginData *pd; | |
| 2918 GaimConnection *gc; | |
| 2919 GaimConversation *gconf; | |
| 2920 | |
| 2921 const char *n = mwPlace_getName(place); | |
| 2922 | |
| 2923 DEBUG_INFO("%s joined place %s\n", NSTR(peer->user), NSTR(n)); | |
| 2924 | |
| 2925 srvc = mwPlace_getService(place); | |
| 2926 session = mwService_getSession(MW_SERVICE(srvc)); | |
| 2927 pd = mwSession_getClientData(session); | |
| 2928 gc = pd->gc; | |
| 2929 | |
| 2930 gconf = mwPlace_getClientData(place); | |
| 2931 g_return_if_fail(gconf != NULL); | |
| 2932 | |
| 2933 gaim_conv_chat_add_user(GAIM_CONV_CHAT(gconf), peer->user, | |
| 2934 NULL, GAIM_CBFLAGS_NONE, TRUE); | |
| 2935 } | |
| 2936 | |
| 2937 | |
| 2938 static void mw_place_peerParted(struct mwPlace *place, | |
| 2939 const struct mwIdBlock *peer) { | |
| 2940 struct mwServicePlace *srvc; | |
| 2941 struct mwSession *session; | |
| 2942 struct mwGaimPluginData *pd; | |
| 2943 GaimConnection *gc; | |
| 2944 GaimConversation *gconf; | |
| 2945 | |
| 2946 const char *n = mwPlace_getName(place); | |
| 2947 | |
| 2948 DEBUG_INFO("%s left place %s\n", NSTR(peer->user), NSTR(n)); | |
| 2949 | |
| 2950 srvc = mwPlace_getService(place); | |
| 2951 session = mwService_getSession(MW_SERVICE(srvc)); | |
| 2952 pd = mwSession_getClientData(session); | |
| 2953 gc = pd->gc; | |
| 2954 | |
| 2955 gconf = mwPlace_getClientData(place); | |
| 2956 g_return_if_fail(gconf != NULL); | |
| 2957 | |
| 2958 gaim_conv_chat_remove_user(GAIM_CONV_CHAT(gconf), peer->user, NULL); | |
| 2959 } | |
| 2960 | |
| 2961 | |
| 2962 static void mw_place_peerSetAttribute(struct mwPlace *place, | |
| 2963 const struct mwIdBlock *peer, | |
| 2964 guint32 attr, struct mwOpaque *o) { | |
| 2965 ; | |
| 2966 } | |
| 2967 | |
| 2968 | |
| 2969 static void mw_place_peerUnsetAttribute(struct mwPlace *place, | |
| 2970 const struct mwIdBlock *peer, | |
| 2971 guint32 attr) { | |
| 2972 ; | |
| 2973 } | |
| 2974 | |
| 2975 | |
| 2976 static void mw_place_message(struct mwPlace *place, | |
| 2977 const struct mwIdBlock *who, | |
| 2978 const char *msg) { | |
| 2979 struct mwServicePlace *srvc; | |
| 2980 struct mwSession *session; | |
| 2981 struct mwGaimPluginData *pd; | |
| 2982 GaimConnection *gc; | |
| 2983 char *esc; | |
| 2984 | |
| 2985 srvc = mwPlace_getService(place); | |
| 2986 session = mwService_getSession(MW_SERVICE(srvc)); | |
| 2987 pd = mwSession_getClientData(session); | |
| 2988 gc = pd->gc; | |
| 2989 | |
| 2990 esc = g_markup_escape_text(msg, -1); | |
| 2991 serv_got_chat_in(gc, PLACE_TO_ID(place), who->user, 0, esc, time(NULL)); | |
| 2992 g_free(esc); | |
| 2993 } | |
| 2994 | |
| 2995 | |
| 2996 static void mw_place_clear(struct mwServicePlace *srvc) { | |
| 2997 ; | |
| 2998 } | |
| 2999 | |
| 3000 | |
| 3001 static struct mwPlaceHandler mw_place_handler = { | |
| 3002 .opened = mw_place_opened, | |
| 3003 .closed = mw_place_closed, | |
| 3004 .peerJoined = mw_place_peerJoined, | |
| 3005 .peerParted = mw_place_peerParted, | |
| 3006 .peerSetAttribute = mw_place_peerSetAttribute, | |
| 3007 .peerUnsetAttribute = mw_place_peerUnsetAttribute, | |
| 3008 .message = mw_place_message, | |
| 3009 .clear = mw_place_clear, | |
| 3010 }; | |
| 3011 | |
| 3012 | |
| 3013 static struct mwServicePlace *mw_srvc_place_new(struct mwSession *s) { | |
| 3014 struct mwServicePlace *srvc; | |
| 3015 srvc = mwServicePlace_new(s, &mw_place_handler); | |
| 2519 return srvc; | 3016 return srvc; |
| 2520 } | 3017 } |
| 2521 | 3018 |
| 2522 | 3019 |
| 2523 static struct mwServiceResolve *mw_srvc_resolve_new(struct mwSession *s) { | 3020 static struct mwServiceResolve *mw_srvc_resolve_new(struct mwSession *s) { |
| 2545 pd->session = mwSession_new(&mw_session_handler); | 3042 pd->session = mwSession_new(&mw_session_handler); |
| 2546 pd->srvc_aware = mw_srvc_aware_new(pd->session); | 3043 pd->srvc_aware = mw_srvc_aware_new(pd->session); |
| 2547 pd->srvc_conf = mw_srvc_conf_new(pd->session); | 3044 pd->srvc_conf = mw_srvc_conf_new(pd->session); |
| 2548 pd->srvc_ft = mw_srvc_ft_new(pd->session); | 3045 pd->srvc_ft = mw_srvc_ft_new(pd->session); |
| 2549 pd->srvc_im = mw_srvc_im_new(pd->session); | 3046 pd->srvc_im = mw_srvc_im_new(pd->session); |
| 3047 pd->srvc_place = mw_srvc_place_new(pd->session); | |
| 2550 pd->srvc_resolve = mw_srvc_resolve_new(pd->session); | 3048 pd->srvc_resolve = mw_srvc_resolve_new(pd->session); |
| 2551 pd->srvc_store = mw_srvc_store_new(pd->session); | 3049 pd->srvc_store = mw_srvc_store_new(pd->session); |
| 2552 pd->group_list_map = g_hash_table_new(g_direct_hash, g_direct_equal); | 3050 pd->group_list_map = g_hash_table_new(g_direct_hash, g_direct_equal); |
| 2553 | 3051 |
| 2554 mwSession_addService(pd->session, MW_SERVICE(pd->srvc_aware)); | 3052 mwSession_addService(pd->session, MW_SERVICE(pd->srvc_aware)); |
| 2555 mwSession_addService(pd->session, MW_SERVICE(pd->srvc_conf)); | 3053 mwSession_addService(pd->session, MW_SERVICE(pd->srvc_conf)); |
| 2556 mwSession_addService(pd->session, MW_SERVICE(pd->srvc_ft)); | 3054 mwSession_addService(pd->session, MW_SERVICE(pd->srvc_ft)); |
| 2557 mwSession_addService(pd->session, MW_SERVICE(pd->srvc_im)); | 3055 mwSession_addService(pd->session, MW_SERVICE(pd->srvc_im)); |
| 3056 mwSession_addService(pd->session, MW_SERVICE(pd->srvc_place)); | |
| 2558 mwSession_addService(pd->session, MW_SERVICE(pd->srvc_resolve)); | 3057 mwSession_addService(pd->session, MW_SERVICE(pd->srvc_resolve)); |
| 2559 mwSession_addService(pd->session, MW_SERVICE(pd->srvc_store)); | 3058 mwSession_addService(pd->session, MW_SERVICE(pd->srvc_store)); |
| 2560 | 3059 |
| 2561 mwSession_addCipher(pd->session, mwCipher_new_RC2_40(pd->session)); | 3060 mwSession_addCipher(pd->session, mwCipher_new_RC2_40(pd->session)); |
| 3061 mwSession_addCipher(pd->session, mwCipher_new_RC2_128(pd->session)); | |
| 2562 | 3062 |
| 2563 mwSession_setClientData(pd->session, pd, NULL); | 3063 mwSession_setClientData(pd->session, pd, NULL); |
| 2564 gc->proto_data = pd; | 3064 gc->proto_data = pd; |
| 2565 | 3065 |
| 2566 return pd; | 3066 return pd; |
| 2570 static void mwGaimPluginData_free(struct mwGaimPluginData *pd) { | 3070 static void mwGaimPluginData_free(struct mwGaimPluginData *pd) { |
| 2571 g_return_if_fail(pd != NULL); | 3071 g_return_if_fail(pd != NULL); |
| 2572 | 3072 |
| 2573 pd->gc->proto_data = NULL; | 3073 pd->gc->proto_data = NULL; |
| 2574 | 3074 |
| 2575 mwSession_removeService(pd->session, SERVICE_AWARE); | 3075 mwSession_removeService(pd->session, mwService_AWARE); |
| 2576 mwSession_removeService(pd->session, SERVICE_CONFERENCE); | 3076 mwSession_removeService(pd->session, mwService_CONFERENCE); |
| 2577 mwSession_removeService(pd->session, SERVICE_IM); | 3077 mwSession_removeService(pd->session, mwService_FILE_TRANSFER); |
| 2578 mwSession_removeService(pd->session, SERVICE_RESOLVE); | 3078 mwSession_removeService(pd->session, mwService_IM); |
| 2579 mwSession_removeService(pd->session, SERVICE_STORAGE); | 3079 mwSession_removeService(pd->session, mwService_PLACE); |
| 3080 mwSession_removeService(pd->session, mwService_RESOLVE); | |
| 3081 mwSession_removeService(pd->session, mwService_STORAGE); | |
| 2580 | 3082 |
| 2581 mwService_free(MW_SERVICE(pd->srvc_aware)); | 3083 mwService_free(MW_SERVICE(pd->srvc_aware)); |
| 2582 mwService_free(MW_SERVICE(pd->srvc_conf)); | 3084 mwService_free(MW_SERVICE(pd->srvc_conf)); |
| 3085 mwService_free(MW_SERVICE(pd->srvc_ft)); | |
| 2583 mwService_free(MW_SERVICE(pd->srvc_im)); | 3086 mwService_free(MW_SERVICE(pd->srvc_im)); |
| 3087 mwService_free(MW_SERVICE(pd->srvc_place)); | |
| 2584 mwService_free(MW_SERVICE(pd->srvc_resolve)); | 3088 mwService_free(MW_SERVICE(pd->srvc_resolve)); |
| 2585 mwService_free(MW_SERVICE(pd->srvc_store)); | 3089 mwService_free(MW_SERVICE(pd->srvc_store)); |
| 2586 | 3090 |
| 2587 mwCipher_free(mwSession_getCipher(pd->session, mwCipher_RC2_40)); | 3091 mwCipher_free(mwSession_getCipher(pd->session, mwCipher_RC2_40)); |
| 3092 mwCipher_free(mwSession_getCipher(pd->session, mwCipher_RC2_128)); | |
| 2588 | 3093 |
| 2589 mwSession_free(pd->session); | 3094 mwSession_free(pd->session); |
| 2590 | 3095 |
| 2591 g_hash_table_destroy(pd->group_list_map); | 3096 g_hash_table_destroy(pd->group_list_map); |
| 2592 | 3097 |
| 2611 | 3116 |
| 2612 | 3117 |
| 2613 static void mw_prpl_list_emblems(GaimBuddy *b, | 3118 static void mw_prpl_list_emblems(GaimBuddy *b, |
| 2614 const char **se, const char **sw, | 3119 const char **se, const char **sw, |
| 2615 const char **nw, const char **ne) { | 3120 const char **nw, const char **ne) { |
| 2616 GaimPresence *presence = gaim_buddy_get_presence(b); | 3121 |
| 2617 GaimStatus *status = gaim_presence_get_active_status(presence); | 3122 /* speaking of custom icons, the external icon here is an ugly |
| 3123 little example of what happens when I use Gimp */ | |
| 3124 | |
| 3125 GaimPresence *presence; | |
| 3126 GaimStatus *status; | |
| 3127 const char *status_id; | |
| 3128 | |
| 3129 presence = gaim_buddy_get_presence(b); | |
| 3130 status = gaim_presence_get_active_status(presence); | |
| 3131 status_id = gaim_status_get_id(status); | |
| 2618 | 3132 |
| 2619 if(! GAIM_BUDDY_IS_ONLINE(b)) { | 3133 if(! GAIM_BUDDY_IS_ONLINE(b)) { |
| 2620 *se = "offline"; | 3134 *se = "offline"; |
| 2621 } else if(!gaim_presence_is_available(presence) && | 3135 } else if(!strcmp(status_id, MW_STATE_AWAY)) { |
| 2622 !strcmp(gaim_status_get_id(status), MW_STATE_AWAY)) { | |
| 2623 *se = "away"; | 3136 *se = "away"; |
| 2624 } else if(!gaim_presence_is_available(presence) && | 3137 } else if(!strcmp(status_id, MW_STATE_BUSY)) { |
| 2625 !strcmp(gaim_status_get_id(status), MW_STATE_BUSY)) { | |
| 2626 *se = "dnd"; | 3138 *se = "dnd"; |
| 3139 } | |
| 3140 | |
| 3141 if(buddy_is_external(b)) { | |
| 3142 /* best assignment ever */ | |
| 3143 *(*se?sw:se) = "external"; | |
| 2627 } | 3144 } |
| 2628 } | 3145 } |
| 2629 | 3146 |
| 2630 | 3147 |
| 2631 static char *mw_prpl_status_text(GaimBuddy *b) { | 3148 static char *mw_prpl_status_text(GaimBuddy *b) { |
| 2636 | 3153 |
| 2637 gc = b->account->gc; | 3154 gc = b->account->gc; |
| 2638 pd = gc->proto_data; | 3155 pd = gc->proto_data; |
| 2639 | 3156 |
| 2640 ret = mwServiceAware_getText(pd->srvc_aware, &t); | 3157 ret = mwServiceAware_getText(pd->srvc_aware, &t); |
| 2641 return (ret)? g_strdup(ret): NULL; | 3158 return g_strdup(ret); |
| 2642 } | 3159 } |
| 2643 | 3160 |
| 2644 | 3161 |
| 2645 static const char *status_text(GaimBuddy *b) { | 3162 static const char *status_text(GaimBuddy *b) { |
| 2646 GaimPresence *presence = gaim_buddy_get_presence(b); | 3163 GaimPresence *presence; |
| 2647 GaimStatus *status = gaim_presence_get_active_status(presence); | 3164 GaimStatus *status; |
| 3165 | |
| 3166 presence = gaim_buddy_get_presence(b); | |
| 3167 status = gaim_presence_get_active_status(presence); | |
| 2648 | 3168 |
| 2649 return gaim_status_get_name(status); | 3169 return gaim_status_get_name(status); |
| 2650 | |
| 2651 /* I left this here in case it's more accurate than the status name. | |
| 2652 * Stu. */ | |
| 2653 #if 0 | |
| 2654 | |
| 2655 guint status = b->uc; | |
| 2656 | |
| 2657 if(! GAIM_BUDDY_IS_ONLINE(b) ) { | |
| 2658 return MW_STATE_OFFLINE; | |
| 2659 | |
| 2660 } else if(status == (mwStatus_AWAY /* XXX | UC_UNAVAILABLE */)) { | |
| 2661 return MW_STATE_AWAY; | |
| 2662 | |
| 2663 } else if(status == (mwStatus_BUSY /* XXX | UC_UNAVAILABLE */)) { | |
| 2664 return MW_STATE_BUSY; | |
| 2665 | |
| 2666 } else if(status == mwStatus_IDLE) { | |
| 2667 return MW_STATE_IDLE; | |
| 2668 | |
| 2669 } else if(status == mwStatus_ACTIVE) { | |
| 2670 return MW_STATE_ACTIVE; | |
| 2671 | |
| 2672 } else { | |
| 2673 return MW_STATE_UNKNOWN; | |
| 2674 } | |
| 2675 #endif | |
| 2676 } | 3170 } |
| 2677 | 3171 |
| 2678 | 3172 |
| 2679 static gboolean user_supports(struct mwServiceAware *srvc, | 3173 static gboolean user_supports(struct mwServiceAware *srvc, |
| 2680 const char *who, guint32 feature) { | 3174 const char *who, guint32 feature) { |
| 2696 | 3190 |
| 2697 mic = user_supports(srvc, who, mwAttribute_MICROPHONE); | 3191 mic = user_supports(srvc, who, mwAttribute_MICROPHONE); |
| 2698 speak = user_supports(srvc, who, mwAttribute_SPEAKERS); | 3192 speak = user_supports(srvc, who, mwAttribute_SPEAKERS); |
| 2699 video = user_supports(srvc, who, mwAttribute_VIDEO_CAMERA); | 3193 video = user_supports(srvc, who, mwAttribute_VIDEO_CAMERA); |
| 2700 | 3194 |
| 2701 if(mic) *f++ = "Microphone"; | 3195 if(mic) *f++ = _("Microphone"); |
| 2702 if(speak) *f++ = "Speakers"; | 3196 if(speak) *f++ = _("Speakers"); |
| 2703 if(video) *f++ = "Video Camera"; | 3197 if(video) *f++ = _("Video Camera"); |
| 2704 } | 3198 } |
| 2705 | 3199 |
| 2706 if(user_supports(srvc, who, mwAttribute_FILE_TRANSFER)) | 3200 if(user_supports(srvc, who, mwAttribute_FILE_TRANSFER)) |
| 2707 *f++ = "File Transfer"; | 3201 *f++ = _("File Transfer"); |
| 2708 | 3202 |
| 2709 return (*feat)? g_strjoinv(", ", feat): NULL; | 3203 return (*feat)? g_strjoinv(", ", feat): NULL; |
| 2710 /* jenni loves siege */ | 3204 /* jenni loves siege */ |
| 2711 } | 3205 } |
| 2712 | 3206 |
| 2723 pd = gc->proto_data; | 3217 pd = gc->proto_data; |
| 2724 | 3218 |
| 2725 str = g_string_new(NULL); | 3219 str = g_string_new(NULL); |
| 2726 | 3220 |
| 2727 tmp = status_text(b); | 3221 tmp = status_text(b); |
| 2728 g_string_append_printf(str, "\n<b>Status</b>: %s", tmp); | 3222 g_string_append_printf(str, _("\n<b>Status</b>: %s"), tmp); |
| 2729 | 3223 |
| 2730 tmp = mwServiceAware_getText(pd->srvc_aware, &idb); | 3224 tmp = mwServiceAware_getText(pd->srvc_aware, &idb); |
| 2731 if(tmp) { | 3225 if(tmp) { |
| 2732 tmp = g_markup_escape_text(tmp, -1); | 3226 tmp = g_markup_escape_text(tmp, -1); |
| 2733 g_string_append_printf(str, "\n<b>Message</b>: %s", tmp); | 3227 g_string_append_printf(str, _("\n<b>Message</b>: %s"), tmp); |
| 2734 g_free((char *) tmp); | 3228 g_free((char *) tmp); |
| 2735 } | 3229 } |
| 2736 | 3230 |
| 2737 tmp = user_supports_text(pd->srvc_aware, b->name); | 3231 tmp = user_supports_text(pd->srvc_aware, b->name); |
| 2738 if(tmp) { | 3232 if(tmp) { |
| 2739 g_string_append_printf(str, "\n<b>Supports</b>: %s", tmp); | 3233 g_string_append_printf(str, _("\n<b>Supports</b>: %s"), tmp); |
| 2740 g_free((char *) tmp); | 3234 g_free((char *) tmp); |
| 3235 } | |
| 3236 | |
| 3237 if(buddy_is_external(b)) { | |
| 3238 g_string_append(str, _("\n<b>External User</b>")); | |
| 2741 } | 3239 } |
| 2742 | 3240 |
| 2743 tmp = str->str; | 3241 tmp = str->str; |
| 2744 g_string_free(str, FALSE); | 3242 g_string_free(str, FALSE); |
| 2745 return (char *) tmp; | 3243 return (char *) tmp; |
| 2763 type = gaim_status_type_new(GAIM_STATUS_AWAY, MW_STATE_AWAY, | 3261 type = gaim_status_type_new(GAIM_STATUS_AWAY, MW_STATE_AWAY, |
| 2764 _("Away"), TRUE); | 3262 _("Away"), TRUE); |
| 2765 gaim_status_type_add_attr(type, MW_STATE_MESSAGE, _("Message"), | 3263 gaim_status_type_add_attr(type, MW_STATE_MESSAGE, _("Message"), |
| 2766 gaim_value_new(GAIM_TYPE_STRING)); | 3264 gaim_value_new(GAIM_TYPE_STRING)); |
| 2767 types = g_list_append(types, type); | 3265 types = g_list_append(types, type); |
| 2768 | 3266 |
| 2769 type = gaim_status_type_new(GAIM_STATUS_UNAVAILABLE, MW_STATE_BUSY, | 3267 type = gaim_status_type_new(GAIM_STATUS_UNAVAILABLE, MW_STATE_BUSY, |
| 2770 _("Do Not Disturb"), TRUE); | 3268 _("Do Not Disturb"), TRUE); |
| 2771 gaim_status_type_add_attr(type, MW_STATE_MESSAGE, _("Message"), | 3269 gaim_status_type_add_attr(type, MW_STATE_MESSAGE, _("Message"), |
| 2772 gaim_value_new(GAIM_TYPE_STRING)); | 3270 gaim_value_new(GAIM_TYPE_STRING)); |
| 2773 types = g_list_append(types, type); | 3271 types = g_list_append(types, type); |
| 2774 | 3272 |
| 2775 return types; | 3273 return types; |
| 2776 } | 3274 } |
| 2777 | 3275 |
| 2778 | 3276 |
| 2779 static void conf_create_prompt_cancel(GaimBuddy *buddy, | 3277 static void conf_create_prompt_cancel(GaimBuddy *buddy, |
| 2780 GaimRequestFields *fields) { | 3278 GaimRequestFields *fields) { |
| 2781 ; | 3279 ; /* nothing to do */ |
| 2782 } | 3280 } |
| 2783 | 3281 |
| 2784 | 3282 |
| 2785 static void conf_create_prompt_join(GaimBuddy *buddy, | 3283 static void conf_create_prompt_join(GaimBuddy *buddy, |
| 2786 GaimRequestFields *fields) { | 3284 GaimRequestFields *fields) { |
| 2836 fields = gaim_request_fields_new(); | 3334 fields = gaim_request_fields_new(); |
| 2837 | 3335 |
| 2838 g = gaim_request_field_group_new(NULL); | 3336 g = gaim_request_field_group_new(NULL); |
| 2839 gaim_request_fields_add_group(fields, g); | 3337 gaim_request_fields_add_group(fields, g); |
| 2840 | 3338 |
| 2841 f = gaim_request_field_string_new(CHAT_KEY_TOPIC, "Topic", NULL, FALSE); | 3339 f = gaim_request_field_string_new(CHAT_KEY_TOPIC, _("Topic"), NULL, FALSE); |
| 2842 gaim_request_field_group_add_field(g, f); | 3340 gaim_request_field_group_add_field(g, f); |
| 2843 | 3341 |
| 2844 f = gaim_request_field_string_new(CHAT_KEY_INVITE, "Message", msg, FALSE); | 3342 f = gaim_request_field_string_new(CHAT_KEY_INVITE, _("Message"), msg, FALSE); |
| 2845 gaim_request_field_group_add_field(g, f); | 3343 gaim_request_field_group_add_field(g, f); |
| 2846 | 3344 |
| 2847 msgA = ("Create conference with user"); | 3345 msgA = _("Create conference with user"); |
| 2848 msgB = ("Please enter a topic for the new conference, and an invitation" | 3346 msgB = _("Please enter a topic for the new conference, and an invitation" |
| 2849 " message to be sent to %s"); | 3347 " message to be sent to %s"); |
| 2850 msgB = g_strdup_printf(msgB, buddy->name); | 3348 msgB = g_strdup_printf(msgB, buddy->name); |
| 2851 | 3349 |
| 2852 gaim_request_fields(gc, "New Conference", | 3350 gaim_request_fields(gc, _("New Conference"), |
| 2853 msgA, msgB, fields, | 3351 msgA, msgB, fields, |
| 2854 "Create", G_CALLBACK(conf_create_prompt_join), | 3352 _("Create"), G_CALLBACK(conf_create_prompt_join), |
| 2855 "Cancel", G_CALLBACK(conf_create_prompt_cancel), | 3353 _("Cancel"), G_CALLBACK(conf_create_prompt_cancel), |
| 2856 buddy); | 3354 buddy); |
| 2857 g_free(msgB); | 3355 g_free(msgB); |
| 2858 } | 3356 } |
| 2859 | 3357 |
| 2860 | 3358 |
| 2911 fields = gaim_request_fields_new(); | 3409 fields = gaim_request_fields_new(); |
| 2912 | 3410 |
| 2913 g = gaim_request_field_group_new(NULL); | 3411 g = gaim_request_field_group_new(NULL); |
| 2914 gaim_request_fields_add_group(fields, g); | 3412 gaim_request_fields_add_group(fields, g); |
| 2915 | 3413 |
| 2916 f = gaim_request_field_list_new("conf", "Available Conferences"); | 3414 f = gaim_request_field_list_new("conf", _("Available Conferences")); |
| 2917 gaim_request_field_list_set_multi_select(f, FALSE); | 3415 gaim_request_field_list_set_multi_select(f, FALSE); |
| 2918 for(; confs; confs = confs->next) { | 3416 for(; confs; confs = confs->next) { |
| 2919 struct mwConference *c = confs->data; | 3417 struct mwConference *c = confs->data; |
| 2920 gaim_request_field_list_add(f, mwConference_getTitle(c), c); | 3418 gaim_request_field_list_add(f, mwConference_getTitle(c), c); |
| 2921 } | 3419 } |
| 2922 gaim_request_field_list_add(f, "Create New Conference...", | 3420 gaim_request_field_list_add(f, _("Create New Conference..."), |
| 2923 GINT_TO_POINTER(0x01)); | 3421 GINT_TO_POINTER(0x01)); |
| 2924 gaim_request_field_group_add_field(g, f); | 3422 gaim_request_field_group_add_field(g, f); |
| 2925 | 3423 |
| 2926 f = gaim_request_field_string_new(CHAT_KEY_INVITE, "Message", NULL, FALSE); | 3424 f = gaim_request_field_string_new(CHAT_KEY_INVITE, "Message", NULL, FALSE); |
| 2927 gaim_request_field_group_add_field(g, f); | 3425 gaim_request_field_group_add_field(g, f); |
| 2928 | 3426 |
| 2929 msgA = "Invite user to a conference"; | 3427 msgA = _("Invite user to a conference"); |
| 2930 msgB = ("Select a conference from the list below to send an invite to" | 3428 msgB = _("Select a conference from the list below to send an invite to" |
| 2931 " user %s. Select \"Create New Conference\" if you'd like to" | 3429 " user %s. Select \"Create New Conference\" if you'd like to" |
| 2932 " create a new conference to invite this user to."); | 3430 " create a new conference to invite this user to."); |
| 2933 msgB = g_strdup_printf(msgB, buddy->name); | 3431 msgB = g_strdup_printf(msgB, buddy->name); |
| 2934 | 3432 |
| 2935 gaim_request_fields(gc, "Invite to Conference", | 3433 gaim_request_fields(gc, _("Invite to Conference"), |
| 2936 msgA, msgB, fields, | 3434 msgA, msgB, fields, |
| 2937 "Invite", G_CALLBACK(conf_select_prompt_invite), | 3435 _("Invite"), G_CALLBACK(conf_select_prompt_invite), |
| 2938 "Cancel", G_CALLBACK(conf_select_prompt_cancel), | 3436 _("Cancel"), G_CALLBACK(conf_select_prompt_cancel), |
| 2939 buddy); | 3437 buddy); |
| 2940 g_free(msgB); | 3438 g_free(msgB); |
| 2941 } | 3439 } |
| 2942 | 3440 |
| 2943 | 3441 |
| 2984 if(! GAIM_BLIST_NODE_IS_BUDDY(node)) | 3482 if(! GAIM_BLIST_NODE_IS_BUDDY(node)) |
| 2985 return l; | 3483 return l; |
| 2986 | 3484 |
| 2987 l = g_list_append(l, NULL); | 3485 l = g_list_append(l, NULL); |
| 2988 | 3486 |
| 2989 act = gaim_blist_node_action_new("Invite to Conference...", | 3487 act = gaim_blist_node_action_new(_("Invite to Conference..."), |
| 2990 blist_menu_conf, NULL, NULL); | 3488 blist_menu_conf, NULL, NULL); |
| 2991 l = g_list_append(l, act); | 3489 l = g_list_append(l, act); |
| 2992 | 3490 |
| 2993 /** note: this never gets called for a GaimGroup, have to use the | 3491 /** note: this never gets called for a GaimGroup, have to use the |
| 2994 blist-node-extended-menu signal for that. The function | 3492 blist-node-extended-menu signal for that. The function |
| 3002 static GList *mw_prpl_chat_info(GaimConnection *gc) { | 3500 static GList *mw_prpl_chat_info(GaimConnection *gc) { |
| 3003 GList *l = NULL; | 3501 GList *l = NULL; |
| 3004 struct proto_chat_entry *pce; | 3502 struct proto_chat_entry *pce; |
| 3005 | 3503 |
| 3006 pce = g_new0(struct proto_chat_entry, 1); | 3504 pce = g_new0(struct proto_chat_entry, 1); |
| 3007 pce->label = "Topic:"; | 3505 pce->label = _("Topic:"); |
| 3008 pce->identifier = CHAT_KEY_TOPIC; | 3506 pce->identifier = CHAT_KEY_TOPIC; |
| 3009 l = g_list_append(l, pce); | 3507 l = g_list_append(l, pce); |
| 3010 | 3508 |
| 3011 return l; | 3509 return l; |
| 3012 } | 3510 } |
| 3030 | 3528 |
| 3031 static void mw_prpl_login(GaimAccount *acct); | 3529 static void mw_prpl_login(GaimAccount *acct); |
| 3032 | 3530 |
| 3033 | 3531 |
| 3034 static void prompt_host_cancel_cb(GaimConnection *gc) { | 3532 static void prompt_host_cancel_cb(GaimConnection *gc) { |
| 3035 gaim_connection_error(gc, "No Sametime Community Server specified"); | 3533 gaim_connection_error(gc, _("No Sametime Community Server specified")); |
| 3036 } | 3534 } |
| 3037 | 3535 |
| 3038 | 3536 |
| 3039 static void prompt_host_ok_cb(GaimConnection *gc, const char *host) { | 3537 static void prompt_host_ok_cb(GaimConnection *gc, const char *host) { |
| 3040 if(host && *host) { | 3538 if(host && *host) { |
| 3041 GaimAccount *acct; | 3539 GaimAccount *acct = gaim_connection_get_account(gc); |
| 3042 | |
| 3043 acct = gaim_connection_get_account(gc); | |
| 3044 gaim_account_set_string(acct, MW_KEY_HOST, host); | 3540 gaim_account_set_string(acct, MW_KEY_HOST, host); |
| 3045 | |
| 3046 mw_prpl_login(acct); | 3541 mw_prpl_login(acct); |
| 3047 | 3542 |
| 3048 } else { | 3543 } else { |
| 3049 prompt_host_cancel_cb(gc); | 3544 prompt_host_cancel_cb(gc); |
| 3050 } | 3545 } |
| 3054 static void prompt_host(GaimConnection *gc) { | 3549 static void prompt_host(GaimConnection *gc) { |
| 3055 GaimAccount *acct; | 3550 GaimAccount *acct; |
| 3056 char *msg; | 3551 char *msg; |
| 3057 | 3552 |
| 3058 acct = gaim_connection_get_account(gc); | 3553 acct = gaim_connection_get_account(gc); |
| 3059 msg = ("No host or IP address has been configured for the" | 3554 msg = _("No host or IP address has been configured for the" |
| 3060 " Meanwhile account %s. Please enter one below to" | 3555 " Meanwhile account %s. Please enter one below to" |
| 3061 " continue logging in."); | 3556 " continue logging in."); |
| 3062 msg = g_strdup_printf(msg, NSTR(gaim_account_get_username(acct))); | 3557 msg = g_strdup_printf(msg, NSTR(gaim_account_get_username(acct))); |
| 3063 | 3558 |
| 3064 gaim_request_input(gc, "Meanwhile Connection Setup", | 3559 gaim_request_input(gc, _("Meanwhile Connection Setup"), |
| 3065 "No Sametime Community Server Specified", msg, | 3560 _("No Sametime Community Server Specified"), msg, |
| 3066 MW_PLUGIN_DEFAULT_HOST, FALSE, FALSE, NULL, | 3561 MW_PLUGIN_DEFAULT_HOST, FALSE, FALSE, NULL, |
| 3067 "Connect", G_CALLBACK(prompt_host_ok_cb), | 3562 _("Connect"), G_CALLBACK(prompt_host_ok_cb), |
| 3068 "Cancel", G_CALLBACK(prompt_host_cancel_cb), | 3563 _("Cancel"), G_CALLBACK(prompt_host_cancel_cb), |
| 3069 gc); | 3564 gc); |
| 3070 | 3565 |
| 3071 g_free(msg); | 3566 g_free(msg); |
| 3072 } | 3567 } |
| 3073 | 3568 |
| 3118 mwSession_setProperty(pd->session, mwSession_AUTH_USER_ID, user, g_free); | 3613 mwSession_setProperty(pd->session, mwSession_AUTH_USER_ID, user, g_free); |
| 3119 mwSession_setProperty(pd->session, mwSession_AUTH_PASSWORD, pass, NULL); | 3614 mwSession_setProperty(pd->session, mwSession_AUTH_PASSWORD, pass, NULL); |
| 3120 mwSession_setProperty(pd->session, mwSession_CLIENT_TYPE_ID, | 3615 mwSession_setProperty(pd->session, mwSession_CLIENT_TYPE_ID, |
| 3121 GUINT_TO_POINTER(MW_CLIENT_TYPE_ID), NULL); | 3616 GUINT_TO_POINTER(MW_CLIENT_TYPE_ID), NULL); |
| 3122 | 3617 |
| 3123 gaim_connection_update_progress(gc, "Connecting", 1, MW_CONNECT_STEPS); | 3618 gaim_connection_update_progress(gc, _("Connecting"), 1, MW_CONNECT_STEPS); |
| 3124 | 3619 |
| 3125 if(gaim_proxy_connect(account, host, port, connect_cb, pd)) { | 3620 if(gaim_proxy_connect(account, host, port, connect_cb, pd)) { |
| 3126 gaim_connection_error(gc, "Unable to connect to host"); | 3621 gaim_connection_error(gc, _("Unable to connect to host")); |
| 3127 } | 3622 } |
| 3128 } | 3623 } |
| 3129 | 3624 |
| 3130 | 3625 |
| 3131 static void mw_prpl_close(GaimConnection *gc) { | 3626 static void mw_prpl_close(GaimConnection *gc) { |
| 3175 srand(time(0) ^ rand()); | 3670 srand(time(0) ^ rand()); |
| 3176 return g_strdup_printf(c, rand() & 0xfff, rand() & 0xffff); | 3671 return g_strdup_printf(c, rand() & 0xfff, rand() & 0xffff); |
| 3177 } | 3672 } |
| 3178 | 3673 |
| 3179 | 3674 |
| 3675 /** determine content type from extension. Not so happy about this, | |
| 3676 but I don't want to actually write image type detection */ | |
| 3180 static const char *im_mime_img_content_type(GaimStoredImage *img) { | 3677 static const char *im_mime_img_content_type(GaimStoredImage *img) { |
| 3181 const char *fn = gaim_imgstore_get_filename(img); | 3678 const char *fn = gaim_imgstore_get_filename(img); |
| 3182 | 3679 |
| 3183 fn = strrchr(fn, '.'); | 3680 fn = strrchr(fn, '.'); |
| 3184 if(! fn) { | 3681 if(! fn) { |
| 3206 const char *fn = gaim_imgstore_get_filename(img); | 3703 const char *fn = gaim_imgstore_get_filename(img); |
| 3207 return g_strdup_printf("attachment; filename=\"%s\"", fn); | 3704 return g_strdup_printf("attachment; filename=\"%s\"", fn); |
| 3208 } | 3705 } |
| 3209 | 3706 |
| 3210 | 3707 |
| 3708 /** turn an IM with embedded images into a multi-part mime document */ | |
| 3211 static char *im_mime_convert(const char *message) { | 3709 static char *im_mime_convert(const char *message) { |
| 3212 GString *str; | 3710 GString *str; |
| 3213 GaimMimeDocument *doc; | 3711 GaimMimeDocument *doc; |
| 3214 GaimMimePart *part; | 3712 GaimMimePart *part; |
| 3215 | 3713 |
| 3305 | 3803 |
| 3306 return tmp; | 3804 return tmp; |
| 3307 } | 3805 } |
| 3308 | 3806 |
| 3309 | 3807 |
| 3808 static char *im_try_convert(const char *msg, | |
| 3809 const char *enc_to, | |
| 3810 const char *enc_from) { | |
| 3811 char *ret; | |
| 3812 GError *error = NULL; | |
| 3813 | |
| 3814 ret = g_convert(msg, -1, enc_to, enc_from, NULL, NULL, &error); | |
| 3815 if(error) { | |
| 3816 /* if there's something that just won't convert, leave it as UTF-8 */ | |
| 3817 DEBUG_INFO("problem converting to %s, preserving %s: %s\n", | |
| 3818 NSTR(enc_to), NSTR(enc_from), NSTR(error->message)); | |
| 3819 g_error_free(error); | |
| 3820 } | |
| 3821 | |
| 3822 return ret; | |
| 3823 } | |
| 3824 | |
| 3825 | |
| 3826 static char *im_encode(GaimConnection *gc, const char *msg) { | |
| 3827 GaimAccount *acct; | |
| 3828 const char *enc; | |
| 3829 | |
| 3830 acct = gaim_connection_get_account(gc); | |
| 3831 g_return_val_if_fail(acct != NULL, NULL); | |
| 3832 | |
| 3833 enc = gaim_account_get_string(acct, MW_KEY_ENCODING, | |
| 3834 MW_PLUGIN_DEFAULT_ENCODING); | |
| 3835 | |
| 3836 return im_try_convert(msg, enc, "UTF-8"); | |
| 3837 } | |
| 3838 | |
| 3839 | |
| 3310 static int mw_prpl_send_im(GaimConnection *gc, | 3840 static int mw_prpl_send_im(GaimConnection *gc, |
| 3311 const char *name, | 3841 const char *name, |
| 3312 const char *message, | 3842 const char *message, |
| 3313 GaimConvImFlags flags) { | 3843 GaimConvImFlags flags) { |
| 3314 | 3844 |
| 3315 struct mwGaimPluginData *pd; | 3845 struct mwGaimPluginData *pd; |
| 3316 struct mwIdBlock who = { (char *) name, NULL }; | 3846 struct mwIdBlock who = { (char *) name, NULL }; |
| 3317 struct mwConversation *conv; | 3847 struct mwConversation *conv; |
| 3848 char *msg = NULL; | |
| 3318 | 3849 |
| 3319 g_return_val_if_fail(gc != NULL, 0); | 3850 g_return_val_if_fail(gc != NULL, 0); |
| 3320 pd = gc->proto_data; | 3851 pd = gc->proto_data; |
| 3321 | 3852 |
| 3322 g_return_val_if_fail(pd != NULL, 0); | 3853 g_return_val_if_fail(pd != NULL, 0); |
| 3854 | |
| 3855 msg = im_encode(gc, message); | |
| 3856 if(!msg) msg = g_strdup(message); | |
| 3323 | 3857 |
| 3324 conv = mwServiceIm_getConversation(pd->srvc_im, &who); | 3858 conv = mwServiceIm_getConversation(pd->srvc_im, &who); |
| 3325 | 3859 |
| 3326 /* this detection of features to determine how to send the message | 3860 /* this detection of features to determine how to send the message |
| 3327 (plain, html, or mime) is flawed because the other end of the | 3861 (plain, html, or mime) is flawed because the other end of the |
| 3329 existing formatting in an outgoing message innapropriate. The end | 3863 existing formatting in an outgoing message innapropriate. The end |
| 3330 result is that it may be possible that the other side of the | 3864 result is that it may be possible that the other side of the |
| 3331 conversation will receive a plaintext message with html contents, | 3865 conversation will receive a plaintext message with html contents, |
| 3332 which is bad. I'm not sure how to fix this correctly. */ | 3866 which is bad. I'm not sure how to fix this correctly. */ |
| 3333 | 3867 |
| 3334 if(strstr(message, "<img ") || strstr(message, "<IMG ")) | 3868 if(strstr(msg, "<img ") || strstr(msg, "<IMG ")) |
| 3335 flags |= GAIM_CONV_IM_IMAGES; | 3869 flags |= GAIM_CONV_IM_IMAGES; |
| 3336 | 3870 |
| 3337 if(mwConversation_isOpen(conv)) { | 3871 if(mwConversation_isOpen(conv)) { |
| 3338 char *msg = NULL; | 3872 char *tmp; |
| 3339 int ret; | 3873 int ret; |
| 3340 | 3874 |
| 3341 if((flags & GAIM_CONV_IM_IMAGES) && | 3875 if((flags & GAIM_CONV_IM_IMAGES) && |
| 3342 mwConversation_supports(conv, mwImSend_MIME)) { | 3876 mwConversation_supports(conv, mwImSend_MIME)) { |
| 3343 | 3877 /* send a MIME message */ |
| 3344 msg = im_mime_convert(message); | 3878 |
| 3345 ret = mwConversation_send(conv, mwImSend_MIME, msg); | 3879 tmp = im_mime_convert(msg); |
| 3880 g_free(msg); | |
| 3881 | |
| 3882 ret = mwConversation_send(conv, mwImSend_MIME, tmp); | |
| 3883 g_free(tmp); | |
| 3346 | 3884 |
| 3347 } else if(mwConversation_supports(conv, mwImSend_HTML)) { | 3885 } else if(mwConversation_supports(conv, mwImSend_HTML)) { |
| 3886 /* send an HTML message */ | |
| 3348 | 3887 |
| 3349 /* need to do this to get the \n to <br> conversion */ | 3888 /* need to do this to get the \n to <br> conversion */ |
| 3350 msg = gaim_strdup_withhtml(message); | 3889 tmp = gaim_strdup_withhtml(msg); |
| 3351 ret = mwConversation_send(conv, mwImSend_HTML, msg); | 3890 g_free(msg); |
| 3891 | |
| 3892 ret = mwConversation_send(conv, mwImSend_HTML, tmp); | |
| 3893 g_free(tmp); | |
| 3352 | 3894 |
| 3353 } else { | 3895 } else { |
| 3354 ret = mwConversation_send(conv, mwImSend_PLAIN, message); | 3896 /* default to text */ |
| 3897 ret = mwConversation_send(conv, mwImSend_PLAIN, msg); | |
| 3898 g_free(msg); | |
| 3355 } | 3899 } |
| 3356 | 3900 |
| 3901 return !ret; | |
| 3902 | |
| 3903 } else { | |
| 3904 | |
| 3905 /* queue up the message safely as plain text */ | |
| 3906 char *tmp = gaim_markup_strip_html(msg); | |
| 3357 g_free(msg); | 3907 g_free(msg); |
| 3358 return !ret; | 3908 |
| 3359 | 3909 convo_queue(conv, mwImSend_PLAIN, tmp); |
| 3360 } else { | 3910 g_free(tmp); |
| 3361 char *msg; | |
| 3362 | |
| 3363 /* queue up the message safely as plain text */ | |
| 3364 msg = gaim_markup_strip_html(message); | |
| 3365 convo_queue(conv, mwImSend_PLAIN, msg); | |
| 3366 g_free(msg); | |
| 3367 | 3911 |
| 3368 if(! mwConversation_isPending(conv)) | 3912 if(! mwConversation_isPending(conv)) |
| 3369 mwConversation_open(conv); | 3913 mwConversation_open(conv); |
| 3370 | 3914 |
| 3371 return 1; | 3915 return 1; |
| 3408 } | 3952 } |
| 3409 | 3953 |
| 3410 | 3954 |
| 3411 static void mw_prpl_get_info(GaimConnection *gc, const char *who) { | 3955 static void mw_prpl_get_info(GaimConnection *gc, const char *who) { |
| 3412 | 3956 |
| 3957 struct mwAwareIdBlock idb = { mwAware_USER, (char *) who, NULL }; | |
| 3958 | |
| 3413 struct mwGaimPluginData *pd; | 3959 struct mwGaimPluginData *pd; |
| 3414 struct mwAwareIdBlock idb = { mwAware_USER, (char *) who, NULL }; | |
| 3415 | |
| 3416 GaimAccount *acct; | 3960 GaimAccount *acct; |
| 3417 GaimBuddy *b; | 3961 GaimBuddy *b; |
| 3418 | 3962 |
| 3419 GString *str; | 3963 GString *str; |
| 3420 const char *tmp; | 3964 const char *tmp; |
| 3421 guint32 type; | 3965 |
| 3966 g_return_if_fail(who != NULL); | |
| 3967 g_return_if_fail(*who != '\0'); | |
| 3422 | 3968 |
| 3423 pd = gc->proto_data; | 3969 pd = gc->proto_data; |
| 3424 | 3970 |
| 3425 acct = gaim_connection_get_account(gc); | 3971 acct = gaim_connection_get_account(gc); |
| 3426 b = gaim_find_buddy(acct, who); | 3972 b = gaim_find_buddy(acct, who); |
| 3427 | 3973 |
| 3428 g_return_if_fail(b != NULL); | |
| 3429 | |
| 3430 str = g_string_new(NULL); | 3974 str = g_string_new(NULL); |
| 3431 | 3975 |
| 3432 g_string_append_printf(str, "<b>User ID:</b> %s<br>", b->name); | 3976 if(g_str_has_prefix(who, "@E ")) { |
| 3433 | 3977 g_string_append(str, _("<b>External User</b><br>")); |
| 3434 if(b->server_alias) { | 3978 } |
| 3435 g_string_append_printf(str, "<b>Full Name:</b> %s<br>", | 3979 |
| 3436 b->server_alias); | 3980 g_string_append_printf(str, _("<b>User ID:</b> %s<br>"), who); |
| 3437 } | 3981 |
| 3438 | 3982 if(b) { |
| 3439 type = gaim_blist_node_get_int((GaimBlistNode *) b, BUDDY_KEY_CLIENT); | 3983 guint32 type; |
| 3440 if(type) { | 3984 |
| 3441 g_string_append(str, "<b>Last Known Client:</b> "); | 3985 if(b->server_alias) { |
| 3442 | 3986 g_string_append_printf(str, _("<b>Full Name:</b> %s<br>"), |
| 3443 tmp = mwLoginType_getName(type); | 3987 b->server_alias); |
| 3444 if(tmp) { | 3988 } |
| 3445 g_string_append(str, tmp); | 3989 |
| 3446 g_string_append(str, "<br>"); | 3990 type = gaim_blist_node_get_int((GaimBlistNode *) b, BUDDY_KEY_CLIENT); |
| 3447 | 3991 if(type) { |
| 3448 } else { | 3992 g_string_append(str, _("<b>Last Known Client:</b> ")); |
| 3449 g_string_append_printf(str, "Unknown (0x%04x)<br>", type); | 3993 |
| 3994 tmp = mwLoginType_getName(type); | |
| 3995 if(tmp) { | |
| 3996 g_string_append(str, tmp); | |
| 3997 g_string_append(str, "<br>"); | |
| 3998 | |
| 3999 } else { | |
| 4000 g_string_append_printf(str, _("Unknown (0x%04x)<br>"), type); | |
| 4001 } | |
| 3450 } | 4002 } |
| 3451 } | 4003 } |
| 3452 | 4004 |
| 3453 tmp = user_supports_text(pd->srvc_aware, who); | 4005 tmp = user_supports_text(pd->srvc_aware, who); |
| 3454 if(tmp) { | 4006 if(tmp) { |
| 3455 g_string_append_printf(str, "<b>Supports:</b> %s<br>", tmp); | 4007 g_string_append_printf(str, _("<b>Supports:</b> %s<br>"), tmp); |
| 3456 g_free((char *) tmp); | 4008 g_free((char *) tmp); |
| 3457 } | 4009 } |
| 3458 | 4010 |
| 3459 tmp = status_text(b); | 4011 if(b) { |
| 3460 g_string_append_printf(str, "<b>Status:</b> %s", tmp); | 4012 tmp = status_text(b); |
| 3461 | 4013 g_string_append_printf(str, _("<b>Status:</b> %s"), tmp); |
| 3462 g_string_append(str, "<hr>"); | 4014 |
| 3463 | 4015 g_string_append(str, "<hr>"); |
| 3464 tmp = mwServiceAware_getText(pd->srvc_aware, &idb); | 4016 |
| 3465 g_string_append(str, tmp); | 4017 tmp = mwServiceAware_getText(pd->srvc_aware, &idb); |
| 4018 if(tmp) g_string_append(str, tmp); | |
| 4019 } | |
| 3466 | 4020 |
| 3467 /* @todo emit a signal to allow a plugin to override the display of | 4021 /* @todo emit a signal to allow a plugin to override the display of |
| 3468 this notification, so that it can create its own */ | 4022 this notification, so that it can create its own */ |
| 3469 | 4023 |
| 3470 gaim_notify_userinfo(gc, who, str->str, NULL, NULL); | 4024 gaim_notify_userinfo(gc, who, str->str, NULL, NULL); |
| 3471 | 4025 |
| 3472 g_string_free(str, TRUE); | 4026 g_string_free(str, TRUE); |
| 3473 } | 4027 } |
| 3474 | 4028 |
| 3475 | 4029 |
| 3476 static void mw_prpl_set_status(GaimAccount *acct, GaimStatus *status) { | 4030 static void mw_prpl_set_status(GaimAccount *acct, GaimStatus *status) { |
| 3477 GaimConnection *gc; | 4031 GaimConnection *gc; |
| 3478 const char *state; | 4032 const char *state; |
| 3479 char *message = NULL; | 4033 char *message = NULL; |
| 3480 struct mwSession *session; | 4034 struct mwSession *session; |
| 3481 struct mwUserStatus stat; | 4035 struct mwUserStatus stat; |
| 3482 | 4036 |
| 3483 g_return_if_fail(acct != NULL); | 4037 g_return_if_fail(acct != NULL); |
| 3484 gc = gaim_account_get_connection(acct); | 4038 gc = gaim_account_get_connection(acct); |
| 3485 | 4039 |
| 3486 state = gaim_status_get_id(status); | 4040 state = gaim_status_get_id(status); |
| 3487 | 4041 |
| 3488 gaim_debug_info("meanwhile", "Set status to %s\n", gaim_status_get_name(status)); | 4042 gaim_debug_info("meanwhile", "Set status to %s\n", |
| 3489 | 4043 gaim_status_get_name(status)); |
| 4044 | |
| 3490 g_return_if_fail(gc != NULL); | 4045 g_return_if_fail(gc != NULL); |
| 3491 | 4046 |
| 3492 session = gc_to_session(gc); | 4047 session = gc_to_session(gc); |
| 3493 g_return_if_fail(session != NULL); | 4048 g_return_if_fail(session != NULL); |
| 3494 | 4049 |
| 3495 /* get a working copy of the current status */ | 4050 /* get a working copy of the current status */ |
| 3496 mwUserStatus_clone(&stat, mwSession_getUserStatus(session)); | 4051 mwUserStatus_clone(&stat, mwSession_getUserStatus(session)); |
| 3497 | 4052 |
| 3498 /* determine the state */ | 4053 /* determine the state */ |
| 3499 if(! strcmp(state, MW_STATE_ACTIVE)) { | 4054 if(! strcmp(state, MW_STATE_ACTIVE)) { |
| 3500 stat.status = mwStatus_ACTIVE; | 4055 stat.status = mwStatus_ACTIVE; |
| 3501 | 4056 |
| 3502 } else if(! strcmp(state, MW_STATE_AWAY)) { | 4057 } else if(! strcmp(state, MW_STATE_AWAY)) { |
| 3503 stat.status = mwStatus_AWAY; | 4058 stat.status = mwStatus_AWAY; |
| 3504 | 4059 |
| 3505 } else if(! strcmp(state, MW_STATE_BUSY)) { | 4060 } else if(! strcmp(state, MW_STATE_BUSY)) { |
| 3506 stat.status = mwStatus_BUSY; | 4061 stat.status = mwStatus_BUSY; |
| 3507 } | 4062 } |
| 3508 | 4063 |
| 3509 /* determine the message */ | 4064 /* determine the message */ |
| 3510 switch(stat.status) { | 4065 switch(stat.status) { |
| 3511 case mwStatus_ACTIVE: | 4066 case mwStatus_ACTIVE: |
| 3512 stat.time = 0; | 4067 stat.time = 0; |
| 3513 case mwStatus_AWAY: | 4068 case mwStatus_AWAY: |
| 3514 case mwStatus_BUSY: | 4069 case mwStatus_BUSY: |
| 3515 message = (char *)gaim_status_get_attr_string(status, MW_STATE_MESSAGE); | 4070 message = (char *)gaim_status_get_attr_string(status, MW_STATE_MESSAGE); |
| 3516 break; | 4071 break; |
| 3517 } | 4072 } |
| 3518 | 4073 |
| 3519 if(message) { | 4074 if(message) { |
| 3520 /* all the possible non-NULL values of message up to this point | 4075 /* all the possible non-NULL values of message up to this point |
| 3521 are const, so we don't need to free them */ | 4076 are const, so we don't need to free them */ |
| 3522 message = gaim_markup_strip_html(message); | 4077 message = gaim_markup_strip_html(message); |
| 3523 } | 4078 } |
| 3524 | 4079 |
| 3525 /* out with the old */ | 4080 /* out with the old */ |
| 3526 g_free(stat.desc); | 4081 g_free(stat.desc); |
| 3527 | 4082 |
| 3528 /* in with the new */ | 4083 /* in with the new */ |
| 3529 stat.desc = (char *) message; | 4084 stat.desc = (char *) message; |
| 3530 | 4085 |
| 3531 mwSession_setUserStatus(session, &stat); | 4086 mwSession_setUserStatus(session, &stat); |
| 3532 mwUserStatus_clear(&stat); | 4087 mwUserStatus_clear(&stat); |
| 3533 } | 4088 } |
| 3534 | 4089 |
| 3535 | 4090 |
| 3536 static void mw_prpl_set_idle(GaimConnection *gc, int time) { | 4091 static void mw_prpl_set_idle(GaimConnection *gc, int t) { |
| 3537 struct mwSession *session; | 4092 struct mwSession *session; |
| 3538 struct mwUserStatus stat; | 4093 struct mwUserStatus stat; |
| 3539 | 4094 |
| 3540 session = gc_to_session(gc); | 4095 session = gc_to_session(gc); |
| 3541 g_return_if_fail(session != NULL); | 4096 g_return_if_fail(session != NULL); |
| 3542 | 4097 |
| 3543 mwUserStatus_clone(&stat, mwSession_getUserStatus(session)); | 4098 mwUserStatus_clone(&stat, mwSession_getUserStatus(session)); |
| 3544 | 4099 |
| 3545 if(time > 0 && stat.status == mwStatus_ACTIVE) { | 4100 if(t > 0 && stat.status == mwStatus_ACTIVE) { |
| 4101 time_t now = time(NULL); | |
| 4102 stat.time = now - t; | |
| 3546 stat.status = mwStatus_IDLE; | 4103 stat.status = mwStatus_IDLE; |
| 3547 | 4104 |
| 3548 } else if(time == 0 && stat.status == mwStatus_IDLE) { | 4105 } else if(t == 0 && stat.status == mwStatus_IDLE) { |
| 4106 stat.time = 0; | |
| 3549 stat.status = mwStatus_ACTIVE; | 4107 stat.status = mwStatus_ACTIVE; |
| 3550 } | 4108 } |
| 3551 | 4109 |
| 3552 /** @todo actually put the idle time in the user status */ | |
| 3553 | |
| 3554 mwSession_setUserStatus(session, &stat); | 4110 mwSession_setUserStatus(session, &stat); |
| 3555 mwUserStatus_clear(&stat); | 4111 mwUserStatus_clear(&stat); |
| 4112 } | |
| 4113 | |
| 4114 | |
| 4115 static struct resolved_id *resolved_id_new(const char *id, | |
| 4116 const char *name) { | |
| 4117 | |
| 4118 struct resolved_id *rid = g_new0(struct resolved_id, 1); | |
| 4119 rid->id = g_strdup(id); | |
| 4120 rid->name = g_strdup(name); | |
| 4121 return rid; | |
| 4122 } | |
| 4123 | |
| 4124 | |
| 4125 static void resolved_id_free(struct resolved_id *rid) { | |
| 4126 if(rid) { | |
| 4127 g_free(rid->id); | |
| 4128 g_free(rid->name); | |
| 4129 g_free(rid); | |
| 4130 } | |
| 3556 } | 4131 } |
| 3557 | 4132 |
| 3558 | 4133 |
| 3559 static void add_resolved_done(const char *id, const char *name, | 4134 static void add_resolved_done(const char *id, const char *name, |
| 3560 GaimBuddy *buddy) { | 4135 GaimBuddy *buddy) { |
| 3581 buddy_add(pd, buddy); | 4156 buddy_add(pd, buddy); |
| 3582 } | 4157 } |
| 3583 | 4158 |
| 3584 | 4159 |
| 3585 static void multi_resolved_cleanup(GaimRequestFields *fields) { | 4160 static void multi_resolved_cleanup(GaimRequestFields *fields) { |
| 3586 | |
| 3587 GaimRequestField *f; | 4161 GaimRequestField *f; |
| 3588 const GList *l; | 4162 const GList *l; |
| 3589 | 4163 |
| 3590 f = gaim_request_fields_get_field(fields, "user"); | 4164 f = gaim_request_fields_get_field(fields, "user"); |
| 3591 l = gaim_request_field_list_get_items(f); | 4165 l = gaim_request_field_list_get_items(f); |
| 3593 for(; l; l = l->next) { | 4167 for(; l; l = l->next) { |
| 3594 const char *i = l->data; | 4168 const char *i = l->data; |
| 3595 struct resolved_id *res; | 4169 struct resolved_id *res; |
| 3596 | 4170 |
| 3597 res = gaim_request_field_list_get_data(f, i); | 4171 res = gaim_request_field_list_get_data(f, i); |
| 3598 | 4172 resolved_id_free(res); |
| 3599 g_free(res->id); | |
| 3600 g_free(res->name); | |
| 3601 g_free(res); | |
| 3602 } | 4173 } |
| 3603 } | 4174 } |
| 3604 | 4175 |
| 3605 | 4176 |
| 3606 static void multi_resolved_cancel(GaimBuddy *buddy, | 4177 static void multi_resolved_cancel(GaimBuddy *buddy, |
| 3636 multi_resolved_cleanup(fields); | 4207 multi_resolved_cleanup(fields); |
| 3637 | 4208 |
| 3638 } else { | 4209 } else { |
| 3639 multi_resolved_cancel(buddy, fields); | 4210 multi_resolved_cancel(buddy, fields); |
| 3640 } | 4211 } |
| 4212 } | |
| 4213 | |
| 4214 | |
| 4215 static void foreach_resolved_id(char *key, char *val, GList **l) { | |
| 4216 struct resolved_id *res = resolved_id_new(key, val); | |
| 4217 *l = g_list_prepend(*l, res); | |
| 4218 } | |
| 4219 | |
| 4220 | |
| 4221 static gint resolved_id_comp(struct resolved_id *a, struct resolved_id *b) { | |
| 4222 return g_ascii_strcasecmp(a->name, b->name); | |
| 3641 } | 4223 } |
| 3642 | 4224 |
| 3643 | 4225 |
| 3644 static void multi_resolved_query(struct mwResolveResult *result, | 4226 static void multi_resolved_query(struct mwResolveResult *result, |
| 3645 GaimBuddy *buddy) { | 4227 GaimBuddy *buddy) { |
| 3646 GaimRequestFields *fields; | 4228 GaimRequestFields *fields; |
| 3647 GaimRequestFieldGroup *g; | 4229 GaimRequestFieldGroup *g; |
| 3648 GaimRequestField *f; | 4230 GaimRequestField *f; |
| 4231 GHashTable *hash; | |
| 3649 GList *l; | 4232 GList *l; |
| 3650 char *msgA, *msgB; | 4233 char *msgA, *msgB; |
| 3651 | 4234 |
| 3652 GaimAccount *acct; | 4235 GaimAccount *acct; |
| 3653 GaimConnection *gc; | 4236 GaimConnection *gc; |
| 3666 | 4249 |
| 3667 /* note that Gaim segfaults if you don't add the group to the fields | 4250 /* note that Gaim segfaults if you don't add the group to the fields |
| 3668 before you add a required field to the group. Feh. */ | 4251 before you add a required field to the group. Feh. */ |
| 3669 gaim_request_fields_add_group(fields, g); | 4252 gaim_request_fields_add_group(fields, g); |
| 3670 | 4253 |
| 3671 f = gaim_request_field_list_new("user", "Possible Matches"); | 4254 f = gaim_request_field_list_new("user", _("Possible Matches")); |
| 3672 gaim_request_field_list_set_multi_select(f, FALSE); | 4255 gaim_request_field_list_set_multi_select(f, FALSE); |
| 3673 gaim_request_field_set_required(f, TRUE); | 4256 gaim_request_field_set_required(f, TRUE); |
| 3674 | 4257 |
| 4258 /* collect results into a set of identities */ | |
| 4259 hash = g_hash_table_new(g_str_hash, g_str_equal); | |
| 3675 for(l = result->matches; l; l = l->next) { | 4260 for(l = result->matches; l; l = l->next) { |
| 3676 struct mwResolveMatch *match = l->data; | 4261 struct mwResolveMatch *match = l->data; |
| 3677 struct resolved_id *res = g_new0(struct resolved_id, 1); | 4262 |
| 4263 if(!match->id || !match->name) | |
| 4264 continue; | |
| 4265 | |
| 4266 g_hash_table_insert(hash, match->id, match->name); | |
| 4267 } | |
| 4268 | |
| 4269 /* collect set into a list of structures */ | |
| 4270 l = NULL; | |
| 4271 g_hash_table_foreach(hash, (GHFunc) foreach_resolved_id, &l); | |
| 4272 g_list_sort(l, (GCompareFunc) resolved_id_comp); | |
| 4273 | |
| 4274 /* populate choices in request field */ | |
| 4275 for(; l; l = l->next) { | |
| 4276 struct resolved_id *res = l->data; | |
| 3678 char *label; | 4277 char *label; |
| 3679 | 4278 |
| 3680 res->id = g_strdup(match->id); | |
| 3681 res->name = g_strdup(match->name); | |
| 3682 | |
| 3683 /* fixes bug 1178603 by making the selection label a combination | 4279 /* fixes bug 1178603 by making the selection label a combination |
| 3684 of the full name and the user id. Problems arrise when multiple | 4280 of the full name and the user id. Problems arrise when multiple |
| 3685 entries have identical labels */ | 4281 entries have identical labels */ |
| 3686 label = g_strdup_printf("%s (%s)", NSTR(res->name), NSTR(res->id)); | 4282 label = g_strdup_printf("%s (%s)", NSTR(res->name), NSTR(res->id)); |
| 3687 gaim_request_field_list_add(f, label, res); | 4283 gaim_request_field_list_add(f, label, res); |
| 3688 g_free(label); | 4284 g_free(label); |
| 3689 } | 4285 } |
| 3690 | 4286 |
| 4287 g_list_free(l); | |
| 4288 | |
| 3691 gaim_request_field_group_add_field(g, f); | 4289 gaim_request_field_group_add_field(g, f); |
| 3692 | 4290 |
| 3693 msgA = ("An ambiguous user ID was entered"); | 4291 msgA = _("An ambiguous user ID was entered"); |
| 3694 msgB = ("The identifier '%s' may possibly refer to any of the following" | 4292 msgB = _("The identifier '%s' may possibly refer to any of the following" |
| 3695 " users. Please select the correct user from the list below to" | 4293 " users. Please select the correct user from the list below to" |
| 3696 " add them to your buddy list."); | 4294 " add them to your buddy list."); |
| 3697 msgB = g_strdup_printf(msgB, result->name); | 4295 msgB = g_strdup_printf(msgB, result->name); |
| 3698 | 4296 |
| 3699 gaim_request_fields(gc, "Select User to Add", | 4297 gaim_request_fields(gc, _("Select User to Add"), |
| 3700 msgA, msgB, fields, | 4298 msgA, msgB, fields, |
| 3701 "Add User", G_CALLBACK(multi_resolved_cb), | 4299 _("Add User"), G_CALLBACK(multi_resolved_cb), |
| 3702 "Cancel", G_CALLBACK(multi_resolved_cancel), | 4300 _("Cancel"), G_CALLBACK(multi_resolved_cancel), |
| 3703 buddy); | 4301 buddy); |
| 3704 g_free(msgB); | 4302 g_free(msgB); |
| 3705 } | 4303 } |
| 3706 | 4304 |
| 3707 | 4305 |
| 3757 | 4355 |
| 3758 if(res && res->name) { | 4356 if(res && res->name) { |
| 3759 /* compose and display an error message */ | 4357 /* compose and display an error message */ |
| 3760 char *msgA, *msgB; | 4358 char *msgA, *msgB; |
| 3761 | 4359 |
| 3762 msgA = "Unable to add user: user not found"; | 4360 msgA = _("Unable to add user: user not found"); |
| 3763 | 4361 |
| 3764 msgB = ("The identifier '%s' did not match any users in your" | 4362 msgB = _("The identifier '%s' did not match any users in your" |
| 3765 " Sametime community. This entry has been removed from" | 4363 " Sametime community. This entry has been removed from" |
| 3766 " your buddy list."); | 4364 " your buddy list."); |
| 3767 msgB = g_strdup_printf(msgB, NSTR(res->name)); | 4365 msgB = g_strdup_printf(msgB, NSTR(res->name)); |
| 3768 | 4366 |
| 3769 gaim_notify_error(gc, "Unable to add user", msgA, msgB); | 4367 gaim_notify_error(gc, _("Unable to add user"), msgA, msgB); |
| 3770 | 4368 |
| 3771 g_free(msgB); | 4369 g_free(msgB); |
| 3772 } | 4370 } |
| 3773 } | 4371 } |
| 3774 | 4372 |
| 3784 guint32 req; | 4382 guint32 req; |
| 3785 | 4383 |
| 3786 pd = gc->proto_data; | 4384 pd = gc->proto_data; |
| 3787 srvc = pd->srvc_resolve; | 4385 srvc = pd->srvc_resolve; |
| 3788 | 4386 |
| 4387 /* catch external buddies. They won't be in the resolve service */ | |
| 4388 if(g_str_has_prefix(buddy->name, "@E ")) { | |
| 4389 buddy_add(pd, buddy); | |
| 4390 return; | |
| 4391 } | |
| 4392 | |
| 3789 query = g_list_prepend(NULL, buddy->name); | 4393 query = g_list_prepend(NULL, buddy->name); |
| 3790 flags = mwResolveFlag_FIRST | mwResolveFlag_USERS; | 4394 flags = mwResolveFlag_FIRST | mwResolveFlag_USERS; |
| 3791 | 4395 |
| 3792 req = mwServiceResolve_resolve(srvc, query, flags, add_buddy_resolved, | 4396 req = mwServiceResolve_resolve(srvc, query, flags, add_buddy_resolved, |
| 3793 buddy, NULL); | 4397 buddy, NULL); |
| 3800 } | 4404 } |
| 3801 | 4405 |
| 3802 | 4406 |
| 3803 static void foreach_add_buddies(GaimGroup *group, GList *buddies, | 4407 static void foreach_add_buddies(GaimGroup *group, GList *buddies, |
| 3804 struct mwGaimPluginData *pd) { | 4408 struct mwGaimPluginData *pd) { |
| 3805 | |
| 3806 struct mwAwareList *list; | 4409 struct mwAwareList *list; |
| 3807 | 4410 |
| 3808 list = list_ensure(pd, group); | 4411 list = list_ensure(pd, group); |
| 3809 mwAwareList_addAware(list, buddies); | 4412 mwAwareList_addAware(list, buddies); |
| 3810 g_list_free(buddies); | 4413 g_list_free(buddies); |
| 3997 | 4600 |
| 3998 static void mw_prpl_join_chat(GaimConnection *gc, | 4601 static void mw_prpl_join_chat(GaimConnection *gc, |
| 3999 GHashTable *components) { | 4602 GHashTable *components) { |
| 4000 | 4603 |
| 4001 struct mwGaimPluginData *pd; | 4604 struct mwGaimPluginData *pd; |
| 4002 struct mwServiceConference *srvc; | |
| 4003 struct mwConference *conf = NULL; | |
| 4004 char *c, *t; | 4605 char *c, *t; |
| 4005 | 4606 |
| 4006 pd = gc->proto_data; | 4607 pd = gc->proto_data; |
| 4007 srvc = pd->srvc_conf; | |
| 4008 | 4608 |
| 4009 c = g_hash_table_lookup(components, CHAT_KEY_NAME); | 4609 c = g_hash_table_lookup(components, CHAT_KEY_NAME); |
| 4010 t = g_hash_table_lookup(components, CHAT_KEY_TOPIC); | 4610 t = g_hash_table_lookup(components, CHAT_KEY_TOPIC); |
| 4011 | 4611 |
| 4012 if(c) conf = conf_find(srvc, c); | 4612 if(g_hash_table_lookup(components, CHAT_KEY_IS_PLACE)) { |
| 4013 | 4613 /* use place service */ |
| 4014 if(conf) { | 4614 struct mwServicePlace *srvc; |
| 4015 DEBUG_INFO("accepting conference invitation\n"); | 4615 struct mwPlace *place = NULL; |
| 4016 mwConference_accept(conf); | 4616 |
| 4017 | 4617 srvc = pd->srvc_place; |
| 4618 place = mwPlace_new(srvc, c, t); | |
| 4619 mwPlace_open(place); | |
| 4620 | |
| 4018 } else { | 4621 } else { |
| 4019 DEBUG_INFO("creating new conference\n"); | 4622 /* use conference service */ |
| 4020 conf = mwConference_new(srvc, t); | 4623 struct mwServiceConference *srvc; |
| 4021 mwConference_open(conf); | 4624 struct mwConference *conf = NULL; |
| 4625 | |
| 4626 srvc = pd->srvc_conf; | |
| 4627 if(c) conf = conf_find(srvc, c); | |
| 4628 | |
| 4629 if(conf) { | |
| 4630 DEBUG_INFO("accepting conference invitation\n"); | |
| 4631 mwConference_accept(conf); | |
| 4632 | |
| 4633 } else { | |
| 4634 DEBUG_INFO("creating new conference\n"); | |
| 4635 conf = mwConference_new(srvc, t); | |
| 4636 mwConference_open(conf); | |
| 4637 } | |
| 4022 } | 4638 } |
| 4023 } | 4639 } |
| 4024 | 4640 |
| 4025 | 4641 |
| 4026 static void mw_prpl_reject_chat(GaimConnection *gc, | 4642 static void mw_prpl_reject_chat(GaimConnection *gc, |
| 4031 char *c; | 4647 char *c; |
| 4032 | 4648 |
| 4033 pd = gc->proto_data; | 4649 pd = gc->proto_data; |
| 4034 srvc = pd->srvc_conf; | 4650 srvc = pd->srvc_conf; |
| 4035 | 4651 |
| 4036 c = g_hash_table_lookup(components, CHAT_KEY_NAME); | 4652 if(g_hash_table_lookup(components, CHAT_KEY_IS_PLACE)) { |
| 4037 if(c) { | 4653 ; /* nothing needs doing */ |
| 4038 struct mwConference *conf = conf_find(srvc, c); | 4654 |
| 4039 if(conf) mwConference_reject(conf, ERR_SUCCESS, "Declined"); | 4655 } else { |
| 4656 /* reject conference */ | |
| 4657 c = g_hash_table_lookup(components, CHAT_KEY_NAME); | |
| 4658 if(c) { | |
| 4659 struct mwConference *conf = conf_find(srvc, c); | |
| 4660 if(conf) mwConference_reject(conf, ERR_SUCCESS, "Declined"); | |
| 4661 } | |
| 4040 } | 4662 } |
| 4041 } | 4663 } |
| 4042 | 4664 |
| 4043 | 4665 |
| 4044 static char *mw_prpl_get_chat_name(GHashTable *components) { | 4666 static char *mw_prpl_get_chat_name(GHashTable *components) { |
| 4061 conf = ID_TO_CONF(pd, id); | 4683 conf = ID_TO_CONF(pd, id); |
| 4062 | 4684 |
| 4063 g_return_if_fail(conf != NULL); | 4685 g_return_if_fail(conf != NULL); |
| 4064 | 4686 |
| 4065 mwConference_invite(conf, &idb, invitation); | 4687 mwConference_invite(conf, &idb, invitation); |
| 4688 | |
| 4689 /* @todo: use Place by default instead */ | |
| 4066 } | 4690 } |
| 4067 | 4691 |
| 4068 | 4692 |
| 4069 static void mw_prpl_chat_leave(GaimConnection *gc, | 4693 static void mw_prpl_chat_leave(GaimConnection *gc, |
| 4070 int id) { | 4694 int id) { |
| 4075 pd = gc->proto_data; | 4699 pd = gc->proto_data; |
| 4076 | 4700 |
| 4077 g_return_if_fail(pd != NULL); | 4701 g_return_if_fail(pd != NULL); |
| 4078 conf = ID_TO_CONF(pd, id); | 4702 conf = ID_TO_CONF(pd, id); |
| 4079 | 4703 |
| 4080 g_return_if_fail(conf != NULL); | 4704 if(conf) { |
| 4081 | 4705 mwConference_destroy(conf, ERR_SUCCESS, "Leaving"); |
| 4082 mwConference_destroy(conf, ERR_SUCCESS, "Leaving"); | 4706 |
| 4707 } else { | |
| 4708 struct mwPlace *place = ID_TO_PLACE(pd, id); | |
| 4709 g_return_if_fail(place != NULL); | |
| 4710 | |
| 4711 mwPlace_destroy(place, ERR_SUCCESS); | |
| 4712 } | |
| 4083 } | 4713 } |
| 4084 | 4714 |
| 4085 | 4715 |
| 4086 static void mw_prpl_chat_whisper(GaimConnection *gc, | 4716 static void mw_prpl_chat_whisper(GaimConnection *gc, |
| 4087 int id, | 4717 int id, |
| 4102 pd = gc->proto_data; | 4732 pd = gc->proto_data; |
| 4103 | 4733 |
| 4104 g_return_val_if_fail(pd != NULL, 0); | 4734 g_return_val_if_fail(pd != NULL, 0); |
| 4105 conf = ID_TO_CONF(pd, id); | 4735 conf = ID_TO_CONF(pd, id); |
| 4106 | 4736 |
| 4107 g_return_val_if_fail(conf != NULL, 0); | 4737 if(conf) { |
| 4108 | 4738 return ! mwConference_sendText(conf, message); |
| 4109 return ! mwConference_sendText(conf, message); | 4739 |
| 4740 } else { | |
| 4741 struct mwPlace *place = ID_TO_PLACE(pd, id); | |
| 4742 g_return_val_if_fail(place != NULL, 0); | |
| 4743 | |
| 4744 return ! mwPlace_sendText(place, message); | |
| 4745 } | |
| 4110 } | 4746 } |
| 4111 | 4747 |
| 4112 | 4748 |
| 4113 static void mw_prpl_keepalive(GaimConnection *gc) { | 4749 static void mw_prpl_keepalive(GaimConnection *gc) { |
| 4114 struct mwSession *session; | 4750 struct mwSession *session; |
| 4289 idb.user = xfer->who; | 4925 idb.user = xfer->who; |
| 4290 | 4926 |
| 4291 /* test that we can actually send the file */ | 4927 /* test that we can actually send the file */ |
| 4292 fp = g_fopen(filename, "rb"); | 4928 fp = g_fopen(filename, "rb"); |
| 4293 if(! fp) { | 4929 if(! fp) { |
| 4294 char *msg = g_strdup_printf("Error reading %s: \n%s\n", | 4930 char *msg = g_strdup_printf(_("Error reading file %s: \n%s\n"), |
| 4295 filename, strerror(errno)); | 4931 filename, strerror(errno)); |
| 4296 gaim_xfer_error(gaim_xfer_get_type(xfer), acct, xfer->who, msg); | 4932 gaim_xfer_error(gaim_xfer_get_type(xfer), acct, xfer->who, msg); |
| 4297 g_free(msg); | 4933 g_free(msg); |
| 4298 return; | 4934 return; |
| 4299 } | 4935 } |
| 4323 static void mw_prpl_send_file(GaimConnection *gc, | 4959 static void mw_prpl_send_file(GaimConnection *gc, |
| 4324 const char *who, const char *file) { | 4960 const char *who, const char *file) { |
| 4325 | 4961 |
| 4326 GaimAccount *acct; | 4962 GaimAccount *acct; |
| 4327 GaimXfer *xfer; | 4963 GaimXfer *xfer; |
| 4328 | |
| 4329 DEBUG_INFO("mw_prpl_send_file\n"); | |
| 4330 | 4964 |
| 4331 acct = gaim_connection_get_account(gc); | 4965 acct = gaim_connection_get_account(gc); |
| 4332 | 4966 |
| 4333 xfer = gaim_xfer_new(acct, GAIM_XFER_SEND, who); | 4967 xfer = gaim_xfer_new(acct, GAIM_XFER_SEND, who); |
| 4334 gaim_xfer_set_init_fnc(xfer, ft_outgoing_init); | 4968 gaim_xfer_set_init_fnc(xfer, ft_outgoing_init); |
| 4407 | 5041 |
| 4408 static GaimPluginPrefFrame * | 5042 static GaimPluginPrefFrame * |
| 4409 mw_plugin_get_plugin_pref_frame(GaimPlugin *plugin) { | 5043 mw_plugin_get_plugin_pref_frame(GaimPlugin *plugin) { |
| 4410 GaimPluginPrefFrame *frame; | 5044 GaimPluginPrefFrame *frame; |
| 4411 GaimPluginPref *pref; | 5045 GaimPluginPref *pref; |
| 4412 | 5046 |
| 4413 frame = gaim_plugin_pref_frame_new(); | 5047 frame = gaim_plugin_pref_frame_new(); |
| 4414 | 5048 |
| 4415 pref = gaim_plugin_pref_new_with_label("Remotely Stored Buddy List"); | 5049 pref = gaim_plugin_pref_new_with_label(_("Remotely Stored Buddy List")); |
| 4416 gaim_plugin_pref_frame_add(frame, pref); | 5050 gaim_plugin_pref_frame_add(frame, pref); |
| 4417 | 5051 |
| 4418 | 5052 |
| 4419 pref = gaim_plugin_pref_new_with_name(MW_PRPL_OPT_BLIST_ACTION); | 5053 pref = gaim_plugin_pref_new_with_name(MW_PRPL_OPT_BLIST_ACTION); |
| 4420 gaim_plugin_pref_set_label(pref, "Buddy List Storage Mode"); | 5054 gaim_plugin_pref_set_label(pref, _("Buddy List Storage Mode")); |
| 4421 | 5055 |
| 4422 gaim_plugin_pref_set_type(pref, GAIM_PLUGIN_PREF_CHOICE); | 5056 gaim_plugin_pref_set_type(pref, GAIM_PLUGIN_PREF_CHOICE); |
| 4423 gaim_plugin_pref_add_choice(pref, "Local Buddy List Only", | 5057 gaim_plugin_pref_add_choice(pref, _("Local Buddy List Only"), |
| 4424 GINT_TO_POINTER(BLIST_CHOICE_NONE)); | 5058 GINT_TO_POINTER(blist_choice_LOCAL)); |
| 4425 gaim_plugin_pref_add_choice(pref, "Merge List from Server", | 5059 gaim_plugin_pref_add_choice(pref, _("Merge List from Server"), |
| 4426 GINT_TO_POINTER(BLIST_CHOICE_LOAD)); | 5060 GINT_TO_POINTER(blist_choice_MERGE)); |
| 4427 gaim_plugin_pref_add_choice(pref, "Merge and Save List to Server", | 5061 gaim_plugin_pref_add_choice(pref, _("Merge and Save List to Server"), |
| 4428 GINT_TO_POINTER(BLIST_CHOICE_SAVE)); | 5062 GINT_TO_POINTER(blist_choice_STORE)); |
| 4429 | 5063 gaim_plugin_pref_add_choice(pref, _("Synchronize List with Server"), |
| 4430 #if 0 | 5064 GINT_TO_POINTER(blist_choice_SYNCH)); |
| 4431 /* possible ways to handle: | 5065 |
| 4432 - mark all buddies as NO_SAVE | |
| 4433 - load server list, delete all local buddies not in server list | |
| 4434 */ | |
| 4435 gaim_plugin_pref_add_choice(pref, "Server Buddy List Only", | |
| 4436 GINT_TO_POINTER(BLIST_CHOISE_SERVER)); | |
| 4437 #endif | |
| 4438 | |
| 4439 gaim_plugin_pref_frame_add(frame, pref); | |
| 4440 | |
| 4441 pref = gaim_plugin_pref_new_with_label("General Options"); | |
| 4442 gaim_plugin_pref_frame_add(frame, pref); | |
| 4443 | |
| 4444 pref = gaim_plugin_pref_new_with_name(MW_PRPL_OPT_FORCE_LOGIN); | |
| 4445 gaim_plugin_pref_set_type(pref, GAIM_PLUGIN_PREF_NONE); | |
| 4446 gaim_plugin_pref_set_label(pref, "Force Login (Ignore Login Redirects)"); | |
| 4447 gaim_plugin_pref_frame_add(frame, pref); | |
| 4448 | |
| 4449 pref = gaim_plugin_pref_new_with_name(MW_PRPL_OPT_PSYCHIC); | |
| 4450 gaim_plugin_pref_set_type(pref, GAIM_PLUGIN_PREF_NONE); | |
| 4451 gaim_plugin_pref_set_label(pref, "Enable Psychic Mode"); | |
| 4452 gaim_plugin_pref_frame_add(frame, pref); | |
| 4453 | |
| 4454 pref = gaim_plugin_pref_new_with_name(MW_PRPL_OPT_SAVE_DYNAMIC); | |
| 4455 gaim_plugin_pref_set_type(pref, GAIM_PLUGIN_PREF_NONE); | |
| 4456 gaim_plugin_pref_set_label(pref, "Save NAB group members locally"); | |
| 4457 gaim_plugin_pref_frame_add(frame, pref); | 5066 gaim_plugin_pref_frame_add(frame, pref); |
| 4458 | 5067 |
| 4459 return frame; | 5068 return frame; |
| 4460 } | 5069 } |
| 4461 | 5070 |
| 4468 static void status_msg_action_cb(GaimConnection *gc, | 5077 static void status_msg_action_cb(GaimConnection *gc, |
| 4469 GaimRequestFields *fields) { | 5078 GaimRequestFields *fields) { |
| 4470 GaimAccount *acct; | 5079 GaimAccount *acct; |
| 4471 GaimRequestField *f; | 5080 GaimRequestField *f; |
| 4472 const char *msg; | 5081 const char *msg; |
| 4473 /* gboolean prompt; */ | |
| 4474 | 5082 |
| 4475 struct mwGaimPluginData *pd; | 5083 struct mwGaimPluginData *pd; |
| 4476 struct mwServiceStorage *srvc; | 5084 struct mwServiceStorage *srvc; |
| 4477 struct mwStorageUnit *unit; | 5085 struct mwStorageUnit *unit; |
| 4478 | 5086 |
| 4496 f = gaim_request_fields_get_field(fields, "busy"); | 5104 f = gaim_request_fields_get_field(fields, "busy"); |
| 4497 msg = gaim_request_field_string_get_value(f); | 5105 msg = gaim_request_field_string_get_value(f); |
| 4498 gaim_account_set_string(acct, MW_KEY_BUSY_MSG, msg); | 5106 gaim_account_set_string(acct, MW_KEY_BUSY_MSG, msg); |
| 4499 unit = mwStorageUnit_newString(mwStore_BUSY_MESSAGES, msg); | 5107 unit = mwStorageUnit_newString(mwStore_BUSY_MESSAGES, msg); |
| 4500 mwServiceStorage_save(srvc, unit, NULL, NULL, NULL); | 5108 mwServiceStorage_save(srvc, unit, NULL, NULL, NULL); |
| 4501 | |
| 4502 #if 0 | |
| 4503 /** @todo not yet used. It should be possible to prompt the user for | |
| 4504 a message (ala the Sametime Connect client) when changing to one | |
| 4505 of the default states, and that preference is here */ | |
| 4506 f = gaim_request_fields_get_field(fields, "prompt"); | |
| 4507 prompt = gaim_request_field_bool_get_value(f); | |
| 4508 gaim_account_set_bool(acct, MW_KEY_MSG_PROMPT, prompt); | |
| 4509 #endif | |
| 4510 | 5109 |
| 4511 #if 0 | 5110 #if 0 |
| 4512 /* XXX */ | 5111 /* XXX */ |
| 4513 /* need to propagate the message change if we're in any of those | 5112 /* need to propagate the message change if we're in any of those |
| 4514 default states */ | 5113 default states */ |
| 4536 GaimRequestFieldGroup *g; | 5135 GaimRequestFieldGroup *g; |
| 4537 GaimRequestField *f; | 5136 GaimRequestField *f; |
| 4538 | 5137 |
| 4539 char *msgA, *msgB; | 5138 char *msgA, *msgB; |
| 4540 const char *val; | 5139 const char *val; |
| 4541 /* gboolean prompt; */ | |
| 4542 | 5140 |
| 4543 gc = act->context; | 5141 gc = act->context; |
| 4544 acct = gaim_connection_get_account(gc); | 5142 acct = gaim_connection_get_account(gc); |
| 4545 | 5143 |
| 4546 fields = gaim_request_fields_new(); | 5144 fields = gaim_request_fields_new(); |
| 4548 g = gaim_request_field_group_new(NULL); | 5146 g = gaim_request_field_group_new(NULL); |
| 4549 gaim_request_fields_add_group(fields, g); | 5147 gaim_request_fields_add_group(fields, g); |
| 4550 | 5148 |
| 4551 val = gaim_account_get_string(acct, MW_KEY_ACTIVE_MSG, | 5149 val = gaim_account_get_string(acct, MW_KEY_ACTIVE_MSG, |
| 4552 MW_PLUGIN_DEFAULT_ACTIVE_MSG); | 5150 MW_PLUGIN_DEFAULT_ACTIVE_MSG); |
| 4553 f = gaim_request_field_string_new("active", "Active Message", val, FALSE); | 5151 f = gaim_request_field_string_new("active", _("Active Message"), val, FALSE); |
| 4554 gaim_request_field_set_required(f, FALSE); | 5152 gaim_request_field_set_required(f, FALSE); |
| 4555 gaim_request_field_group_add_field(g, f); | 5153 gaim_request_field_group_add_field(g, f); |
| 4556 | 5154 |
| 4557 val = gaim_account_get_string(acct, MW_KEY_AWAY_MSG, | 5155 val = gaim_account_get_string(acct, MW_KEY_AWAY_MSG, |
| 4558 MW_PLUGIN_DEFAULT_AWAY_MSG); | 5156 MW_PLUGIN_DEFAULT_AWAY_MSG); |
| 4559 f = gaim_request_field_string_new("away", "Away Message", val, FALSE); | 5157 f = gaim_request_field_string_new("away", _("Away Message"), val, FALSE); |
| 4560 gaim_request_field_set_required(f, FALSE); | 5158 gaim_request_field_set_required(f, FALSE); |
| 4561 gaim_request_field_group_add_field(g, f); | 5159 gaim_request_field_group_add_field(g, f); |
| 4562 | 5160 |
| 4563 val = gaim_account_get_string(acct, MW_KEY_BUSY_MSG, | 5161 val = gaim_account_get_string(acct, MW_KEY_BUSY_MSG, |
| 4564 MW_PLUGIN_DEFAULT_BUSY_MSG); | 5162 MW_PLUGIN_DEFAULT_BUSY_MSG); |
| 4565 f = gaim_request_field_string_new("busy", "Busy Message", val, FALSE); | 5163 f = gaim_request_field_string_new("busy", _("Busy Message"), val, FALSE); |
| 4566 gaim_request_field_set_required(f, FALSE); | 5164 gaim_request_field_set_required(f, FALSE); |
| 4567 gaim_request_field_group_add_field(g, f); | 5165 gaim_request_field_group_add_field(g, f); |
| 4568 | 5166 |
| 4569 #if 0 | 5167 msgA = _("Default status messages"); |
| 4570 /** @todo not yet used. It should be possible to prompt the user for | |
| 4571 a message (ala the Sametime Connect client) when changing to one | |
| 4572 of the default states, and that preference is here */ | |
| 4573 prompt = gaim_account_get_bool(acct, MW_KEY_MSG_PROMPT, FALSE); | |
| 4574 f = gaim_request_field_bool_new("prompt", | |
| 4575 ("Prompt for message when changing" | |
| 4576 " to one of these states?"), FALSE); | |
| 4577 gaim_request_field_group_add_field(g, f); | |
| 4578 #endif | |
| 4579 | |
| 4580 msgA = ("Default status messages"); | |
| 4581 msgB = (""); | 5168 msgB = (""); |
| 4582 | 5169 |
| 4583 gaim_request_fields(gc, "Edit Status Messages", | 5170 gaim_request_fields(gc, _("Edit Status Messages"), |
| 4584 msgA, msgB, fields, | 5171 msgA, msgB, fields, |
| 4585 _("OK"), G_CALLBACK(status_msg_action_cb), | 5172 _("OK"), G_CALLBACK(status_msg_action_cb), |
| 4586 _("Cancel"), NULL, | 5173 _("Cancel"), NULL, |
| 4587 gc); | 5174 gc); |
| 4588 } | 5175 } |
| 4608 fclose(file); | 5195 fclose(file); |
| 4609 | 5196 |
| 4610 l = mwSametimeList_load(str->str); | 5197 l = mwSametimeList_load(str->str); |
| 4611 g_string_free(str, TRUE); | 5198 g_string_free(str, TRUE); |
| 4612 | 5199 |
| 4613 blist_import(gc, l); | 5200 blist_merge(gc, l); |
| 4614 mwSametimeList_free(l); | 5201 mwSametimeList_free(l); |
| 4615 } | 5202 } |
| 4616 | 5203 |
| 4617 | 5204 |
| 4618 /** prompts for a file to import blist from */ | 5205 /** prompts for a file to import blist from */ |
| 4621 GaimAccount *account; | 5208 GaimAccount *account; |
| 4622 char *title; | 5209 char *title; |
| 4623 | 5210 |
| 4624 gc = act->context; | 5211 gc = act->context; |
| 4625 account = gaim_connection_get_account(gc); | 5212 account = gaim_connection_get_account(gc); |
| 4626 title = g_strdup_printf("Import Sametime List for Account %s", | 5213 title = g_strdup_printf(_("Import Sametime List for Account %s"), |
| 4627 gaim_account_get_username(account)); | 5214 gaim_account_get_username(account)); |
| 4628 | 5215 |
| 4629 gaim_request_file(gc, title, NULL, FALSE, | 5216 gaim_request_file(gc, title, NULL, FALSE, |
| 4630 G_CALLBACK(st_import_action_cb), NULL, | 5217 G_CALLBACK(st_import_action_cb), NULL, |
| 4631 gc); | 5218 gc); |
| 4660 GaimAccount *account; | 5247 GaimAccount *account; |
| 4661 char *title; | 5248 char *title; |
| 4662 | 5249 |
| 4663 gc = act->context; | 5250 gc = act->context; |
| 4664 account = gaim_connection_get_account(gc); | 5251 account = gaim_connection_get_account(gc); |
| 4665 title = g_strdup_printf("Export Sametime List for Account %s", | 5252 title = g_strdup_printf(_("Export Sametime List for Account %s"), |
| 4666 gaim_account_get_username(account)); | 5253 gaim_account_get_username(account)); |
| 4667 | 5254 |
| 4668 gaim_request_file(gc, title, NULL, TRUE, | 5255 gaim_request_file(gc, title, NULL, TRUE, |
| 4669 G_CALLBACK(st_export_action_cb), NULL, | 5256 G_CALLBACK(st_export_action_cb), NULL, |
| 4670 gc); | 5257 gc); |
| 4711 /* collision checking */ | 5298 /* collision checking */ |
| 4712 group = gaim_find_group(name); | 5299 group = gaim_find_group(name); |
| 4713 if(group) { | 5300 if(group) { |
| 4714 char *msgA, *msgB; | 5301 char *msgA, *msgB; |
| 4715 | 5302 |
| 4716 msgA = "Unable to add group: group exists"; | 5303 msgA = _("Unable to add group: group exists"); |
| 4717 msgB = "A group named '%s' already exists in your buddy list."; | 5304 msgB = _("A group named '%s' already exists in your buddy list."); |
| 4718 msgB = g_strdup_printf(msgB, name); | 5305 msgB = g_strdup_printf(msgB, name); |
| 4719 | 5306 |
| 4720 gaim_notify_error(gc, "Unable to add group", msgA, msgB); | 5307 gaim_notify_error(gc, _("Unable to add group"), msgA, msgB); |
| 4721 | 5308 |
| 4722 g_free(msgB); | 5309 g_free(msgB); |
| 4723 return; | 5310 return; |
| 4724 } | 5311 } |
| 4725 | 5312 |
| 4772 fields = gaim_request_fields_new(); | 5359 fields = gaim_request_fields_new(); |
| 4773 | 5360 |
| 4774 g = gaim_request_field_group_new(NULL); | 5361 g = gaim_request_field_group_new(NULL); |
| 4775 gaim_request_fields_add_group(fields, g); | 5362 gaim_request_fields_add_group(fields, g); |
| 4776 | 5363 |
| 4777 f = gaim_request_field_list_new("group", "Possible Matches"); | 5364 f = gaim_request_field_list_new("group", _("Possible Matches")); |
| 4778 gaim_request_field_list_set_multi_select(f, FALSE); | 5365 gaim_request_field_list_set_multi_select(f, FALSE); |
| 4779 gaim_request_field_set_required(f, TRUE); | 5366 gaim_request_field_set_required(f, TRUE); |
| 4780 | 5367 |
| 4781 for(l = result->matches; l; l = l->next) { | 5368 for(l = result->matches; l; l = l->next) { |
| 4782 struct mwResolveMatch *match = l->data; | 5369 struct mwResolveMatch *match = l->data; |
| 4788 gaim_request_field_list_add(f, res->name, res); | 5375 gaim_request_field_list_add(f, res->name, res); |
| 4789 } | 5376 } |
| 4790 | 5377 |
| 4791 gaim_request_field_group_add_field(g, f); | 5378 gaim_request_field_group_add_field(g, f); |
| 4792 | 5379 |
| 4793 msgA = ("Notes Address Book group results"); | 5380 msgA = _("Notes Address Book group results"); |
| 4794 msgB = ("The identifier '%s' may possibly refer to any of the following" | 5381 msgB = _("The identifier '%s' may possibly refer to any of the following" |
| 4795 " Notes Address Book groups. Please select the correct group from" | 5382 " Notes Address Book groups. Please select the correct group from" |
| 4796 " the list below to add it to your buddy list."); | 5383 " the list below to add it to your buddy list."); |
| 4797 msgB = g_strdup_printf(msgB, result->name); | 5384 msgB = g_strdup_printf(msgB, result->name); |
| 4798 | 5385 |
| 4799 gaim_request_fields(gc, "Select Notes Address Book", | 5386 gaim_request_fields(gc, _("Select Notes Address Book"), |
| 4800 msgA, msgB, fields, | 5387 msgA, msgB, fields, |
| 4801 "Add Group", G_CALLBACK(remote_group_multi_cb), | 5388 _("Add Group"), G_CALLBACK(remote_group_multi_cb), |
| 4802 "Cancel", G_CALLBACK(remote_group_multi_cleanup), | 5389 _("Cancel"), G_CALLBACK(remote_group_multi_cleanup), |
| 4803 pd); | 5390 pd); |
| 4804 | 5391 |
| 4805 g_free(msgB); | 5392 g_free(msgB); |
| 4806 } | 5393 } |
| 4807 | 5394 |
| 4834 } | 5421 } |
| 4835 | 5422 |
| 4836 if(res && res->name) { | 5423 if(res && res->name) { |
| 4837 char *msgA, *msgB; | 5424 char *msgA, *msgB; |
| 4838 | 5425 |
| 4839 msgA = "Unable to add group: group not found"; | 5426 msgA = _("Unable to add group: group not found"); |
| 4840 | 5427 |
| 4841 msgB = ("The identifier '%s' did not match any Notes Address Book" | 5428 msgB = _("The identifier '%s' did not match any Notes Address Book" |
| 4842 " groups in your Sametime community."); | 5429 " groups in your Sametime community."); |
| 4843 msgB = g_strdup_printf(msgB, res->name); | 5430 msgB = g_strdup_printf(msgB, res->name); |
| 4844 | 5431 |
| 4845 gaim_notify_error(gc, "Unable to add group", msgA, msgB); | 5432 gaim_notify_error(gc, _("Unable to add group"), msgA, msgB); |
| 4846 | 5433 |
| 4847 g_free(msgB); | 5434 g_free(msgB); |
| 4848 } | 5435 } |
| 4849 } | 5436 } |
| 4850 | 5437 |
| 4876 GaimConnection *gc; | 5463 GaimConnection *gc; |
| 4877 const char *msgA, *msgB; | 5464 const char *msgA, *msgB; |
| 4878 | 5465 |
| 4879 gc = act->context; | 5466 gc = act->context; |
| 4880 | 5467 |
| 4881 msgA = "Notes Address Book Group"; | 5468 msgA = _("Notes Address Book Group"); |
| 4882 msgB = ("Enter the name of a Notes Address Book group in the field below" | 5469 msgB = _("Enter the name of a Notes Address Book group in the field below" |
| 4883 " to add the group and its members to your buddy list."); | 5470 " to add the group and its members to your buddy list."); |
| 4884 | 5471 |
| 4885 gaim_request_input(gc, "Add Group", msgA, msgB, NULL, | 5472 gaim_request_input(gc, _("Add Group"), msgA, msgB, NULL, |
| 4886 FALSE, FALSE, NULL, | 5473 FALSE, FALSE, NULL, |
| 4887 "Add", G_CALLBACK(remote_group_action_cb), | 5474 _("Add"), G_CALLBACK(remote_group_action_cb), |
| 4888 "Cancel", NULL, | 5475 _("Cancel"), NULL, |
| 4889 gc); | 5476 gc); |
| 4890 } | 5477 } |
| 4891 | 5478 |
| 4892 | 5479 |
| 4893 static GList *mw_plugin_actions(GaimPlugin *plugin, gpointer context) { | 5480 static GList *mw_plugin_actions(GaimPlugin *plugin, gpointer context) { |
| 4894 GaimPluginAction *act; | 5481 GaimPluginAction *act; |
| 4895 GList *l = NULL; | 5482 GList *l = NULL; |
| 4896 | 5483 |
| 4897 act = gaim_plugin_action_new("Set Status Messages...", status_msg_action); | 5484 act = gaim_plugin_action_new(_("Set Status Messages..."), |
| 5485 status_msg_action); | |
| 4898 l = g_list_append(l, act); | 5486 l = g_list_append(l, act); |
| 4899 | 5487 |
| 4900 act = gaim_plugin_action_new("Import Sametime List...", st_import_action); | 5488 act = gaim_plugin_action_new(_("Import Sametime List..."), |
| 5489 st_import_action); | |
| 4901 l = g_list_append(l, act); | 5490 l = g_list_append(l, act); |
| 4902 | 5491 |
| 4903 act = gaim_plugin_action_new("Export Sametime List...", st_export_action); | 5492 act = gaim_plugin_action_new(_("Export Sametime List..."), |
| 5493 st_export_action); | |
| 4904 l = g_list_append(l, act); | 5494 l = g_list_append(l, act); |
| 4905 | 5495 |
| 4906 act = gaim_plugin_action_new("Add Notes Address Book Group...", | 5496 act = gaim_plugin_action_new(_("Add Notes Address Book Group..."), |
| 4907 remote_group_action); | 5497 remote_group_action); |
| 4908 l = g_list_append(l, act); | 5498 l = g_list_append(l, act); |
| 4909 | 5499 |
| 4910 return l; | 5500 return l; |
| 4911 } | 5501 } |
| 4982 GList *l = NULL; | 5572 GList *l = NULL; |
| 4983 | 5573 |
| 4984 GLogLevelFlags logflags = | 5574 GLogLevelFlags logflags = |
| 4985 G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION; | 5575 G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION; |
| 4986 | 5576 |
| 5577 /* set up the preferences */ | |
| 5578 gaim_prefs_add_none(MW_PRPL_OPT_BASE); | |
| 5579 gaim_prefs_add_int(MW_PRPL_OPT_BLIST_ACTION, BLIST_CHOICE_DEFAULT); | |
| 5580 | |
| 5581 /* remove dead preferences */ | |
| 5582 gaim_prefs_remove(MW_PRPL_OPT_PSYCHIC); | |
| 5583 gaim_prefs_remove(MW_PRPL_OPT_SAVE_DYNAMIC); | |
| 5584 | |
| 4987 /* host to connect to */ | 5585 /* host to connect to */ |
| 4988 opt = gaim_account_option_string_new("Server", MW_KEY_HOST, | 5586 opt = gaim_account_option_string_new(_("Server"), MW_KEY_HOST, |
| 4989 MW_PLUGIN_DEFAULT_HOST); | 5587 MW_PLUGIN_DEFAULT_HOST); |
| 4990 l = g_list_append(l, opt); | 5588 l = g_list_append(l, opt); |
| 4991 | 5589 |
| 4992 /* port to connect to */ | 5590 /* port to connect to */ |
| 4993 opt = gaim_account_option_int_new("Port", MW_KEY_PORT, | 5591 opt = gaim_account_option_int_new(_("Port"), MW_KEY_PORT, |
| 4994 MW_PLUGIN_DEFAULT_PORT); | 5592 MW_PLUGIN_DEFAULT_PORT); |
| 4995 l = g_list_append(l, opt); | 5593 l = g_list_append(l, opt); |
| 4996 | 5594 |
| 5595 /* default attempted encoding */ | |
| 5596 opt = gaim_account_option_string_new(_("Encoding"), MW_KEY_ENCODING, | |
| 5597 MW_PLUGIN_DEFAULT_ENCODING); | |
| 5598 l = g_list_append(l, opt); | |
| 5599 | |
| 5600 { /* copy the old force login setting from prefs if it's | |
| 5601 there. Don't delete the preference, since there may be more | |
| 5602 than one account that wants to check for it. */ | |
| 5603 gboolean b = FALSE; | |
| 5604 const char *label = _("Force Login (Ignore Server Redirects)"); | |
| 5605 | |
| 5606 if(gaim_prefs_exists(MW_PRPL_OPT_FORCE_LOGIN)) | |
| 5607 b = gaim_prefs_get_bool(MW_PRPL_OPT_FORCE_LOGIN); | |
| 5608 | |
| 5609 opt = gaim_account_option_bool_new(label, MW_KEY_FORCE, b); | |
| 5610 l = g_list_append(l, opt); | |
| 5611 } | |
| 5612 | |
| 4997 mw_prpl_info.protocol_options = l; | 5613 mw_prpl_info.protocol_options = l; |
| 4998 l = NULL; | 5614 l = NULL; |
| 4999 | |
| 5000 /* set up the prefs for blist options */ | |
| 5001 gaim_prefs_add_none(MW_PRPL_OPT_BASE); | |
| 5002 gaim_prefs_add_int(MW_PRPL_OPT_BLIST_ACTION, BLIST_CHOICE_DEFAULT); | |
| 5003 gaim_prefs_add_bool(MW_PRPL_OPT_PSYCHIC, FALSE); | |
| 5004 gaim_prefs_add_bool(MW_PRPL_OPT_FORCE_LOGIN, FALSE); | |
| 5005 gaim_prefs_add_bool(MW_PRPL_OPT_SAVE_DYNAMIC, TRUE); | |
| 5006 | 5615 |
| 5007 /* forward all our g_log messages to gaim. Generally all the logging | 5616 /* forward all our g_log messages to gaim. Generally all the logging |
| 5008 calls are using gaim_log directly, but the g_return macros will | 5617 calls are using gaim_log directly, but the g_return macros will |
| 5009 get caught here */ | 5618 get caught here */ |
| 5010 log_handler[0] = g_log_set_handler(G_LOG_DOMAIN, logflags, | 5619 log_handler[0] = g_log_set_handler(G_LOG_DOMAIN, logflags, |
