# HG changeset patch # User John Bailey # Date 1300057892 0 # Node ID 7cbd01b1ed31c4029ba09ed9eee430506d1a105e # Parent ad7380e10f2a8de4d1e42e986a3271560bed0995# Parent 2b1b52d66a24150e03e8d11e815b958ed69f0153 propagate from branch 'im.pidgin.pidgin.next.minor' (head 00d82ac80e3aef1bae2cc576f8f909c224c576b4) to branch 'im.pidgin.pidgin' (head f3f071b7cd1383e2303f4b2e04cf11d110da3a78) diff -r 2b1b52d66a24 -r 7cbd01b1ed31 ChangeLog --- a/ChangeLog Sun Mar 13 23:10:44 2011 +0000 +++ b/ChangeLog Sun Mar 13 23:11:32 2011 +0000 @@ -1,5 +1,16 @@ Pidgin and Finch: The Pimpin' Penguin IM Clients That're Good for the Soul +version 2.8.0 (??/??/????): + libpurple: + * media: Allow obtaining active local and remote candidates. (#11830) + * media: Allow getting/setting video capabilities. (Jakub Adam) (half of + #13095) + * Simple Silence Suppression is optional per-account. (Jakub Adam) (half + of #13180) + + Pidgin: + * Duplicate code cleanup. (Gabriel Schulhof) (#10599) + version 2.7.12 (??/??/????): General: * Implement simple silence suppression for voice calls, preventing wasted diff -r 2b1b52d66a24 -r 7cbd01b1ed31 ChangeLog.API --- a/ChangeLog.API Sun Mar 13 23:10:44 2011 +0000 +++ b/ChangeLog.API Sun Mar 13 23:11:32 2011 +0000 @@ -1,5 +1,20 @@ Pidgin and Finch: The Pimpin' Penguin IM Clients That're Good for the Soul +version 2.8.0 (??/??/????): + libpurple: + Added: + * account-authorization-requested-with-message signal (Stefan Ott) + (#8690) + * purple_notify_user_info_add_pair_plaintext + * purple_media_get_active_local_candidates + * purple_media_get_active_remote_candidates + * purple_media_manager_get_video_caps (Jakub Adam) (#13095) + * purple_media_manager_set_video_caps (Jakub Adam) (#13095) + + Pidgin: + Added: + * pidgin_make_scrollable (Gabriel Schulhof) (#10599) + version 2.7.12 (??/??/????): version 2.7.11 (03/10/2011): diff -r 2b1b52d66a24 -r 7cbd01b1ed31 configure.ac --- a/configure.ac Sun Mar 13 23:10:44 2011 +0000 +++ b/configure.ac Sun Mar 13 23:11:32 2011 +0000 @@ -43,10 +43,10 @@ # # Make sure to update finch/libgnt/configure.ac with libgnt version changes. # -m4_define([purple_lt_current], [7]) +m4_define([purple_lt_current], [8]) m4_define([purple_major_version], [2]) -m4_define([purple_minor_version], [7]) -m4_define([purple_micro_version], [12]) +m4_define([purple_minor_version], [8]) +m4_define([purple_micro_version], [0]) m4_define([purple_version_suffix], [devel]) m4_define([purple_version], [purple_major_version.purple_minor_version.purple_micro_version]) diff -r 2b1b52d66a24 -r 7cbd01b1ed31 doc/account-signals.dox --- a/doc/account-signals.dox Sun Mar 13 23:10:44 2011 +0000 +++ b/doc/account-signals.dox Sun Mar 13 23:11:32 2011 +0000 @@ -14,6 +14,7 @@ @signal account-actions-changed @signal account-alias-changed @signal account-authorization-requested + @signal account-authorization-requested-with-message @signal account-authorization-denied @signal account-authorization-granted @signal account-error-changed @@ -158,6 +159,23 @@ @since 2.3.0 @endsignaldef + @signaldef account-authorization-requested-with-message + @signalproto +int (*account_authorization_requested)(PurpleAccount *account, const char *user, const char *message); + @endsignalproto + @signaldesc + Emitted when a user requests authorization. + @param account The account. + @param user The name of the user requesting authorization. + @param message The authorization request message + @return PURPLE_ACCOUNT_RESPONSE_IGNORE to silently ignore the request, + PURPLE_ACCOUNT_RESPONSE_DENY to block the request (the sender might + get informed, PURPLE_ACCOUNT_RESPONSE_ACCEPT if the request should be + granted. If PURPLE_ACCOUNT_RESPONSE_PASS is returned, then the user + will be prompted with the request. + @since 2.8.0 + @endsignaldef + @signaldef account-authorization-denied @signalproto void (*account_authorization_denied)(PurpleAccount *account, const char *user); diff -r 2b1b52d66a24 -r 7cbd01b1ed31 libpurple/account.c --- a/libpurple/account.c Sun Mar 13 23:10:44 2011 +0000 +++ b/libpurple/account.c Sun Mar 13 23:11:32 2011 +0000 @@ -1441,6 +1441,27 @@ return NULL; } + plugin_return = GPOINTER_TO_INT( + purple_signal_emit_return_1( + purple_accounts_get_handle(), + "account-authorization-requested-with-message", + account, remote_user, message + )); + + switch (plugin_return) + { + case PURPLE_ACCOUNT_RESPONSE_IGNORE: + return NULL; + case PURPLE_ACCOUNT_RESPONSE_ACCEPT: + if (auth_cb != NULL) + auth_cb(user_data); + return NULL; + case PURPLE_ACCOUNT_RESPONSE_DENY: + if (deny_cb != NULL) + deny_cb(user_data); + return NULL; + } + if (ui_ops != NULL && ui_ops->request_authorize != NULL) { info = g_new0(PurpleAccountRequestInfo, 1); info->type = PURPLE_ACCOUNT_REQUEST_AUTHORIZATION; @@ -1915,6 +1936,20 @@ } } +gboolean +purple_account_get_silence_suppression(const PurpleAccount *account) +{ + return purple_account_get_bool(account, "silence-suppression", FALSE); +} + +void +purple_account_set_silence_suppression(PurpleAccount *account, gboolean value) +{ + g_return_if_fail(account != NULL); + + purple_account_set_bool(account, "silence-suppression", value); +} + void purple_account_clear_settings(PurpleAccount *account) { @@ -3046,6 +3081,13 @@ PURPLE_SUBTYPE_ACCOUNT), purple_value_new(PURPLE_TYPE_STRING)); + purple_signal_register(handle, "account-authorization-requested-with-message", + purple_marshal_INT__POINTER_POINTER_POINTER, + purple_value_new(PURPLE_TYPE_INT), 3, + purple_value_new(PURPLE_TYPE_SUBTYPE, + PURPLE_SUBTYPE_ACCOUNT), + purple_value_new(PURPLE_TYPE_STRING), + purple_value_new(PURPLE_TYPE_STRING)); purple_signal_register(handle, "account-authorization-denied", purple_marshal_VOID__POINTER_POINTER, NULL, 2, purple_value_new(PURPLE_TYPE_SUBTYPE, diff -r 2b1b52d66a24 -r 7cbd01b1ed31 libpurple/account.h --- a/libpurple/account.h Sun Mar 13 23:10:44 2011 +0000 +++ b/libpurple/account.h Sun Mar 13 23:11:32 2011 +0000 @@ -59,6 +59,16 @@ PURPLE_ACCOUNT_REQUEST_AUTHORIZATION = 0 /* Account authorization request */ } PurpleAccountRequestType; +/** + * Account request response types + */ +typedef enum +{ + PURPLE_ACCOUNT_RESPONSE_IGNORE = -2, + PURPLE_ACCOUNT_RESPONSE_DENY = -1, + PURPLE_ACCOUNT_RESPONSE_PASS = 0, + PURPLE_ACCOUNT_RESPONSE_ACCEPT = 1 +} PurpleAccountRequestResponse; /** Account UI operations, used to notify the user of status changes and when * buddies add this account to their buddy lists. @@ -503,6 +513,24 @@ PurpleGetPublicAliasFailureCallback failure_cb); /** + * Return whether silence suppression is used during voice call. + * + * @param account The account. + * + * @return @c TRUE if suppression is used, or @c FALSE if not. + */ +gboolean purple_account_get_silence_suppression(const PurpleAccount *account); + +/** + * Sets whether silence suppression is used during voice call. + * + * @param account The account. + * @param value @c TRUE if suppression should be used. + */ +void purple_account_set_silence_suppression(PurpleAccount *account, + gboolean value); + +/** * Clears all protocol-specific settings on an account. * * @param account The account. diff -r 2b1b52d66a24 -r 7cbd01b1ed31 libpurple/conversation.c --- a/libpurple/conversation.c Sun Mar 13 23:10:44 2011 +0000 +++ b/libpurple/conversation.c Sun Mar 13 23:11:32 2011 +0000 @@ -2135,6 +2135,8 @@ cb->name = g_strdup(name); cb->flags = flags; cb->alias = g_strdup(alias); + cb->attributes = g_hash_table_new_full(g_str_hash, g_str_equal, + g_free, g_free); PURPLE_DBUS_REGISTER_POINTER(cb, PurpleConvChatBuddy); return cb; @@ -2167,6 +2169,7 @@ g_free(cb->alias); g_free(cb->alias_key); g_free(cb->name); + g_hash_table_destroy(cb->attributes); PURPLE_DBUS_UNREGISTER_POINTER(cb); g_free(cb); @@ -2180,6 +2183,76 @@ return cb->name; } +const char * +purple_conv_chat_cb_get_attribute(PurpleConvChatBuddy *cb, const char *key) +{ + g_return_val_if_fail(cb != NULL, NULL); + g_return_val_if_fail(key != NULL, NULL); + + return g_hash_table_lookup(cb->attributes, key); +} + +static void +append_attribute_key(gpointer key, gpointer value, gpointer user_data) +{ + GList **list = user_data; + *list = g_list_prepend(*list, key); +} + +GList * +purple_conv_chat_cb_get_attribute_keys(PurpleConvChatBuddy *cb) +{ + GList *keys = NULL; + + g_return_val_if_fail(cb != NULL, NULL); + + g_hash_table_foreach(cb->attributes, (GHFunc)append_attribute_key, &keys); + + return keys; +} + +void +purple_conv_chat_cb_set_attribute(PurpleConvChat *chat, PurpleConvChatBuddy *cb, const char *key, const char *value) +{ + PurpleConversation *conv; + PurpleConversationUiOps *ops; + + g_return_if_fail(cb != NULL); + g_return_if_fail(key != NULL); + g_return_if_fail(value != NULL); + + g_hash_table_replace(cb->attributes, g_strdup(key), g_strdup(value)); + + conv = purple_conv_chat_get_conversation(chat); + ops = purple_conversation_get_ui_ops(conv); + + if (ops != NULL && ops->chat_update_user != NULL) + ops->chat_update_user(conv, cb->name); +} + +void +purple_conv_chat_cb_set_attributes(PurpleConvChat *chat, PurpleConvChatBuddy *cb, GList *keys, GList *values) +{ + PurpleConversation *conv; + PurpleConversationUiOps *ops; + + g_return_if_fail(cb != NULL); + g_return_if_fail(keys != NULL); + g_return_if_fail(values != NULL); + + while (keys != NULL && values != NULL) { + g_hash_table_replace(cb->attributes, g_strdup(keys->data), g_strdup(values->data)); + keys = g_list_next(keys); + values = g_list_next(values); + } + + conv = purple_conv_chat_get_conversation(chat); + ops = purple_conversation_get_ui_ops(conv); + + if (ops != NULL && ops->chat_update_user != NULL) + ops->chat_update_user(conv, cb->name); +} + GList * purple_conversation_get_extended_menu(PurpleConversation *conv) { diff -r 2b1b52d66a24 -r 7cbd01b1ed31 libpurple/conversation.h --- a/libpurple/conversation.h Sun Mar 13 23:10:44 2011 +0000 +++ b/libpurple/conversation.h Sun Mar 13 23:11:32 2011 +0000 @@ -139,7 +139,8 @@ PURPLE_CBFLAGS_HALFOP = 0x0002, /**< Half-op */ PURPLE_CBFLAGS_OP = 0x0004, /**< Channel Op or Moderator */ PURPLE_CBFLAGS_FOUNDER = 0x0008, /**< Channel Founder */ - PURPLE_CBFLAGS_TYPING = 0x0010 /**< Currently typing */ + PURPLE_CBFLAGS_TYPING = 0x0010, /**< Currently typing */ + PURPLE_CBFLAGS_AWAY = 0x0020 /**< Currently away. @since 2.8.0 */ } PurpleConvChatBuddyFlags; @@ -300,6 +301,9 @@ PurpleConvChatBuddyFlags flags; /**< A bitwise OR of flags for this participant, * such as whether they are a channel operator. */ + GHashTable *attributes; /**< A hash table of attributes about the user, such as + * real name, user@host, etc. + */ }; /** @@ -513,6 +517,46 @@ const char *purple_conversation_get_name(const PurpleConversation *conv); /** + * Get an attribute of a chat buddy + * + * @param cb The chat buddy. + * @param key The key of the attribute. + * + * @return The value of the attribute key. + */ +const char *purple_conv_chat_cb_get_attribute(PurpleConvChatBuddy *cb, const char *key); + +/** + * Get the keys of all atributes of a chat buddy + * + * @param cb The chat buddy. + * + * @return A list of the attributes of a chat buddy. + */ +GList *purple_conv_chat_cb_get_attribute_keys(PurpleConvChatBuddy *cb); + +/** + * Set an attribute of a chat buddy + * + * @param chat The chat. + * @param cb The chat buddy. + * @param key The key of the attribute. + * @param value The value of the attribute. + */ +void purple_conv_chat_cb_set_attribute(PurpleConvChat *chat, PurpleConvChatBuddy *cb, const char *key, const char *value); + +/** + * Set attributes of a chat buddy + * + * @param chat The chat. + * @param cb The chat buddy. + * @param keys A GList of the keys. + * @param values A GList of the values. + */ +void +purple_conv_chat_cb_set_attributes(PurpleConvChat *chat, PurpleConvChatBuddy *cb, GList *keys, GList *values); + +/** * Enables or disables logging for this conversation. * * @param conv The conversation. diff -r 2b1b52d66a24 -r 7cbd01b1ed31 libpurple/media-gst.h --- a/libpurple/media-gst.h Sun Mar 13 23:10:44 2011 +0000 +++ b/libpurple/media-gst.h Sun Mar 13 23:11:32 2011 +0000 @@ -159,6 +159,31 @@ PurpleMediaElementInfo *purple_media_manager_get_active_element( PurpleMediaManager *manager, PurpleMediaElementType type); +/** + * Reduces media formats supported by the video source to given set. + * + * Useful to force negotiation of smaller picture resolution more suitable for + * use with particular codec and communication protocol without rescaling. + * + * @param manager The media manager to set the media formats. + * @param caps Set of allowed media formats. + * + * @since 2.8.0 + */ +void purple_media_manager_set_video_caps(PurpleMediaManager *manager, + GstCaps *caps); + +/** + * Returns current set of media formats limiting the output from video source. + * + * @param manager The media manager to get the media formats from. + * + * @return @c GstCaps limiting the video source's formats. + * + * @since 2.8.0 + */ +GstCaps *purple_media_manager_get_video_caps(PurpleMediaManager *manager); + gchar *purple_media_element_info_get_id(PurpleMediaElementInfo *info); gchar *purple_media_element_info_get_name(PurpleMediaElementInfo *info); PurpleMediaElementType purple_media_element_info_get_element_type( diff -r 2b1b52d66a24 -r 7cbd01b1ed31 libpurple/media.c --- a/libpurple/media.c Sun Mar 13 23:10:44 2011 +0000 +++ b/libpurple/media.c Sun Mar 13 23:11:32 2011 +0000 @@ -1151,12 +1151,6 @@ #endif } -#if 0 -/* - * These two functions aren't being used and I'd rather not lock in the API - * until they are needed. If they ever are. - */ - GList * purple_media_get_active_local_candidates(PurpleMedia *media, const gchar *sess_id, const gchar *participant) @@ -1186,7 +1180,6 @@ return NULL; #endif } -#endif gboolean purple_media_set_remote_codecs(PurpleMedia *media, const gchar *sess_id, diff -r 2b1b52d66a24 -r 7cbd01b1ed31 libpurple/media.h --- a/libpurple/media.h Sun Mar 13 23:10:44 2011 +0000 +++ b/libpurple/media.h Sun Mar 13 23:11:32 2011 +0000 @@ -230,12 +230,6 @@ const gchar *sess_id, const gchar *participant); -#if 0 -/* - * These two functions aren't being used and I'd rather not lock in the API - * until they are needed. If they ever are. - */ - /** * Gets the active local candidates for the stream. * @@ -245,6 +239,8 @@ * from. * * @return The active candidates retrieved. + * + * @since 2.8.0 */ GList *purple_media_get_active_local_candidates(PurpleMedia *media, const gchar *sess_id, const gchar *participant); @@ -258,10 +254,11 @@ * from. * * @return The remote candidates retrieved. + * + * @since 2.8.0 */ GList *purple_media_get_active_remote_candidates(PurpleMedia *media, const gchar *sess_id, const gchar *participant); -#endif /** * Sets remote candidates from the stream. diff -r 2b1b52d66a24 -r 7cbd01b1ed31 libpurple/media/backend-fs2.c --- a/libpurple/media/backend-fs2.c Sun Mar 13 23:10:44 2011 +0000 +++ b/libpurple/media/backend-fs2.c Sun Mar 13 23:11:32 2011 +0000 @@ -155,13 +155,7 @@ static void purple_media_backend_fs2_init(PurpleMediaBackendFs2 *self) -{ - PurpleMediaBackendFs2Private *priv = - PURPLE_MEDIA_BACKEND_FS2_GET_PRIVATE(self); - - priv->silence_threshold = purple_prefs_get_int( - "/purple/media/audio/silence_threshold") / 100.0; -} +{} static gboolean event_probe_cb(GstPad *srcpad, GstEvent *event, gboolean release_pad) @@ -817,9 +811,11 @@ if (!strncmp(name, "sendlevel_", 10)) { session = get_session(self, name+10); - percent = gst_msg_db_to_percent(msg, "decay"); - g_object_set(session->srcvalve, - "drop", (percent < priv->silence_threshold), NULL); + if (priv->silence_threshold > 0) { + percent = gst_msg_db_to_percent(msg, "decay"); + g_object_set(session->srcvalve, + "drop", (percent < priv->silence_threshold), NULL); + } } g_free(name); @@ -1255,6 +1251,13 @@ return FALSE; } + if (purple_account_get_silence_suppression( + purple_media_get_account(priv->media))) + priv->silence_threshold = purple_prefs_get_int( + "/purple/media/audio/silence_threshold") / 100.0; + else + priv->silence_threshold = 0; + pipeline = purple_media_manager_get_pipeline( purple_media_get_manager(priv->media)); diff -r 2b1b52d66a24 -r 7cbd01b1ed31 libpurple/mediamanager.c --- a/libpurple/mediamanager.c Sun Mar 13 23:10:44 2011 +0000 +++ b/libpurple/mediamanager.c Sun Mar 13 23:11:32 2011 +0000 @@ -420,7 +420,30 @@ #ifdef USE_GSTREAMER -static GstCaps * +void +purple_media_manager_set_video_caps(PurpleMediaManager *manager, GstCaps *caps) +{ +#ifdef USE_VV + if (manager->priv->video_caps) + gst_caps_unref(manager->priv->video_caps); + + manager->priv->video_caps = caps; + + if (manager->priv->pipeline && manager->priv->video_src) { + gchar *id = purple_media_element_info_get_id(manager->priv->video_src); + GstElement *src = gst_bin_get_by_name(GST_BIN(manager->priv->pipeline), id); + + if (src) { + GstElement *capsfilter = gst_bin_get_by_name(GST_BIN(src), "prpl_video_caps"); + g_object_set(G_OBJECT(capsfilter), "caps", caps, NULL); + } + + g_free(id); + } +#endif +} + +GstCaps * purple_media_manager_get_video_caps(PurpleMediaManager *manager) { #ifdef USE_VV diff -r 2b1b52d66a24 -r 7cbd01b1ed31 libpurple/notify.c --- a/libpurple/notify.c Sun Mar 13 23:10:44 2011 +0000 +++ b/libpurple/notify.c Sun Mar 13 23:11:32 2011 +0000 @@ -602,6 +602,18 @@ } void +purple_notify_user_info_add_pair_plaintext(PurpleNotifyUserInfo *user_info, const char *label, const char *value) +{ + gchar *escaped; + PurpleNotifyUserInfoEntry *entry; + + escaped = g_markup_escape_text(value, -1); + entry = purple_notify_user_info_entry_new(label, escaped); + g_free(escaped); + user_info->user_info_entries = g_list_append(user_info->user_info_entries, entry); +} + +void purple_notify_user_info_prepend_pair(PurpleNotifyUserInfo *user_info, const char *label, const char *value) { PurpleNotifyUserInfoEntry *entry; diff -r 2b1b52d66a24 -r 7cbd01b1ed31 libpurple/notify.h --- a/libpurple/notify.h Sun Mar 13 23:10:44 2011 +0000 +++ b/libpurple/notify.h Sun Mar 13 23:11:32 2011 +0000 @@ -540,13 +540,28 @@ * a colon. If NULL, value will be displayed without a * label. * @param value The value, which might be displayed by a UI after - * the label. If NULL, label will still be displayed; - * the UI should then treat label as independent and not + * the label. This should be valid HTML. If you want + * to insert plaintext then use + * purple_notify_user_info_add_pair_plaintext(), instead. + * If this is NULL the label will still be displayed; + * the UI should treat label as independent and not * include a colon if it would otherwise. */ +/* + * TODO: In 3.0.0 this function should be renamed to + * purple_notify_user_info_add_pair_html(). And optionally + * purple_notify_user_info_add_pair_plaintext() could be renamed to + * purple_notify_user_info_add_pair(). + */ void purple_notify_user_info_add_pair(PurpleNotifyUserInfo *user_info, const char *label, const char *value); /** + * Like purple_notify_user_info_add_pair, but value should be plaintext + * and will be escaped using g_markup_escape_text(). + */ +void purple_notify_user_info_add_pair_plaintext(PurpleNotifyUserInfo *user_info, const char *label, const char *value); + +/** * Prepend a label/value pair to a PurpleNotifyUserInfo object * * @param user_info The PurpleNotifyUserInfo diff -r 2b1b52d66a24 -r 7cbd01b1ed31 libpurple/protocols/irc/irc.c --- a/libpurple/protocols/irc/irc.c Sun Mar 13 23:10:44 2011 +0000 +++ b/libpurple/protocols/irc/irc.c Sun Mar 13 23:11:32 2011 +0000 @@ -41,6 +41,8 @@ static void irc_ison_buddy_init(char *name, struct irc_buddy *ib, GList **list); +static void irc_who_channel(PurpleConversation *conv, struct irc_conn *irc); + static const char *irc_blist_icon(PurpleAccount *a, PurpleBuddy *b); static GList *irc_status_types(PurpleAccount *account); static GList *irc_actions(PurplePlugin *plugin, gpointer context); @@ -232,6 +234,26 @@ *list = g_list_append(*list, ib); } + +gboolean irc_who_channel_timeout(struct irc_conn *irc) +{ + // WHO all of our channels. + g_list_foreach(purple_get_conversations(), (GFunc)irc_who_channel, (gpointer)irc); + + return TRUE; +} + +static void irc_who_channel(PurpleConversation *conv, struct irc_conn *irc) +{ + if (purple_conversation_get_account(conv) == irc->account && purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) { + char *buf = irc_format(irc, "vc", "WHO", purple_conversation_get_name(conv)); + + purple_debug(PURPLE_DEBUG_INFO, "irc", "Performing periodic who on %s", purple_conversation_get_name(conv)); + irc_send(irc, buf); + g_free(buf); + } +} + static void irc_ison_one(struct irc_conn *irc, struct irc_buddy *ib) { char *buf; @@ -517,6 +539,8 @@ } if (irc->timer) purple_timeout_remove(irc->timer); + if (irc->who_channel_timer) + purple_timeout_remove(irc->who_channel_timer); g_hash_table_destroy(irc->cmds); g_hash_table_destroy(irc->msgs); g_hash_table_destroy(irc->buddies); diff -r 2b1b52d66a24 -r 7cbd01b1ed31 libpurple/protocols/irc/irc.h --- a/libpurple/protocols/irc/irc.h Sun Mar 13 23:10:44 2011 +0000 +++ b/libpurple/protocols/irc/irc.h Sun Mar 13 23:11:32 2011 +0000 @@ -55,6 +55,7 @@ char *server; int fd; guint timer; + guint who_channel_timer; GHashTable *buddies; gboolean ison_outstanding; @@ -106,6 +107,7 @@ int irc_send(struct irc_conn *irc, const char *buf); gboolean irc_blist_timeout(struct irc_conn *irc); +gboolean irc_who_channel_timeout(struct irc_conn *irc); void irc_buddy_query(struct irc_conn *irc); char *irc_escape_privmsg(const char *text, gssize length); @@ -164,6 +166,7 @@ void irc_msg_unknown(struct irc_conn *irc, const char *name, const char *from, char **args); void irc_msg_wallops(struct irc_conn *irc, const char *name, const char *from, char **args); void irc_msg_whois(struct irc_conn *irc, const char *name, const char *from, char **args); +void irc_msg_who(struct irc_conn *irc, const char *name, const char *from, char **args); void irc_msg_ignore(struct irc_conn *irc, const char *name, const char *from, char **args); diff -r 2b1b52d66a24 -r 7cbd01b1ed31 libpurple/protocols/irc/msgs.c --- a/libpurple/protocols/irc/msgs.c Sun Mar 13 23:10:44 2011 +0000 +++ b/libpurple/protocols/irc/msgs.c Sun Mar 13 23:11:32 2011 +0000 @@ -110,6 +110,8 @@ irc_blist_timeout(irc); if (!irc->timer) irc->timer = purple_timeout_add_seconds(45, (GSourceFunc)irc_blist_timeout, (gpointer)irc); + if (!irc->who_channel_timer) + irc->who_channel_timer = purple_timeout_add_seconds(300, (GSourceFunc)irc_who_channel_timeout, (gpointer)irc); } void irc_msg_default(struct irc_conn *irc, const char *name, const char *from, char **args) @@ -400,6 +402,59 @@ memset(&irc->whois, 0, sizeof(irc->whois)); } +void irc_msg_who(struct irc_conn *irc, const char *name, const char *from, char **args) +{ + if (!strcmp(name, "352")) { + PurpleConversation *conv; + PurpleConvChat *chat; + PurpleConvChatBuddy *cb; + + char *userhost, *realname; + + PurpleConvChatBuddyFlags flags; + GList *keys = NULL, *values = NULL; + + conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, args[1], irc->account); + if (!conv) { + purple_debug(PURPLE_DEBUG_ERROR, "irc", "Got a WHO response for %s, which doesn't exist\n", args[1]); + return; + } + + cb = purple_conv_chat_cb_find(PURPLE_CONV_CHAT(conv), args[5]); + if (!cb) { + purple_debug(PURPLE_DEBUG_ERROR, "irc", "Got a WHO response for %s who isn't a buddy.\n", args[5]); + return; + } + + chat = PURPLE_CONV_CHAT(conv); + + userhost = g_strdup_printf("%s@%s", args[2], args[3]); + realname = g_strdup(args[8]); + + keys = g_list_prepend(keys, "userhost"); + values = g_list_prepend(values, userhost); + + keys = g_list_prepend(keys, "realname"); + values = g_list_prepend(values, realname); + + purple_conv_chat_cb_set_attributes(chat, cb, keys, values); + + g_list_free(keys); + g_list_free(values); + + g_free(userhost); + g_free(realname); + + flags = purple_conv_chat_user_get_flags(chat, cb->name); + + if (args[6][0] == 'G' && !(flags & PURPLE_CBFLAGS_AWAY)) { + purple_conv_chat_user_set_flags(chat, cb->name, flags | PURPLE_CBFLAGS_AWAY); + } else if(args[6][0] == 'H' && (flags & PURPLE_CBFLAGS_AWAY)) { + purple_conv_chat_user_set_flags(chat, cb->name, flags & ~PURPLE_CBFLAGS_AWAY); + } + } +} + void irc_msg_list(struct irc_conn *irc, const char *name, const char *from, char **args) { if (!irc->roomlist) @@ -797,7 +852,10 @@ { PurpleConnection *gc = purple_account_get_connection(irc->account); PurpleConversation *convo; - char *nick = irc_mask_nick(from), *userhost; + PurpleConvChat *chat; + PurpleConvChatBuddy *cb; + + char *nick = irc_mask_nick(from), *userhost, *buf; struct irc_buddy *ib; static int id = 1; @@ -820,6 +878,12 @@ } purple_conversation_set_data(convo, IRC_NAMES_FLAG, GINT_TO_POINTER(FALSE)); + + // Get the real name and user host for all participants. + buf = irc_format(irc, "vc", "WHO", args[0]); + irc_send(irc, buf); + g_free(buf); + /* Until purple_conversation_present does something that * one would expect in Pidgin, this call produces buggy * behavior both for the /join and auto-join cases. */ @@ -835,8 +899,16 @@ } userhost = irc_mask_userhost(from); - purple_conv_chat_add_user(PURPLE_CONV_CHAT(convo), nick, userhost, PURPLE_CBFLAGS_NONE, TRUE); - + chat = PURPLE_CONV_CHAT(convo); + + purple_conv_chat_add_user(chat, nick, userhost, PURPLE_CBFLAGS_NONE, TRUE); + + cb = purple_conv_chat_cb_find(chat, nick); + + if (cb) { + purple_conv_chat_cb_set_attribute(chat, cb, "userhost", userhost); + } + if ((ib = g_hash_table_lookup(irc->buddies, nick)) != NULL) { ib->new_online_status = TRUE; irc_buddy_status(nick, ib, irc); diff -r 2b1b52d66a24 -r 7cbd01b1ed31 libpurple/protocols/irc/parse.c --- a/libpurple/protocols/irc/parse.c Sun Mar 13 23:10:44 2011 +0000 +++ b/libpurple/protocols/irc/parse.c Sun Mar 13 23:11:32 2011 +0000 @@ -65,6 +65,7 @@ { "319", "nn:", irc_msg_whois }, /* Whois channels */ { "320", "nn:", irc_msg_whois }, /* Whois (fn ident) */ { "314", "nnnvv:", irc_msg_whois }, /* Whowas user */ + { "315", "nt:", irc_msg_who }, /* end of WHO channel */ { "369", "nt:", irc_msg_endwhois }, /* End of WHOWAS */ { "321", "*", irc_msg_list }, /* Start of list */ { "322", "ncv:", irc_msg_list }, /* List. */ @@ -73,6 +74,7 @@ { "331", "nc:", irc_msg_topic }, /* No channel topic */ { "332", "nc:", irc_msg_topic }, /* Channel topic */ { "333", "*", irc_msg_ignore }, /* Topic setter stuff */ + { "352", "nvcvnvvv:", irc_msg_who },/* Channel WHO */ { "353", "nvc:", irc_msg_names }, /* Names list */ { "366", "nc:", irc_msg_names }, /* End of names */ { "367", "ncnnv", irc_msg_ban }, /* Ban list */ diff -r 2b1b52d66a24 -r 7cbd01b1ed31 libpurple/protocols/jabber/buddy.c --- a/libpurple/protocols/jabber/buddy.c Sun Mar 13 23:10:44 2011 +0000 +++ b/libpurple/protocols/jabber/buddy.c Sun Mar 13 23:11:32 2011 +0000 @@ -1021,7 +1021,7 @@ if (!serverside_alias) serverside_alias = g_strdup(text); - purple_notify_user_info_add_pair(user_info, _("Full Name"), text); + purple_notify_user_info_add_pair_plaintext(user_info, _("Full Name"), text); } else if(!strcmp(child->name, "N")) { for(child2 = child->child; child2; child2 = child2->next) { @@ -1032,11 +1032,11 @@ text2 = xmlnode_get_data(child2); if(text2 && !strcmp(child2->name, "FAMILY")) { - purple_notify_user_info_add_pair(user_info, _("Family Name"), text2); + purple_notify_user_info_add_pair_plaintext(user_info, _("Family Name"), text2); } else if(text2 && !strcmp(child2->name, "GIVEN")) { - purple_notify_user_info_add_pair(user_info, _("Given Name"), text2); + purple_notify_user_info_add_pair_plaintext(user_info, _("Given Name"), text2); } else if(text2 && !strcmp(child2->name, "MIDDLE")) { - purple_notify_user_info_add_pair(user_info, _("Middle Name"), text2); + purple_notify_user_info_add_pair_plaintext(user_info, _("Middle Name"), text2); } g_free(text2); } @@ -1047,10 +1047,10 @@ g_free(serverside_alias); serverside_alias = g_strdup(text); - purple_notify_user_info_add_pair(user_info, _("Nickname"), text); + purple_notify_user_info_add_pair_plaintext(user_info, _("Nickname"), text); } } else if(text && !strcmp(child->name, "BDAY")) { - purple_notify_user_info_add_pair(user_info, _("Birthday"), text); + purple_notify_user_info_add_pair_plaintext(user_info, _("Birthday"), text); } else if(!strcmp(child->name, "ADR")) { gboolean address_line_added = FALSE; @@ -1074,25 +1074,25 @@ } if(!strcmp(child2->name, "POBOX")) { - purple_notify_user_info_add_pair(user_info, _("P.O. Box"), text2); + purple_notify_user_info_add_pair_plaintext(user_info, _("P.O. Box"), text2); } else if (g_str_equal(child2->name, "EXTADD") || g_str_equal(child2->name, "EXTADR")) { /* * EXTADD is correct, EXTADR is generated by other * clients. The next time someone reads this, remove * EXTADR. */ - purple_notify_user_info_add_pair(user_info, _("Extended Address"), text2); + purple_notify_user_info_add_pair_plaintext(user_info, _("Extended Address"), text2); } else if(!strcmp(child2->name, "STREET")) { - purple_notify_user_info_add_pair(user_info, _("Street Address"), text2); + purple_notify_user_info_add_pair_plaintext(user_info, _("Street Address"), text2); } else if(!strcmp(child2->name, "LOCALITY")) { - purple_notify_user_info_add_pair(user_info, _("Locality"), text2); + purple_notify_user_info_add_pair_plaintext(user_info, _("Locality"), text2); } else if(!strcmp(child2->name, "REGION")) { - purple_notify_user_info_add_pair(user_info, _("Region"), text2); + purple_notify_user_info_add_pair_plaintext(user_info, _("Region"), text2); } else if(!strcmp(child2->name, "PCODE")) { - purple_notify_user_info_add_pair(user_info, _("Postal Code"), text2); + purple_notify_user_info_add_pair_plaintext(user_info, _("Postal Code"), text2); } else if(!strcmp(child2->name, "CTRY") || !strcmp(child2->name, "COUNTRY")) { - purple_notify_user_info_add_pair(user_info, _("Country"), text2); + purple_notify_user_info_add_pair_plaintext(user_info, _("Country"), text2); } g_free(text2); } @@ -1106,13 +1106,13 @@ /* show what kind of number it is */ number = xmlnode_get_data(child2); if(number) { - purple_notify_user_info_add_pair(user_info, _("Telephone"), number); + purple_notify_user_info_add_pair_plaintext(user_info, _("Telephone"), number); g_free(number); } } else if((number = xmlnode_get_data(child))) { /* lots of clients (including purple) do this, but it's * out of spec */ - purple_notify_user_info_add_pair(user_info, _("Telephone"), number); + purple_notify_user_info_add_pair_plaintext(user_info, _("Telephone"), number); g_free(number); } } else if(!strcmp(child->name, "EMAIL")) { @@ -1153,18 +1153,18 @@ text2 = xmlnode_get_data(child2); if(text2 && !strcmp(child2->name, "ORGNAME")) { - purple_notify_user_info_add_pair(user_info, _("Organization Name"), text2); + purple_notify_user_info_add_pair_plaintext(user_info, _("Organization Name"), text2); } else if(text2 && !strcmp(child2->name, "ORGUNIT")) { - purple_notify_user_info_add_pair(user_info, _("Organization Unit"), text2); + purple_notify_user_info_add_pair_plaintext(user_info, _("Organization Unit"), text2); } g_free(text2); } } else if(text && !strcmp(child->name, "TITLE")) { - purple_notify_user_info_add_pair(user_info, _("Job Title"), text); + purple_notify_user_info_add_pair_plaintext(user_info, _("Job Title"), text); } else if(text && !strcmp(child->name, "ROLE")) { - purple_notify_user_info_add_pair(user_info, _("Role"), text); + purple_notify_user_info_add_pair_plaintext(user_info, _("Role"), text); } else if(text && !strcmp(child->name, "DESC")) { - purple_notify_user_info_add_pair(user_info, _("Description"), text); + purple_notify_user_info_add_pair_plaintext(user_info, _("Description"), text); } else if(!strcmp(child->name, "PHOTO") || !strcmp(child->name, "LOGO")) { char *bintext = NULL; diff -r 2b1b52d66a24 -r 7cbd01b1ed31 libpurple/protocols/msn/msn.c --- a/libpurple/protocols/msn/msn.c Sun Mar 13 23:10:44 2011 +0000 +++ b/libpurple/protocols/msn/msn.c Sun Mar 13 23:11:32 2011 +0000 @@ -1040,7 +1040,6 @@ const char *psm, *name; const char *mediatype = NULL; char *currentmedia = NULL; - char *tmp; psm = purple_status_get_attr_string(status, "message"); if (purple_presence_is_status_primitive_active(presence, PURPLE_STATUS_TUNE)) { @@ -1084,9 +1083,7 @@ } if (psm != NULL && *psm) { - tmp = g_markup_escape_text(psm, -1); - purple_notify_user_info_add_pair(user_info, tmp2, tmp); - g_free(tmp); + purple_notify_user_info_add_pair_plaintext(user_info, tmp2, psm); } else { purple_notify_user_info_add_pair(user_info, _("Status"), tmp2); } @@ -1094,13 +1091,11 @@ g_free(tmp2); } else { if (psm != NULL && *psm) { - tmp = g_markup_escape_text(psm, -1); if (purple_presence_is_idle(presence)) { - purple_notify_user_info_add_pair(user_info, _("Idle"), tmp); + purple_notify_user_info_add_pair_plaintext(user_info, _("Idle"), psm); } else { - purple_notify_user_info_add_pair(user_info, _("Status"), tmp); + purple_notify_user_info_add_pair_plaintext(user_info, _("Status"), psm); } - g_free(tmp); } else { if (purple_presence_is_idle(presence)) { purple_notify_user_info_add_pair(user_info, _("Status"), @@ -2304,9 +2299,7 @@ alias = purple_buddy_get_local_buddy_alias(b); if (alias && alias[0]) { - char *aliastext = g_markup_escape_text(alias, -1); - purple_notify_user_info_add_pair(user_info, _("Alias"), aliastext); - g_free(aliastext); + purple_notify_user_info_add_pair_plaintext(user_info, _("Alias"), alias); } if ((alias = purple_buddy_get_server_alias(b)) != NULL) diff -r 2b1b52d66a24 -r 7cbd01b1ed31 libpurple/protocols/yahoo/libymsg.c --- a/libpurple/protocols/yahoo/libymsg.c Sun Mar 13 23:10:44 2011 +0000 +++ b/libpurple/protocols/yahoo/libymsg.c Sun Mar 13 23:11:32 2011 +0000 @@ -3990,7 +3990,6 @@ void yahoo_tooltip_text(PurpleBuddy *b, PurpleNotifyUserInfo *user_info, gboolean full) { YahooFriend *f; - char *escaped; char *status = NULL; const char *presence = NULL; PurpleAccount *account; @@ -4029,14 +4028,12 @@ } if (status != NULL) { - escaped = g_markup_escape_text(status, strlen(status)); - purple_notify_user_info_add_pair(user_info, _("Status"), escaped); + purple_notify_user_info_add_pair_plaintext(user_info, _("Status"), status); g_free(status); - g_free(escaped); } if (presence != NULL) - purple_notify_user_info_add_pair(user_info, _("Presence"), presence); + purple_notify_user_info_add_pair_plaintext(user_info, _("Presence"), presence); if (f && full) { YahooPersonalDetails *ypd = &f->ypd; diff -r 2b1b52d66a24 -r 7cbd01b1ed31 libpurple/protocols/yahoo/yahoo_profile.c --- a/libpurple/protocols/yahoo/yahoo_profile.c Sun Mar 13 23:10:44 2011 +0000 +++ b/libpurple/protocols/yahoo/yahoo_profile.c Sun Mar 13 23:11:32 2011 +0000 @@ -701,14 +701,12 @@ if (b) { const char *balias = purple_buddy_get_local_buddy_alias(b); if(balias && balias[0]) { - char *aliastext = g_markup_escape_text(balias, -1); - purple_notify_user_info_add_pair(user_info, _("Alias"), aliastext); - g_free(aliastext); + purple_notify_user_info_add_pair_plaintext(user_info, _("Alias"), balias); } #if 0 if (b->idle > 0) { char *idletime = purple_str_seconds_to_string(time(NULL) - b->idle); - purple_notify_user_info_add_pair(user_info, _("Idle"), idletime); + purple_notify_user_info_add_pair_plaintext(user_info, _("Idle"), idletime); g_free(idletime); } #endif @@ -719,7 +717,7 @@ if ((f = yahoo_friend_find(info_data->gc, purple_buddy_get_name(b)))) { const char *ip; if ((ip = yahoo_friend_get_ip(f))) - purple_notify_user_info_add_pair(user_info, _("IP Address"), ip); + purple_notify_user_info_add_pair_plaintext(user_info, _("IP Address"), ip); } } } diff -r 2b1b52d66a24 -r 7cbd01b1ed31 libpurple/signals.c --- a/libpurple/signals.c Sun Mar 13 23:10:44 2011 +0000 +++ b/libpurple/signals.c Sun Mar 13 23:11:32 2011 +0000 @@ -818,6 +818,21 @@ *return_val = GINT_TO_POINTER(ret_val); } + void +purple_marshal_INT__POINTER_POINTER_POINTER( + PurpleCallback cb, va_list args, void *data, void **return_val) +{ + gint ret_val; + void *arg1 = va_arg(args, void *); + void *arg2 = va_arg(args, void *); + void *arg3 = va_arg(args, void *); + + ret_val = ((gint (*)(void *, void *, void *, void *))cb)(arg1, arg2, arg3, data); + + if (return_val != NULL) + *return_val = GINT_TO_POINTER(ret_val); +} + void purple_marshal_INT__POINTER_POINTER_POINTER_POINTER_POINTER( PurpleCallback cb, va_list args, void *data, void **return_val) diff -r 2b1b52d66a24 -r 7cbd01b1ed31 libpurple/signals.h --- a/libpurple/signals.h Sun Mar 13 23:10:44 2011 +0000 +++ b/libpurple/signals.h Sun Mar 13 23:11:32 2011 +0000 @@ -330,6 +330,8 @@ PurpleCallback cb, va_list args, void *data, void **return_val); void purple_marshal_INT__POINTER_POINTER( PurpleCallback cb, va_list args, void *data, void **return_val); +void purple_marshal_INT__POINTER_POINTER_POINTER( + PurpleCallback cb, va_list args, void *data, void **return_val); void purple_marshal_INT__POINTER_POINTER_POINTER_POINTER_POINTER( PurpleCallback cb, va_list args, void *data, void **return_val); diff -r 2b1b52d66a24 -r 7cbd01b1ed31 pidgin/gtkaccount.c --- a/pidgin/gtkaccount.c Sun Mar 13 23:10:44 2011 +0000 +++ b/pidgin/gtkaccount.c Sun Mar 13 23:11:32 2011 +0000 @@ -143,6 +143,10 @@ GtkWidget *proxy_user_entry; GtkWidget *proxy_pass_entry; + /* Voice & Video Options*/ + GtkWidget *voice_frame; + GtkWidget *suppression_check; + } AccountPrefsDialog; static AccountsWindow *accounts_window = NULL; @@ -159,6 +163,7 @@ static void add_user_options(AccountPrefsDialog *dialog, GtkWidget *parent); static void add_protocol_options(AccountPrefsDialog *dialog); static void add_proxy_options(AccountPrefsDialog *dialog, GtkWidget *parent); +static void add_voice_options(AccountPrefsDialog *dialog); static GtkWidget * add_pref_box(AccountPrefsDialog *dialog, GtkWidget *parent, @@ -237,6 +242,7 @@ add_login_options(dialog, dialog->top_vbox); add_user_options(dialog, dialog->top_vbox); add_protocol_options(dialog); + add_voice_options(dialog); gtk_widget_grab_focus(dialog->protocol_menu); @@ -1163,6 +1169,39 @@ G_CALLBACK(proxy_type_changed_cb), dialog); } +static void +add_voice_options(AccountPrefsDialog *dialog) +{ +#ifdef USE_VV + if (!dialog->prpl_info || !dialog->prpl_info->initiate_media) { + if (dialog->voice_frame) { + gtk_widget_destroy(dialog->voice_frame); + dialog->voice_frame = NULL; + dialog->suppression_check = NULL; + } + return; + } + + if (!dialog->voice_frame) { + dialog->voice_frame = gtk_vbox_new(FALSE, PIDGIN_HIG_BORDER); + gtk_container_set_border_width(GTK_CONTAINER(dialog->voice_frame), + PIDGIN_HIG_BORDER); + + dialog->suppression_check = + gtk_check_button_new_with_mnemonic(_("Use _silence suppression")); + gtk_box_pack_start(GTK_BOX(dialog->voice_frame), dialog->suppression_check, + FALSE, FALSE, 0); + + gtk_notebook_append_page(GTK_NOTEBOOK(dialog->notebook), + dialog->voice_frame, gtk_label_new_with_mnemonic(_("_Voice and Video"))); + gtk_widget_show_all(dialog->voice_frame); + } + + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->suppression_check), + purple_account_get_silence_suppression(dialog->account)); +#endif +} + static gboolean account_win_destroy_cb(GtkWidget *w, GdkEvent *event, AccountPrefsDialog *dialog) @@ -1437,6 +1476,12 @@ proxy_info = NULL; } + /* Voice and Video settings */ + if (dialog->voice_frame) { + purple_account_set_silence_suppression(account, + gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->suppression_check))); + } + /* If this is a new account, add it to our list */ if (new_acct) purple_accounts_add(account); @@ -1558,6 +1603,8 @@ gtk_widget_show(dbox); add_proxy_options(dialog, dbox); + add_voice_options(dialog); + /* Cancel button */ pidgin_dialog_add_button(GTK_DIALOG(win), GTK_STOCK_CANCEL, G_CALLBACK(cancel_account_prefs_cb), dialog); @@ -2141,7 +2188,6 @@ create_accounts_list(AccountsWindow *dialog) { GtkWidget *frame; - GtkWidget *sw; GtkWidget *label; GtkWidget *treeview; GtkTreeSelection *sel; @@ -2181,16 +2227,6 @@ gtk_misc_set_alignment(GTK_MISC(label), 0.5, 0.5); gtk_notebook_append_page(GTK_NOTEBOOK(accounts_window->notebook), label, NULL); - /* Create the scrolled window. */ - sw = gtk_scrolled_window_new(0, 0); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), - GTK_POLICY_AUTOMATIC, - GTK_POLICY_AUTOMATIC); - gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), - GTK_SHADOW_NONE); - gtk_notebook_append_page(GTK_NOTEBOOK(accounts_window->notebook), sw, NULL); - gtk_widget_show(sw); - /* Create the list model. */ dialog->model = gtk_list_store_new(NUM_COLUMNS, GDK_TYPE_PIXBUF, /* COLUMN_ICON */ @@ -2216,7 +2252,9 @@ g_signal_connect(G_OBJECT(treeview), "button_press_event", G_CALLBACK(account_treeview_double_click_cb), dialog); - gtk_container_add(GTK_CONTAINER(sw), treeview); + gtk_notebook_append_page(GTK_NOTEBOOK(accounts_window->notebook), + pidgin_make_scrollable(treeview, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC, GTK_SHADOW_NONE, -1, -1), + NULL); add_columns(treeview, dialog); gtk_tree_view_columns_autosize(GTK_TREE_VIEW(treeview)); diff -r 2b1b52d66a24 -r 7cbd01b1ed31 pidgin/gtkblist.c --- a/pidgin/gtkblist.c Sun Mar 13 23:10:44 2011 +0000 +++ b/pidgin/gtkblist.c Sun Mar 13 23:11:32 2011 +0000 @@ -5730,7 +5730,6 @@ GtkTreeViewColumn *column; GtkWidget *menu; GtkWidget *ebox; - GtkWidget *sw; GtkWidget *sep; GtkWidget *label; GtkWidget *close; @@ -5881,11 +5880,6 @@ g_signal_connect(G_OBJECT(ebox), "button-press-event", G_CALLBACK(headline_box_press_cb), gtkblist); /****************************** GtkTreeView **********************************/ - sw = gtk_scrolled_window_new(NULL,NULL); - gtk_widget_show(sw); - gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW(sw), GTK_SHADOW_NONE); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - gtkblist->treemodel = gtk_tree_store_new(BLIST_COLUMNS, GDK_TYPE_PIXBUF, /* Status icon */ G_TYPE_BOOLEAN, /* Status icon visible */ @@ -5965,8 +5959,9 @@ gtk_tree_view_set_search_equal_func(GTK_TREE_VIEW(gtkblist->treeview), pidgin_blist_search_equal_func, NULL, NULL); - gtk_box_pack_start(GTK_BOX(gtkblist->vbox), sw, TRUE, TRUE, 0); - gtk_container_add(GTK_CONTAINER(sw), gtkblist->treeview); + gtk_box_pack_start(GTK_BOX(gtkblist->vbox), + pidgin_make_scrollable(gtkblist->treeview, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC, GTK_SHADOW_NONE, -1, -1), + TRUE, TRUE, 0); sep = gtk_hseparator_new(); gtk_box_pack_start(GTK_BOX(gtkblist->vbox), sep, FALSE, FALSE, 0); diff -r 2b1b52d66a24 -r 7cbd01b1ed31 pidgin/gtkcertmgr.c --- a/pidgin/gtkcertmgr.c Sun Mar 13 23:10:44 2011 +0000 +++ b/pidgin/gtkcertmgr.c Sun Mar 13 23:11:32 2011 +0000 @@ -390,7 +390,6 @@ { GtkWidget *bbox; GtkListStore *store; - GtkWidget *sw; /* This block of variables will end up in tpm_dat */ GtkTreeView *listview; @@ -417,16 +416,6 @@ g_signal_connect(G_OBJECT(mgmt_widget), "destroy", G_CALLBACK(tls_peers_mgmt_destroy), NULL); - /* Scrolled window */ - sw = gtk_scrolled_window_new(NULL,NULL); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), - GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS); - gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), GTK_SHADOW_IN); - gtk_box_pack_start(GTK_BOX(mgmt_widget), GTK_WIDGET(sw), - TRUE, TRUE, /* Take up lots of space */ - 0); - gtk_widget_show(GTK_WIDGET(sw)); - /* List view */ store = gtk_list_store_new(TPM_N_COLUMNS, G_TYPE_STRING); @@ -463,7 +452,10 @@ g_signal_connect(G_OBJECT(select), "changed", G_CALLBACK(tls_peers_mgmt_select_chg_cb), NULL); - gtk_container_add(GTK_CONTAINER(sw), GTK_WIDGET(listview)); + gtk_box_pack_start(GTK_BOX(mgmt_widget), + pidgin_make_scrollable(GTK_WIDGET(listview), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS, GTK_SHADOW_IN, -1, -1), + TRUE, TRUE, /* Take up lots of space */ + 0); gtk_widget_show(GTK_WIDGET(listview)); /* Fill the list for the first time */ diff -r 2b1b52d66a24 -r 7cbd01b1ed31 pidgin/gtkconv.c --- a/pidgin/gtkconv.c Sun Mar 13 23:10:44 2011 +0000 +++ b/pidgin/gtkconv.c Sun Mar 13 23:11:32 2011 +0000 @@ -4693,7 +4693,7 @@ setup_chat_userlist(PidginConversation *gtkconv, GtkWidget *hpaned) { PidginChatPane *gtkchat = gtkconv->u.chat; - GtkWidget *lbox, *sw, *list; + GtkWidget *lbox, *list; GtkListStore *ls; GtkCellRenderer *rend; GtkTreeViewColumn *col; @@ -4713,12 +4713,6 @@ gtk_widget_show(gtkchat->count); /* Setup the list of users. */ - sw = gtk_scrolled_window_new(NULL, NULL); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), - GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), GTK_SHADOW_IN); - gtk_box_pack_start(GTK_BOX(lbox), sw, TRUE, TRUE, 0); - gtk_widget_show(sw); ls = gtk_list_store_new(CHAT_USERS_COLUMNS, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT, @@ -4788,7 +4782,9 @@ gtkchat->list = list; - gtk_container_add(GTK_CONTAINER(sw), list); + gtk_box_pack_start(GTK_BOX(lbox), + pidgin_make_scrollable(list, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC, GTK_SHADOW_IN, -1, -1), + TRUE, TRUE, 0); } static gboolean @@ -4895,7 +4891,6 @@ PurpleConversation *conv = gtkconv->active_conv; PurpleBuddy *buddy; gboolean chat = (conv->type == PURPLE_CONV_TYPE_CHAT); - GtkPolicyType imhtml_sw_hscroll; int buddyicon_size = 0; /* Setup the top part of the pane */ @@ -5012,10 +5007,7 @@ gtk_imhtml_show_comments(GTK_IMHTML(gtkconv->imhtml),TRUE); g_object_set_data(G_OBJECT(gtkconv->imhtml), "gtkconv", gtkconv); - gtk_scrolled_window_get_policy(GTK_SCROLLED_WINDOW(imhtml_sw), - &imhtml_sw_hscroll, NULL); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(imhtml_sw), - imhtml_sw_hscroll, GTK_POLICY_ALWAYS); + g_object_set(G_OBJECT(imhtml_sw), "vscrollbar-policy", GTK_POLICY_ALWAYS, NULL); g_signal_connect_after(G_OBJECT(gtkconv->imhtml), "button_press_event", G_CALLBACK(entry_stop_rclick_cb), NULL); diff -r 2b1b52d66a24 -r 7cbd01b1ed31 pidgin/gtkft.c --- a/pidgin/gtkft.c Sun Mar 13 23:10:44 2011 +0000 +++ b/pidgin/gtkft.c Sun Mar 13 23:11:32 2011 +0000 @@ -557,22 +557,12 @@ static GtkWidget * setup_tree(PidginXferDialog *dialog) { - GtkWidget *sw; GtkWidget *tree; GtkListStore *model; GtkCellRenderer *renderer; GtkTreeViewColumn *column; GtkTreeSelection *selection; - /* Create the scrolled window. */ - sw = gtk_scrolled_window_new(0, 0); - gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), - GTK_SHADOW_IN); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), - GTK_POLICY_AUTOMATIC, - GTK_POLICY_AUTOMATIC); - gtk_widget_show(sw); - /* Build the tree model */ /* Transfer type, Progress Bar, Filename, Size, Remaining */ model = gtk_list_store_new(NUM_COLUMNS, GDK_TYPE_PIXBUF, G_TYPE_INT, @@ -636,10 +626,9 @@ gtk_tree_view_columns_autosize(GTK_TREE_VIEW(tree)); - gtk_container_add(GTK_CONTAINER(sw), tree); gtk_widget_show(tree); - return sw; + return tree; } static GtkWidget * @@ -713,7 +702,6 @@ PidginXferDialog *dialog; GtkWidget *window; GtkWidget *vbox1, *vbox2; - GtkWidget *sw; GtkWidget *expander; GtkWidget *alignment; GtkWidget *table; @@ -744,9 +732,9 @@ gtk_widget_show(vbox2); /* Setup the listbox */ - sw = setup_tree(dialog); - gtk_box_pack_start(GTK_BOX(vbox2), sw, TRUE, TRUE, 0); - gtk_widget_set_size_request(sw,-1, 140); + gtk_box_pack_start(GTK_BOX(vbox2), + pidgin_make_scrollable(setup_tree(dialog), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC, GTK_SHADOW_IN, -1, 140), + TRUE, TRUE, 0); /* "Close this window when all transfers finish" */ checkbox = gtk_check_button_new_with_mnemonic( diff -r 2b1b52d66a24 -r 7cbd01b1ed31 pidgin/gtkimhtmltoolbar.c --- a/pidgin/gtkimhtmltoolbar.c Sun Mar 13 23:10:44 2011 +0000 +++ b/pidgin/gtkimhtmltoolbar.c Sun Mar 13 23:11:32 2011 +0000 @@ -858,14 +858,9 @@ g_signal_connect(G_OBJECT(dialog), "button-press-event", (GCallback)smiley_dialog_input_cb, toolbar); } - scrolled = gtk_scrolled_window_new (NULL, NULL); - gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW (scrolled), GTK_SHADOW_NONE); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (scrolled), - GTK_POLICY_NEVER, GTK_POLICY_NEVER); + + scrolled = pidgin_make_scrollable(smiley_table, GTK_POLICY_NEVER, GTK_POLICY_NEVER, GTK_SHADOW_NONE, -1, -1); gtk_box_pack_start(GTK_BOX(vbox), scrolled, TRUE, TRUE, 0); - gtk_widget_show(scrolled); - - gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolled), smiley_table); gtk_widget_show(smiley_table); viewport = gtk_widget_get_parent(smiley_table); @@ -890,8 +885,10 @@ * makes one or both scrollbars visible (sometimes). * I too think this hack is gross. But I couldn't find a better way -- sadrul */ gtk_window_set_resizable(GTK_WINDOW(dialog), TRUE); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (scrolled), - GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + g_object_set(G_OBJECT(scrolled), + "hscrollbar-policy", GTK_POLICY_AUTOMATIC, + "vscrollbar-policy", GTK_POLICY_AUTOMATIC, + NULL); #ifdef _WIN32 winpidgin_ensure_onscreen(dialog); diff -r 2b1b52d66a24 -r 7cbd01b1ed31 pidgin/gtklog.c --- a/pidgin/gtklog.c Sun Mar 13 23:10:44 2011 +0000 +++ b/pidgin/gtklog.c Sun Mar 13 23:11:32 2011 +0000 @@ -531,7 +531,6 @@ GtkWidget *title_box; char *text; GtkWidget *pane; - GtkWidget *sw; GtkCellRenderer *rend; GtkTreeViewColumn *col; GtkTreeSelection *sel; @@ -614,10 +613,6 @@ gtk_box_pack_start(GTK_BOX(GTK_DIALOG(lv->window)->vbox), pane, TRUE, TRUE, 0); /* List *************/ - sw = gtk_scrolled_window_new (NULL, NULL); - gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw), GTK_SHADOW_IN); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS); - gtk_paned_add1(GTK_PANED(pane), sw); lv->treestore = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_POINTER); lv->treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (lv->treestore)); g_object_unref(G_OBJECT(lv->treestore)); @@ -625,7 +620,8 @@ col = gtk_tree_view_column_new_with_attributes ("time", rend, "markup", 0, NULL); gtk_tree_view_append_column (GTK_TREE_VIEW(lv->treeview), col); gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (lv->treeview), FALSE); - gtk_container_add (GTK_CONTAINER (sw), lv->treeview); + gtk_paned_add1(GTK_PANED(pane), + pidgin_make_scrollable(lv->treeview, GTK_POLICY_NEVER, GTK_POLICY_ALWAYS, GTK_SHADOW_IN, -1, -1)); populate_log_tree(lv); diff -r 2b1b52d66a24 -r 7cbd01b1ed31 pidgin/gtknotify.c --- a/pidgin/gtknotify.c Sun Mar 13 23:10:44 2011 +0000 +++ b/pidgin/gtknotify.c Sun Mar 13 23:11:32 2011 +0000 @@ -956,7 +956,6 @@ GtkWidget *vbox; GtkWidget *label; - GtkWidget *sw; PidginNotifySearchResultsData *data; char *label_text; char *primary_esc, *secondary_esc; @@ -1012,15 +1011,6 @@ model = gtk_list_store_newv(col_num, col_types); g_free(col_types); - /* Setup the scrolled window containing the treeview */ - sw = gtk_scrolled_window_new(NULL, NULL); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), - GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS); - gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), - GTK_SHADOW_IN); - gtk_box_pack_start(GTK_BOX(vbox), sw, TRUE, TRUE, 0); - gtk_widget_show(sw); - /* Setup the treeview */ treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(model)); g_object_unref(G_OBJECT(model)); @@ -1029,7 +1019,9 @@ gtk_tree_selection_set_mode(gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)), GTK_SELECTION_SINGLE); gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(treeview), TRUE); - gtk_container_add(GTK_CONTAINER(sw), treeview); + gtk_box_pack_start(GTK_BOX(vbox), + pidgin_make_scrollable(treeview, GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS, GTK_SHADOW_IN, -1, -1), + TRUE, TRUE, 0); gtk_widget_show(treeview); renderer = gtk_cell_renderer_pixbuf_new(); @@ -1488,7 +1480,6 @@ GtkTreeStore *model = NULL; GtkWidget *dialog = NULL; GtkWidget *label = NULL; - GtkWidget *sw; GtkCellRenderer *rend; GtkTreeViewColumn *column; GtkWidget *button = NULL; @@ -1526,10 +1517,6 @@ /* Golden ratio it up! */ gtk_widget_set_size_request(dialog, 550, 400); - sw = gtk_scrolled_window_new(NULL, NULL); - gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW(sw), GTK_SHADOW_IN); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS); - spec_dialog = g_new0(PidginNotifyDialog, 1); spec_dialog->dialog = dialog; @@ -1538,7 +1525,6 @@ g_object_unref(G_OBJECT(model)); gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(spec_dialog->treeview), TRUE); - gtk_container_add(GTK_CONTAINER(sw), spec_dialog->treeview); if (type == PIDGIN_NOTIFY_MAIL) { gtk_window_set_title(GTK_WINDOW(dialog), _("New Mail")); @@ -1660,7 +1646,9 @@ gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); gtk_misc_set_alignment(GTK_MISC(label), 0, 0); gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); - gtk_box_pack_start(GTK_BOX(vbox), sw, TRUE, TRUE, 2); + gtk_box_pack_start(GTK_BOX(vbox), + pidgin_make_scrollable(spec_dialog->treeview, GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS, GTK_SHADOW_IN, -1, -1), + TRUE, TRUE, 2); return spec_dialog; } diff -r 2b1b52d66a24 -r 7cbd01b1ed31 pidgin/gtkplugin.c --- a/pidgin/gtkplugin.c Sun Mar 13 23:10:44 2011 +0000 +++ b/pidgin/gtkplugin.c Sun Mar 13 23:11:32 2011 +0000 @@ -706,7 +706,6 @@ void pidgin_plugin_dialog_show() { - GtkWidget *sw; GtkWidget *event_view; GtkListStore *ls; GtkCellRenderer *rend, *rendt; @@ -729,12 +728,6 @@ gtk_widget_set_sensitive(pref_button, FALSE); gtk_window_set_role(GTK_WINDOW(plugin_dialog), "plugins"); - sw = gtk_scrolled_window_new(NULL,NULL); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW(sw), GTK_SHADOW_IN); - - gtk_box_pack_start(GTK_BOX(GTK_DIALOG(plugin_dialog)->vbox), sw, TRUE, TRUE, 0); - ls = gtk_list_store_new(4, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_BOOLEAN); gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(ls), 1, GTK_SORT_ASCENDING); @@ -779,7 +772,9 @@ gtk_tree_view_append_column (GTK_TREE_VIEW(event_view), col); gtk_tree_view_column_set_sort_column_id(col, 1); g_object_unref(G_OBJECT(ls)); - gtk_container_add(GTK_CONTAINER(sw), event_view); + gtk_box_pack_start(GTK_BOX(GTK_DIALOG(plugin_dialog)->vbox), + pidgin_make_scrollable(event_view, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC, GTK_SHADOW_IN, -1, -1), + TRUE, TRUE, 0); gtk_tree_view_set_search_column(GTK_TREE_VIEW(event_view), 1); gtk_tree_view_set_search_equal_func(GTK_TREE_VIEW(event_view), pidgin_tree_view_search_equal_func, NULL, NULL); diff -r 2b1b52d66a24 -r 7cbd01b1ed31 pidgin/gtkpounce.c --- a/pidgin/gtkpounce.c Sun Mar 13 23:10:44 2011 +0000 +++ b/pidgin/gtkpounce.c Sun Mar 13 23:11:32 2011 +0000 @@ -1221,21 +1221,11 @@ static GtkWidget * create_pounces_list(PouncesManager *dialog) { - GtkWidget *sw; GtkWidget *treeview; GtkTreeSelection *sel; GtkTreeViewColumn *column; GtkCellRenderer *renderer; - /* Create the scrolled window */ - sw = gtk_scrolled_window_new(0, 0); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), - GTK_POLICY_AUTOMATIC, - GTK_POLICY_AUTOMATIC); - gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), - GTK_SHADOW_IN); - gtk_widget_show(sw); - /* Create the list model */ dialog->model = gtk_list_store_new(POUNCES_MANAGER_NUM_COLUMNS, G_TYPE_POINTER, @@ -1259,7 +1249,6 @@ /* Handle double-clicking */ g_signal_connect(G_OBJECT(treeview), "button_press_event", G_CALLBACK(pounce_double_click_cb), dialog); - gtk_container_add(GTK_CONTAINER(sw), treeview); gtk_widget_show(treeview); /* Pouncee Column */ @@ -1319,7 +1308,7 @@ /* Populate list */ populate_pounces_list(dialog); - return sw; + return pidgin_make_scrollable(treeview, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC, GTK_SHADOW_IN, -1, -1); } void diff -r 2b1b52d66a24 -r 7cbd01b1ed31 pidgin/gtkprefs.c --- a/pidgin/gtkprefs.c Sun Mar 13 23:10:44 2011 +0000 +++ b/pidgin/gtkprefs.c Sun Mar 13 23:11:32 2011 +0000 @@ -2513,12 +2513,6 @@ vbox->parent->parent, TRUE, TRUE, 0, GTK_PACK_START); /* SOUND SELECTION */ - sw = gtk_scrolled_window_new(NULL,NULL); - gtk_widget_set_size_request(sw, -1, 100); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); - gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW(sw), GTK_SHADOW_IN); - - gtk_box_pack_start(GTK_BOX(vbox), sw, TRUE, TRUE, 0); event_store = gtk_list_store_new (4, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_UINT); for (j=0; j < PURPLE_NUM_SOUNDS; j++) { @@ -2567,7 +2561,9 @@ NULL); gtk_tree_view_append_column (GTK_TREE_VIEW(event_view), col); g_object_unref(G_OBJECT(event_store)); - gtk_container_add(GTK_CONTAINER(sw), event_view); + gtk_box_pack_start(GTK_BOX(vbox), + pidgin_make_scrollable(event_view, GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC, GTK_SHADOW_IN, -1, 100), + TRUE, TRUE, 0); hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); diff -r 2b1b52d66a24 -r 7cbd01b1ed31 pidgin/gtkprivacy.c --- a/pidgin/gtkprivacy.c Sun Mar 13 23:10:44 2011 +0000 +++ b/pidgin/gtkprivacy.c Sun Mar 13 23:11:32 2011 +0000 @@ -133,12 +133,6 @@ GtkTreeViewColumn *column; GtkTreeSelection *sel; - sw = gtk_scrolled_window_new(NULL, NULL); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), - GTK_POLICY_AUTOMATIC, - GTK_POLICY_AUTOMATIC); - gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), GTK_SHADOW_IN); - treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(model)); *ret_treeview = treeview; @@ -150,7 +144,7 @@ gtk_tree_view_column_set_clickable(GTK_TREE_VIEW_COLUMN(column), TRUE); gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column); gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(treeview), FALSE); - gtk_container_add(GTK_CONTAINER(sw), treeview); + sw = pidgin_make_scrollable(treeview, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC, GTK_SHADOW_IN, -1, 200); gtk_widget_show(treeview); @@ -159,8 +153,6 @@ g_signal_connect(G_OBJECT(sel), "changed", G_CALLBACK(user_selected_cb), dialog); - gtk_widget_set_size_request(sw, -1, 200); - return sw; } diff -r 2b1b52d66a24 -r 7cbd01b1ed31 pidgin/gtkrequest.c --- a/pidgin/gtkrequest.c Sun Mar 13 23:10:44 2011 +0000 +++ b/pidgin/gtkrequest.c Sun Mar 13 23:11:32 2011 +0000 @@ -419,16 +419,6 @@ } else { if (multiline) { - GtkWidget *sw; - - sw = gtk_scrolled_window_new(NULL, NULL); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), - GTK_POLICY_NEVER, GTK_POLICY_ALWAYS); - gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), - GTK_SHADOW_IN); - - gtk_widget_set_size_request(sw, 320, 130); - /* GtkTextView */ entry = gtk_text_view_new(); gtk_text_view_set_editable(GTK_TEXT_VIEW(entry), TRUE); @@ -442,12 +432,12 @@ gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(entry), GTK_WRAP_WORD_CHAR); - gtk_box_pack_start(GTK_BOX(vbox), sw, TRUE, TRUE, 0); - if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/spellcheck")) pidgin_setup_gtkspell(GTK_TEXT_VIEW(entry)); - gtk_container_add(GTK_CONTAINER(sw), entry); + gtk_box_pack_start(GTK_BOX(vbox), + pidgin_make_scrollable(entry, GTK_POLICY_NEVER, GTK_POLICY_ALWAYS, GTK_SHADOW_IN, 320, 130), + TRUE, TRUE, 0); } else { entry = gtk_entry_new(); @@ -852,12 +842,6 @@ { GtkWidget *textview; - widget = gtk_scrolled_window_new(NULL, NULL); - gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(widget), - GTK_SHADOW_IN); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(widget), - GTK_POLICY_NEVER, GTK_POLICY_ALWAYS); - textview = gtk_text_view_new(); gtk_text_view_set_editable(GTK_TEXT_VIEW(textview), TRUE); @@ -867,11 +851,8 @@ if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/spellcheck")) pidgin_setup_gtkspell(GTK_TEXT_VIEW(textview)); - gtk_container_add(GTK_CONTAINER(widget), textview); gtk_widget_show(textview); - gtk_widget_set_size_request(widget, -1, 75); - if (value != NULL) { GtkTextBuffer *buffer; @@ -893,6 +874,8 @@ g_signal_connect(G_OBJECT(buffer), "changed", G_CALLBACK(req_entry_field_changed_cb), field); } + + widget = pidgin_make_scrollable(textview, GTK_POLICY_NEVER, GTK_POLICY_ALWAYS, GTK_SHADOW_IN, -1, 75); } else { @@ -1093,7 +1076,6 @@ static GtkWidget * create_list_field(PurpleRequestField *field) { - GtkWidget *sw; GtkWidget *treeview; GtkListStore *store; GtkCellRenderer *renderer; @@ -1105,14 +1087,6 @@ icons = purple_request_field_list_get_icons(field); - /* Create the scrolled window */ - sw = gtk_scrolled_window_new(NULL, NULL); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), - GTK_POLICY_AUTOMATIC, - GTK_POLICY_AUTOMATIC); - gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), - GTK_SHADOW_IN); - gtk_widget_show(sw); /* Create the list store */ if (icons) @@ -1188,10 +1162,9 @@ g_signal_connect(G_OBJECT(sel), "changed", G_CALLBACK(list_field_select_changed_cb), field); - gtk_container_add(GTK_CONTAINER(sw), treeview); gtk_widget_show(treeview); - return sw; + return pidgin_make_scrollable(treeview, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC, GTK_SHADOW_IN, -1, -1); } static void * @@ -1212,7 +1185,6 @@ GtkWidget *table; GtkWidget *button; GtkWidget *img; - GtkWidget *sw; GtkSizeGroup *sg; GList *gl, *fl; PurpleRequestFieldGroup *group; @@ -1297,18 +1269,10 @@ if(total_fields > 9) { GtkWidget *hbox_for_spacing, *vbox_for_spacing; - sw = gtk_scrolled_window_new(NULL, NULL); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), - GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); - gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), - GTK_SHADOW_NONE); - gtk_widget_set_size_request(sw, -1, 200); - gtk_box_pack_start(GTK_BOX(vbox), sw, TRUE, TRUE, 0); - gtk_widget_show(sw); - hbox_for_spacing = gtk_hbox_new(FALSE, PIDGIN_HIG_BORDER); - gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(sw), - hbox_for_spacing); + gtk_box_pack_start(GTK_BOX(vbox), + pidgin_make_scrollable(hbox_for_spacing, GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC, GTK_SHADOW_NONE, -1, 200), + TRUE, TRUE, 0); gtk_widget_show(hbox_for_spacing); vbox_for_spacing = gtk_vbox_new(FALSE, PIDGIN_HIG_BORDER); diff -r 2b1b52d66a24 -r 7cbd01b1ed31 pidgin/gtkroomlist.c --- a/pidgin/gtkroomlist.c Sun Mar 13 23:10:44 2011 +0000 +++ b/pidgin/gtkroomlist.c Sun Mar 13 23:11:32 2011 +0000 @@ -548,15 +548,8 @@ pidgin_add_widget_to_vbox(GTK_BOX(vbox2), _("_Account:"), NULL, dialog->account_widget, TRUE, NULL); /* scrolled window */ - dialog->sw = gtk_scrolled_window_new(NULL, NULL); - gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(dialog->sw), - GTK_SHADOW_IN); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(dialog->sw), - GTK_POLICY_AUTOMATIC, - GTK_POLICY_AUTOMATIC); + dialog->sw = pidgin_make_scrollable(NULL, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC, GTK_SHADOW_IN, -1, 250); gtk_box_pack_start(GTK_BOX(vbox2), dialog->sw, TRUE, TRUE, 0); - gtk_widget_set_size_request(dialog->sw, -1, 250); - gtk_widget_show(dialog->sw); /* progress bar */ dialog->progress = gtk_progress_bar_new(); diff -r 2b1b52d66a24 -r 7cbd01b1ed31 pidgin/gtksavedstatuses.c --- a/pidgin/gtksavedstatuses.c Sun Mar 13 23:10:44 2011 +0000 +++ b/pidgin/gtksavedstatuses.c Sun Mar 13 23:11:32 2011 +0000 @@ -438,20 +438,11 @@ static GtkWidget * create_saved_status_list(StatusWindow *dialog) { - GtkWidget *sw; GtkWidget *treeview; GtkTreeSelection *sel; GtkTreeViewColumn *column; GtkCellRenderer *renderer; - /* Create the scrolled window */ - sw = gtk_scrolled_window_new(0, 0); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), - GTK_POLICY_AUTOMATIC, - GTK_POLICY_ALWAYS); - gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), - GTK_SHADOW_IN); - /* Create the list model */ dialog->model = gtk_list_store_new(STATUS_WINDOW_NUM_COLUMNS, G_TYPE_STRING, @@ -472,8 +463,6 @@ g_signal_connect(G_OBJECT(sel), "changed", G_CALLBACK(status_selected_cb), dialog); - gtk_container_add(GTK_CONTAINER(sw), treeview); - /* Add columns */ column = gtk_tree_view_column_new(); gtk_tree_view_column_set_title(column, _("Title")); @@ -527,9 +516,9 @@ /* Populate list */ populate_saved_status_list(dialog); - gtk_widget_show_all(sw); + gtk_widget_show_all(treeview); - return sw; + return pidgin_make_scrollable(treeview, GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS, GTK_SHADOW_IN, -1, -1); } static gboolean @@ -1092,7 +1081,6 @@ GtkWidget *entry; GtkWidget *frame; GtkWidget *hbox; - GtkWidget *sw; GtkWidget *text; GtkWidget *toolbar; GtkWidget *vbox; @@ -1181,14 +1169,6 @@ dbox = gtk_vbox_new(FALSE, PIDGIN_HIG_CAT_SPACE); gtk_container_add(GTK_CONTAINER(expander), dbox); - /* Different status message treeview */ - sw = gtk_scrolled_window_new(NULL, NULL); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), - GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS); - gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), - GTK_SHADOW_IN); - gtk_box_pack_start(GTK_BOX(dbox), sw, TRUE, TRUE, 0); - /* Create the list model */ dialog->model = gtk_list_store_new(STATUS_EDITOR_NUM_COLUMNS, G_TYPE_POINTER, @@ -1205,7 +1185,9 @@ dialog->treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(dialog->model)); gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(dialog->treeview), TRUE); gtk_widget_set_size_request(dialog->treeview, -1, 150); - gtk_container_add(GTK_CONTAINER(sw), dialog->treeview); + gtk_box_pack_start(GTK_BOX(dbox), + pidgin_make_scrollable(dialog->treeview, GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS, GTK_SHADOW_IN, -1, -1), + TRUE, TRUE, 0); /* Add columns */ status_editor_add_columns(dialog); diff -r 2b1b52d66a24 -r 7cbd01b1ed31 pidgin/gtksmiley.c --- a/pidgin/gtksmiley.c Sun Mar 13 23:10:44 2011 +0000 +++ b/pidgin/gtksmiley.c Sun Mar 13 23:11:32 2011 +0000 @@ -774,7 +774,6 @@ static GtkWidget *smiley_list_create(SmileyManager *dialog) { - GtkWidget *sw; GtkWidget *treeview; GtkTreeSelection *sel; GtkTargetEntry te[3] = { @@ -783,14 +782,6 @@ {"STRING", 0, 2} }; - sw = gtk_scrolled_window_new(NULL, NULL); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), - GTK_POLICY_AUTOMATIC, - GTK_POLICY_AUTOMATIC); - gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), - GTK_SHADOW_IN); - gtk_widget_show(sw); - /* Create the list model */ dialog->model = gtk_list_store_new(N_COL, GDK_TYPE_PIXBUF, /* ICON */ @@ -807,7 +798,6 @@ sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)); gtk_tree_selection_set_mode(sel, GTK_SELECTION_MULTIPLE); - gtk_container_add(GTK_CONTAINER(sw), treeview); g_signal_connect(G_OBJECT(sel), "changed", G_CALLBACK(smile_selected_cb), dialog); g_signal_connect(G_OBJECT(treeview), "row_activated", G_CALLBACK(smiley_edit_cb), dialog); @@ -822,7 +812,7 @@ add_columns(treeview, dialog); populate_smiley_list(dialog); - return sw; + return pidgin_make_scrollable(treeview, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC, GTK_SHADOW_IN, -1, -1); } static void refresh_list() diff -r 2b1b52d66a24 -r 7cbd01b1ed31 pidgin/gtkstatusbox.c --- a/pidgin/gtkstatusbox.c Sun Mar 13 23:10:44 2011 +0000 +++ b/pidgin/gtkstatusbox.c Sun Mar 13 23:11:32 2011 +0000 @@ -1308,15 +1308,19 @@ *width = GTK_WIDGET(status_box)->allocation.width; hpolicy = vpolicy = GTK_POLICY_NEVER; - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (status_box->scrolled_window), - hpolicy, vpolicy); + g_object_set(G_OBJECT(status_box->scrolled_window), + "hscrollbar-policy", hpolicy, + "vscrollbar-policy", vpolicy, + NULL); gtk_widget_size_request (status_box->popup_frame, &popup_req); if (popup_req.width > *width) { hpolicy = GTK_POLICY_ALWAYS; - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (status_box->scrolled_window), - hpolicy, vpolicy); + g_object_set(G_OBJECT(status_box->scrolled_window), + "hscrollbar-policy", hpolicy, + "vscrollbar-policy", vpolicy, + NULL); gtk_widget_size_request (status_box->popup_frame, &popup_req); } @@ -1351,8 +1355,10 @@ { vpolicy = GTK_POLICY_ALWAYS; - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (status_box->scrolled_window), - hpolicy, vpolicy); + g_object_set(G_OBJECT(status_box->scrolled_window), + "hscrollbar-policy", hpolicy, + "vscrollbar-policy", vpolicy, + NULL); } } @@ -1795,19 +1801,6 @@ gtk_widget_show (status_box->popup_frame); - status_box->scrolled_window = gtk_scrolled_window_new (NULL, NULL); - - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (status_box->scrolled_window), - GTK_POLICY_NEVER, - GTK_POLICY_NEVER); - gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (status_box->scrolled_window), - GTK_SHADOW_NONE); - - gtk_widget_show (status_box->scrolled_window); - - gtk_container_add (GTK_CONTAINER (status_box->popup_frame), - status_box->scrolled_window); - status_box->tree_view = gtk_tree_view_new (); sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (status_box->tree_view)); gtk_tree_selection_set_mode (sel, GTK_SELECTION_BROWSE); @@ -1826,7 +1819,11 @@ gtk_tree_view_column_set_attributes(status_box->column, icon_rend, "stock-id", ICON_STOCK_COLUMN, NULL); gtk_tree_view_column_set_attributes(status_box->column, text_rend, "markup", TEXT_COLUMN, NULL); gtk_tree_view_column_set_attributes(status_box->column, emblem_rend, "stock-id", EMBLEM_COLUMN, "visible", EMBLEM_VISIBLE_COLUMN, NULL); - gtk_container_add(GTK_CONTAINER(status_box->scrolled_window), status_box->tree_view); + + status_box->scrolled_window = pidgin_make_scrollable(status_box->tree_view, GTK_POLICY_NEVER, GTK_POLICY_NEVER, GTK_SHADOW_NONE, -1, -1); + gtk_container_add (GTK_CONTAINER (status_box->popup_frame), + status_box->scrolled_window); + gtk_widget_show(status_box->tree_view); gtk_tree_view_set_search_column(GTK_TREE_VIEW(status_box->tree_view), TEXT_COLUMN); gtk_tree_view_set_search_equal_func(GTK_TREE_VIEW(status_box->tree_view), diff -r 2b1b52d66a24 -r 7cbd01b1ed31 pidgin/gtkutils.c --- a/pidgin/gtkutils.c Sun Mar 13 23:10:44 2011 +0000 +++ b/pidgin/gtkutils.c Sun Mar 13 23:11:32 2011 +0000 @@ -245,12 +245,6 @@ gtk_widget_show(sep); } - sw = gtk_scrolled_window_new(NULL, NULL); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), - GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - gtk_box_pack_start(GTK_BOX(vbox), sw, TRUE, TRUE, 0); - gtk_widget_show(sw); - imhtml = gtk_imhtml_new(NULL, NULL); gtk_imhtml_set_editable(GTK_IMHTML(imhtml), editable); gtk_imhtml_set_format_functions(GTK_IMHTML(imhtml), GTK_IMHTML_ALL ^ GTK_IMHTML_IMAGE); @@ -267,7 +261,8 @@ } pidgin_setup_imhtml(imhtml); - gtk_container_add(GTK_CONTAINER(sw), imhtml); + sw = pidgin_make_scrollable(imhtml, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC, GTK_SHADOW_NONE, -1, -1); + gtk_box_pack_start(GTK_BOX(vbox), sw, TRUE, TRUE, 0); if (imhtml_ret != NULL) *imhtml_ret = imhtml; @@ -3495,6 +3490,29 @@ } #endif +GtkWidget * +pidgin_make_scrollable(GtkWidget *child, GtkPolicyType hscrollbar_policy, GtkPolicyType vscrollbar_policy, GtkShadowType shadow_type, int width, int height) +{ + GtkWidget *sw = gtk_scrolled_window_new(NULL, NULL); + + if (G_LIKELY(sw)) { + gtk_widget_show(sw); + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), hscrollbar_policy, vscrollbar_policy); + gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), shadow_type); + if (width != -1 || height != -1) + gtk_widget_set_size_request(sw, width, height); + if (child) { + if (GTK_WIDGET_GET_CLASS(child)->set_scroll_adjustments_signal) + gtk_container_add(GTK_CONTAINER(sw), child); + else + gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(sw), child); + } + return sw; + } + + return child; +} + void pidgin_utils_init(void) { gtk_imhtml_class_register_protocol("http://", url_clicked_cb, link_context_menu); diff -r 2b1b52d66a24 -r 7cbd01b1ed31 pidgin/gtkutils.h --- a/pidgin/gtkutils.h Sun Mar 13 23:10:44 2011 +0000 +++ b/pidgin/gtkutils.h Sun Mar 13 23:11:32 2011 +0000 @@ -845,6 +845,19 @@ GdkPixbuf *pidgin_pixbuf_from_imgstore(PurpleStoredImage *image); /** + * Add scrollbars to a widget + * @param widget The child widget + * @hscrollbar_policy Horizontal scrolling policy + * @vscrollbar_policy Vertical scrolling policy + * @shadow Shadow type + * @width Desired widget width, or -1 for default + * @height Desired widget height, or -1 for default + * + * @since 2.8.0 + */ +GtkWidget *pidgin_make_scrollable(GtkWidget *child, GtkPolicyType hscrollbar_policy, GtkPolicyType vscrollbar_policy, GtkShadowType shadow_type, int width, int height); + +/** * Initialize some utility functions. * * @since 2.6.0 diff -r 2b1b52d66a24 -r 7cbd01b1ed31 pidgin/plugins/disco/gtkdisco.c --- a/pidgin/plugins/disco/gtkdisco.c Sun Mar 13 23:10:44 2011 +0000 +++ b/pidgin/plugins/disco/gtkdisco.c Sun Mar 13 23:11:32 2011 +0000 @@ -651,15 +651,8 @@ pidgin_add_widget_to_vbox(GTK_BOX(vbox2), _("_Account:"), NULL, dialog->account_widget, TRUE, NULL); /* scrolled window */ - dialog->sw = gtk_scrolled_window_new(NULL, NULL); - gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(dialog->sw), - GTK_SHADOW_IN); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(dialog->sw), - GTK_POLICY_AUTOMATIC, - GTK_POLICY_AUTOMATIC); + dialog->sw = pidgin_make_scrollable(NULL, GTK_POLICY_ALWAYS, GTK_POLICY_ALWAYS, GTK_SHADOW_IN, -1, 250); gtk_box_pack_start(GTK_BOX(vbox2), dialog->sw, TRUE, TRUE, 0); - gtk_widget_set_size_request(dialog->sw, -1, 250); - gtk_widget_show(dialog->sw); /* progress bar */ dialog->progress = gtk_progress_bar_new(); diff -r 2b1b52d66a24 -r 7cbd01b1ed31 pidgin/plugins/gevolution/add_buddy_dialog.c --- a/pidgin/plugins/gevolution/add_buddy_dialog.c Sun Mar 13 23:10:44 2011 +0000 +++ b/pidgin/plugins/gevolution/add_buddy_dialog.c Sun Mar 13 23:11:32 2011 +0000 @@ -430,7 +430,6 @@ { GevoAddBuddyDialog *dialog; GtkWidget *button; - GtkWidget *sw; GtkWidget *label; GtkWidget *vbox; GtkWidget *hbox; @@ -510,16 +509,6 @@ g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(clear_cb), dialog); - /* Scrolled Window */ - sw = gtk_scrolled_window_new(0, 0); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), - GTK_POLICY_AUTOMATIC, - GTK_POLICY_ALWAYS); - gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), - GTK_SHADOW_IN); - gtk_box_pack_start(GTK_BOX(vbox), sw, TRUE, TRUE, 0); - gtk_widget_show(sw); - /* Create the list model for the treeview. */ dialog->model = gtk_list_store_new(NUM_COLUMNS, G_TYPE_STRING, GDK_TYPE_PIXBUF, @@ -529,7 +518,9 @@ dialog->treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(dialog->model)); gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(dialog->treeview), TRUE); - gtk_container_add(GTK_CONTAINER(sw), dialog->treeview); + gtk_box_pack_start(GTK_BOX(vbox), + pidgin_make_scrollable(dialog->treeview, GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS, GTK_SHADOW_IN, -1, -1), + TRUE, TRUE, 0); gtk_widget_show(dialog->treeview); selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(dialog->treeview)); diff -r 2b1b52d66a24 -r 7cbd01b1ed31 pidgin/plugins/gevolution/assoc-buddy.c --- a/pidgin/plugins/gevolution/assoc-buddy.c Sun Mar 13 23:10:44 2011 +0000 +++ b/pidgin/plugins/gevolution/assoc-buddy.c Sun Mar 13 23:11:32 2011 +0000 @@ -314,7 +314,6 @@ { GevoAssociateBuddyDialog *dialog; GtkWidget *button; - GtkWidget *sw; GtkWidget *label; GtkWidget *vbox; GtkWidget *hbox; @@ -389,16 +388,6 @@ g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(clear_cb), dialog); - /* Scrolled Window */ - sw = gtk_scrolled_window_new(0, 0); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), - GTK_POLICY_AUTOMATIC, - GTK_POLICY_ALWAYS); - gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), - GTK_SHADOW_IN); - gtk_box_pack_start(GTK_BOX(vbox), sw, TRUE, TRUE, 0); - gtk_widget_show(sw); - /* Create the list model for the treeview. */ dialog->model = gtk_list_store_new(NUM_COLUMNS, G_TYPE_STRING, G_TYPE_POINTER); @@ -407,7 +396,9 @@ dialog->treeview = gtk_tree_view_new_with_model( GTK_TREE_MODEL(dialog->model)); gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(dialog->treeview), TRUE); - gtk_container_add(GTK_CONTAINER(sw), dialog->treeview); + gtk_box_pack_start(GTK_BOX(vbox), + pidgin_make_scrollable(dialog->treeview, GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS, GTK_SHADOW_IN, -1, -1), + TRUE, TRUE, 0); gtk_widget_show(dialog->treeview); selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(dialog->treeview)); @@ -437,19 +428,10 @@ * User details */ - /* Scrolled Window */ - sw = gtk_scrolled_window_new(0, 0); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), - GTK_POLICY_NEVER, - GTK_POLICY_ALWAYS); - gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), - GTK_SHADOW_IN); - gtk_container_add(GTK_CONTAINER(expander), sw); - gtk_widget_show(sw); - /* Textview */ dialog->imhtml = gtk_imhtml_new(NULL, NULL); - gtk_container_add(GTK_CONTAINER(sw), dialog->imhtml); + gtk_container_add(GTK_CONTAINER(expander), + pidgin_make_scrollable(dialog->imhtml, GTK_POLICY_NEVER, GTK_POLICY_ALWAYS, GTK_SHADOW_IN, -1, -1)); gtk_widget_show(dialog->imhtml); /* Separator. */ diff -r 2b1b52d66a24 -r 7cbd01b1ed31 pidgin/plugins/gevolution/gevolution.c --- a/pidgin/plugins/gevolution/gevolution.c Sun Mar 13 23:10:44 2011 +0000 +++ b/pidgin/plugins/gevolution/gevolution.c Sun Mar 13 23:11:32 2011 +0000 @@ -417,7 +417,6 @@ GtkWidget *ret; GtkWidget *vbox; GtkWidget *label; - GtkWidget *sw; GtkWidget *treeview; GtkTreeViewColumn *column; GtkCellRenderer *renderer; @@ -439,17 +438,6 @@ gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); gtk_widget_show(label); - /* Scrolled window */ - sw = gtk_scrolled_window_new(0, 0); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), - GTK_POLICY_AUTOMATIC, - GTK_POLICY_ALWAYS); - gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), - GTK_SHADOW_IN); - gtk_box_pack_start(GTK_BOX(vbox), sw, TRUE, TRUE, 0); - gtk_widget_set_size_request(sw, 300, 300); - gtk_widget_show(sw); - /* Create the list model for the treeview. */ model = gtk_list_store_new(NUM_COLUMNS, G_TYPE_BOOLEAN, GDK_TYPE_PIXBUF, @@ -458,7 +446,9 @@ /* Setup the treeview */ treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(model)); gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(treeview), TRUE); - gtk_container_add(GTK_CONTAINER(sw), treeview); + gtk_box_pack_start(GTK_BOX(vbox), + pidgin_make_scrollable(treeview, GTK_POLICY_AUTO, GTK_POLICY_ALWAYS, GTK_SHADOW_IN, 300, 300), + TRUE, TRUE, 0); gtk_widget_show(treeview); /* Setup the column */ diff -r 2b1b52d66a24 -r 7cbd01b1ed31 pidgin/plugins/spellchk.c --- a/pidgin/plugins/spellchk.c Sun Mar 13 23:10:44 2011 +0000 +++ b/pidgin/plugins/spellchk.c Sun Mar 13 23:11:32 2011 +0000 @@ -2156,7 +2156,7 @@ static GtkWidget * get_config_frame(PurplePlugin *plugin) { - GtkWidget *ret, *vbox, *win; + GtkWidget *ret, *vbox; GtkWidget *hbox; GtkWidget *button; GtkSizeGroup *sg; @@ -2173,15 +2173,6 @@ gtk_container_set_border_width(GTK_CONTAINER(vbox), 4); gtk_widget_show(vbox); - win = gtk_scrolled_window_new(0, 0); - gtk_box_pack_start(GTK_BOX(vbox), win, TRUE, TRUE, 0); - gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(win), - GTK_SHADOW_IN); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(win), - GTK_POLICY_NEVER, - GTK_POLICY_ALWAYS); - gtk_widget_show(win); - tree = gtk_tree_view_new_with_model(GTK_TREE_MODEL(model)); gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(tree), TRUE); gtk_widget_set_size_request(tree, -1, 200); @@ -2240,7 +2231,9 @@ gtk_tree_selection_set_mode(gtk_tree_view_get_selection(GTK_TREE_VIEW(tree)), GTK_SELECTION_MULTIPLE); - gtk_container_add(GTK_CONTAINER(win), tree); + gtk_box_pack_start(GTK_BOX(vbox), + pidgin_make_scrollable(tree, GTK_POLICY_NEVER, GTK_POLICY_ALWAYS, GTK_SHADOW_IN, -1, -1), + TRUE, TRUE, 0); gtk_widget_show(tree); hbox = gtk_hbutton_box_new(); diff -r 2b1b52d66a24 -r 7cbd01b1ed31 pidgin/plugins/xmppconsole.c --- a/pidgin/plugins/xmppconsole.c Sun Mar 13 23:10:44 2011 +0000 +++ b/pidgin/plugins/xmppconsole.c Sun Mar 13 23:11:32 2011 +0000 @@ -744,7 +744,6 @@ create_console(PurplePluginAction *action) { GtkWidget *vbox = gtk_vbox_new(FALSE, 6); - GtkWidget *sw = gtk_scrolled_window_new(NULL, NULL); GtkWidget *label; GtkTextBuffer *buffer; GtkWidget *toolbar; @@ -784,16 +783,13 @@ gtk_box_pack_start(GTK_BOX(console->hbox), console->dropdown, TRUE, TRUE, 0); g_signal_connect(G_OBJECT(console->dropdown), "changed", G_CALLBACK(dropdown_changed_cb), NULL); - gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), GTK_SHADOW_ETCHED_IN); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), - GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - console->imhtml = gtk_imhtml_new(NULL, NULL); - gtk_box_pack_start(GTK_BOX(vbox), sw, TRUE, TRUE, 0); if (console->count == 0) gtk_imhtml_append_text(GTK_IMHTML(console->imhtml), _("Not connected to XMPP"), 0); - gtk_container_add(GTK_CONTAINER(sw), console->imhtml); + gtk_box_pack_start(GTK_BOX(vbox), + pidgin_make_scrollable(console->imhtml, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC, GTK_SHADOW_ETCHED_IN, -1, -1), + TRUE, TRUE, 0); toolbar = gtk_toolbar_new(); button = gtk_tool_button_new(NULL, ""); @@ -810,21 +806,16 @@ gtk_box_pack_start(GTK_BOX(vbox), toolbar, FALSE, FALSE, 0); - sw = gtk_scrolled_window_new(NULL, NULL); - gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), GTK_SHADOW_ETCHED_IN); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), - GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - console->entry = gtk_imhtml_new(NULL, NULL); gtk_imhtml_set_whole_buffer_formatting_only(GTK_IMHTML(console->entry), TRUE); g_signal_connect(G_OBJECT(console->entry),"message_send", G_CALLBACK(message_send_cb), console); - gtk_box_pack_start(GTK_BOX(vbox), sw, FALSE, FALSE, 0); - gtk_container_add(GTK_CONTAINER(sw), console->entry); + console->sw = pidgin_make_scrollable(console->entry, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC, GTK_SHADOW_ETCHED_IN, -1, -1); + gtk_box_pack_start(GTK_BOX(vbox), console->sw, FALSE, FALSE, 0); gtk_imhtml_set_editable(GTK_IMHTML(console->entry), TRUE); buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(console->entry)); g_signal_connect(G_OBJECT(buffer), "changed", G_CALLBACK(entry_changed_cb), NULL); - console->sw = sw; + entry_changed_cb(buffer, NULL); gtk_widget_show_all(console->window);