summaryrefslogtreecommitdiff
path: root/pidgin/gtkconv.c
diff options
context:
space:
mode:
Diffstat (limited to 'pidgin/gtkconv.c')
-rw-r--r--pidgin/gtkconv.c123
1 files changed, 94 insertions, 29 deletions
diff --git a/pidgin/gtkconv.c b/pidgin/gtkconv.c
index 610433118a..8958d27d60 100644
--- a/pidgin/gtkconv.c
+++ b/pidgin/gtkconv.c
@@ -24,6 +24,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
*
*/
+#define _PIDGIN_GTKCONV_C_
+
#include "internal.h"
#include "pidgin.h"
@@ -161,7 +163,7 @@ static const char *item_factory_translate_func (const char *path, gpointer func_
gboolean pidgin_conv_has_focus(PurpleConversation *conv);
static GdkColor* generate_nick_colors(guint *numcolors, GdkColor background);
static gboolean color_is_visible(GdkColor foreground, GdkColor background, int color_contrast, int brightness_contrast);
-static GtkTextTag *get_buddy_tag(PurpleConversation *conv, const char *who, gboolean create);
+static GtkTextTag *get_buddy_tag(PurpleConversation *conv, const char *who, PurpleMessageFlags flag, gboolean create);
static void pidgin_conv_update_fields(PurpleConversation *conv, PidginConvFields fields);
static void focus_out_from_menubar(GtkWidget *wid, PidginWindow *win);
static void pidgin_conv_tab_pack(PidginWindow *win, PidginConversation *gtkconv);
@@ -172,7 +174,8 @@ static void pidgin_conv_set_position_size(PidginWindow *win, int x, int y,
int width, int height);
static gboolean pidgin_conv_xy_to_right_infopane(PidginWindow *win, int x, int y);
-static const GdkColor *get_nick_color(PidginConversation *gtkconv, const char *name) {
+static const GdkColor *get_nick_color(PidginConversation *gtkconv, const char *name)
+{
static GdkColor col;
GtkStyle *style = gtk_widget_get_style(gtkconv->imhtml);
float scale;
@@ -1910,6 +1913,40 @@ move_to_next_unread_tab(PidginConversation *gtkconv, gboolean forward)
}
static gboolean
+gtkconv_cycle_focus(PidginConversation *gtkconv, GtkDirectionType dir)
+{
+ PurpleConversation *conv = gtkconv->active_conv;
+ gboolean chat = purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT;
+ GtkWidget *next = NULL;
+ struct {
+ GtkWidget *from;
+ GtkWidget *to;
+ } transitions[] = {
+ {gtkconv->entry, gtkconv->imhtml},
+ {gtkconv->imhtml, chat ? gtkconv->u.chat->list : gtkconv->entry},
+ {chat ? gtkconv->u.chat->list : NULL, gtkconv->entry},
+ {NULL, NULL}
+ }, *ptr;
+
+ for (ptr = transitions; !next && ptr->from; ptr++) {
+ GtkWidget *from, *to;
+ if (dir == GTK_DIR_TAB_FORWARD) {
+ from = ptr->from;
+ to = ptr->to;
+ } else {
+ from = ptr->to;
+ to = ptr->from;
+ }
+ if (gtk_widget_is_focus(from))
+ next = to;
+ }
+
+ if (next)
+ gtk_widget_grab_focus(next);
+ return !!next;
+}
+
+static gboolean
conv_keypress_common(PidginConversation *gtkconv, GdkEventKey *event)
{
PidginWindow *win;
@@ -1970,7 +2007,10 @@ conv_keypress_common(PidginConversation *gtkconv, GdkEventKey *event)
#endif
return TRUE;
break;
-
+ case GDK_F6:
+ if (gtkconv_cycle_focus(gtkconv, event->state & GDK_SHIFT_MASK ? GTK_DIR_TAB_BACKWARD : GTK_DIR_TAB_FORWARD))
+ return TRUE;
+ break;
} /* End of switch */
}
@@ -1997,6 +2037,10 @@ conv_keypress_common(PidginConversation *gtkconv, GdkEventKey *event)
return TRUE;
}
break;
+ case GDK_F6:
+ if (gtkconv_cycle_focus(gtkconv, event->state & GDK_SHIFT_MASK ? GTK_DIR_TAB_BACKWARD : GTK_DIR_TAB_FORWARD))
+ return TRUE;
+ break;
}
}
return FALSE;
@@ -4423,7 +4467,7 @@ buddy_cb_common(PurpleBuddy *buddy, PurpleConversation *conv, gboolean is_buddy)
blist_node_aliased_cb((PurpleBlistNode *)buddy, NULL, conv);
- texttag = get_buddy_tag(conv, purple_buddy_get_name(buddy), FALSE); /* XXX: do we want the normalized name? */
+ texttag = get_buddy_tag(conv, purple_buddy_get_name(buddy), 0, FALSE); /* XXX: do we want the normalized name? */
if (texttag) {
g_object_set(texttag, "weight", is_buddy ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL, NULL);
}
@@ -5343,16 +5387,35 @@ pidgin_conv_write_im(PurpleConversation *conv, const char *who,
purple_conversation_write(conv, who, message, flags, mtime);
}
+static const char *
+get_text_tag_color(GtkTextTag *tag)
+{
+ GdkColor *color = NULL;
+ gboolean set = FALSE;
+ static char colcode[] = "#XXXXXX";
+ if (tag)
+ g_object_get(G_OBJECT(tag), "foreground-set", &set, "foreground-gdk", &color, NULL);
+ if (set && color)
+ g_snprintf(colcode, sizeof(colcode), "#%02x%02x%02x",
+ color->red >> 8, color->green >> 8, color->blue >> 8);
+ else
+ colcode[0] = '\0';
+ if (color)
+ gdk_color_free(color);
+ return colcode;
+}
+
/* The callback for an event on a link tag. */
static gboolean buddytag_event(GtkTextTag *tag, GObject *imhtml,
- GdkEvent *event, GtkTextIter *arg2, gpointer data) {
+ GdkEvent *event, GtkTextIter *arg2, gpointer data)
+{
if (event->type == GDK_BUTTON_PRESS
|| event->type == GDK_2BUTTON_PRESS) {
GdkEventButton *btn_event = (GdkEventButton*) event;
PurpleConversation *conv = data;
char *buddyname;
- /* strlen("BUDDY ") == 6 */
+ /* strlen("BUDDY " or "HILIT ") == 6 */
g_return_val_if_fail((tag->name != NULL)
&& (strlen(tag->name) > 6), FALSE);
@@ -5392,24 +5455,33 @@ static gboolean buddytag_event(GtkTextTag *tag, GObject *imhtml,
return FALSE;
}
-static GtkTextTag *get_buddy_tag(PurpleConversation *conv, const char *who, gboolean create)
+static GtkTextTag *get_buddy_tag(PurpleConversation *conv, const char *who, PurpleMessageFlags flag,
+ gboolean create)
{
PidginConversation *gtkconv = PIDGIN_CONVERSATION(conv);
GtkTextTag *buddytag;
gchar *str;
+ gboolean highlight = (flag & PURPLE_MESSAGE_NICK);
+ GtkTextBuffer *buffer = GTK_IMHTML(gtkconv->imhtml)->text_buffer;
- str = g_strdup_printf("BUDDY %s", who);
+ str = g_strdup_printf(highlight ? "HILIT %s" : "BUDDY %s", who);
buddytag = gtk_text_tag_table_lookup(
- gtk_text_buffer_get_tag_table(
- GTK_IMHTML(gtkconv->imhtml)->text_buffer), str);
+ gtk_text_buffer_get_tag_table(buffer), str);
if (buddytag == NULL && create) {
- buddytag = gtk_text_buffer_create_tag(
- GTK_IMHTML(gtkconv->imhtml)->text_buffer, str,
- "foreground-gdk", get_nick_color(gtkconv, who),
- "weight", purple_find_buddy(purple_conversation_get_account(conv), who) ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL,
- NULL);
+ if (highlight)
+ buddytag = gtk_text_buffer_create_tag(buffer, str,
+ "foreground", get_text_tag_color(gtk_text_tag_table_lookup(
+ gtk_text_buffer_get_tag_table(buffer), "highlight-name")),
+ "weight", PANGO_WEIGHT_BOLD,
+ NULL);
+ else
+ buddytag = gtk_text_buffer_create_tag(
+ buffer, str,
+ "foreground-gdk", get_nick_color(gtkconv, who),
+ "weight", purple_find_buddy(purple_conversation_get_account(conv), who) ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL,
+ NULL);
g_signal_connect(G_OBJECT(buddytag), "event",
G_CALLBACK(buddytag_event), conv);
@@ -5766,7 +5838,9 @@ pidgin_conv_write_conv(PurpleConversation *conv, const char *name, const char *a
}
if (flags & PURPLE_MESSAGE_NICK) {
- tagname = "highlight-name";
+ if (type == PURPLE_CONV_TYPE_IM) {
+ tagname = "highlight-name";
+ }
} else if (flags & PURPLE_MESSAGE_RECV) {
/* The tagname for chats is handled by get_buddy_tag */
if (type == PURPLE_CONV_TYPE_IM) {
@@ -5785,7 +5859,7 @@ pidgin_conv_write_conv(PurpleConversation *conv, const char *name, const char *a
if (tagname)
tag = gtk_text_tag_table_lookup(gtk_text_buffer_get_tag_table(buffer), tagname);
else
- tag = get_buddy_tag(conv, name, TRUE);
+ tag = get_buddy_tag(conv, name, flags, TRUE);
if (GTK_IMHTML(gtkconv->imhtml)->show_comments) {
/* The color for the timestamp has to be set in the font-tags, unfortunately.
@@ -5793,19 +5867,10 @@ pidgin_conv_write_conv(PurpleConversation *conv, const char *name, const char *a
* bold. I thought applying the "comment" tag again, which has "weight" set
* to PANGO_WEIGHT_NORMAL, would remove the boldness. But it doesn't. So
* this will have to do. I don't terribly like it. -- sadrul */
- GdkColor *color = NULL;
- gboolean set = FALSE;
- char colcode[] = "COLOR=\"#XXXXXX\"";
- g_object_get(G_OBJECT(tag), "foreground-set", &set, "foreground-gdk", &color, NULL);
- if (set && color)
- g_snprintf(colcode, sizeof(colcode), "COLOR=\"#%02x%02x%02x\"",
- color->red >> 8, color->green >> 8, color->blue >> 8);
- else
- colcode[0] = '\0';
- g_snprintf(buf2, BUF_LONG, "<FONT %s SIZE=\"2\"><!--%s --></FONT>", colcode, mdate);
+ const char *color = get_text_tag_color(tag);
+ g_snprintf(buf2, BUF_LONG, "<FONT %s%s%s SIZE=\"2\"><!--%s --></FONT>",
+ color ? "COLOR=\"" : "", color ? color : "", color ? "\"" : "", mdate);
gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), buf2, gtk_font_options_all | GTK_IMHTML_NO_SCROLL);
- if (color)
- gdk_color_free(color);
}
gtk_text_buffer_get_end_iter(buffer, &end);