示例#1
0
文件: gtklog.c 项目: bf4/pidgin-mac
static void log_select_cb(GtkTreeSelection *sel, PidginLogViewer *viewer) {
	GtkTreeIter iter;
	GValue val;
	GtkTreeModel *model = GTK_TREE_MODEL(viewer->treestore);
	PurpleLog *log = NULL;
	PurpleLogReadFlags flags;
	char *read = NULL;

	if (!gtk_tree_selection_get_selected(sel, &model, &iter))
		return;

	val.g_type = 0;
	gtk_tree_model_get_value (model, &iter, 1, &val);
	log = g_value_get_pointer(&val);
	g_value_unset(&val);

	if (log == NULL)
		return;

	pidgin_set_cursor(viewer->window, GDK_WATCH);

	if (log->type != PURPLE_LOG_SYSTEM) {
		char *title;
		if (log->type == PURPLE_LOG_CHAT)
			title = g_strdup_printf(_("<span size='larger' weight='bold'>Conversation in %s on %s</span>"),
									log->name, log_get_date(log));
		else
			title = g_strdup_printf(_("<span size='larger' weight='bold'>Conversation with %s on %s</span>"),
									log->name, log_get_date(log));

		gtk_label_set_markup(GTK_LABEL(viewer->label), title);
		g_free(title);
	}

	read = purple_log_read(log, &flags);
	viewer->flags = flags;

	gtk_imhtml_clear(GTK_IMHTML(viewer->imhtml));
	gtk_imhtml_set_protocol_name(GTK_IMHTML(viewer->imhtml),
	                            purple_account_get_protocol_name(log->account));

	purple_signal_emit(pidgin_log_get_handle(), "log-displaying", viewer, log);

	gtk_imhtml_append_text(GTK_IMHTML(viewer->imhtml), read,
			       GTK_IMHTML_NO_COMMENTS | GTK_IMHTML_NO_TITLE | GTK_IMHTML_NO_SCROLL |
			       ((flags & PURPLE_LOG_READ_NO_NEWLINE) ? GTK_IMHTML_NO_NEWLINE : 0));
	g_free(read);

	if (viewer->search != NULL) {
		gtk_imhtml_search_clear(GTK_IMHTML(viewer->imhtml));
		g_idle_add(search_find_cb, viewer);
	}

	pidgin_clear_cursor(viewer->window);
}
示例#2
0
static void historize(PurpleConversation *c)
{
	PurpleAccount *account = NULL;
	PurpleConversationType convtype;
	PidginConversation *gtkconv = NULL;
	GtkTextIter start;
	GtkIMHtmlOptions options;
	GList *logs = NULL, *logs_head = NULL;
	struct tm *log_tm = NULL, *local_tm = NULL;
	time_t t, log_time;
	double limit_time = 0.0;
	const char *name = NULL, *alias = NULL, *LOG_MODE = NULL;
	char *header = NULL, *protocol = NULL, *history = NULL;
	int conv_counter = 0;
	int limit_offset = 0;
	int byte_counter = 0;
	int check_time = 0;
	int log_size, overshoot;

	account = purple_conversation_get_account(c);
	name = purple_conversation_get_name(c);
	alias = name;
	LOG_MODE = purple_prefs_get_string("/purple/logging/format");

	/* If logging isn't enabled, don't show any history */
	if(!purple_prefs_get_bool("/purple/logging/log_ims") &&
			!purple_prefs_get_bool("/purple/logging/log_chats"))
		return;
	
	/* If the user wants to show 0 logs, stop now */
	if(PREF_NUMBER_VAL == 0) {
		return;
	}
	
	/* If the logging mode is html, set the output options to include no newline.
	 * Otherwise, it's normal text, so we don't need extra lines */
	if(strcasecmp(LOG_MODE, "html")==0) {
		options = GTK_IMHTML_NO_NEWLINE;
	} else {
		options = GTK_IMHTML_NO_COLOURS;
	}
	
	/* Determine whether this is an IM or a chat. In either case, if the user has that
	 * particular log type disabled, the logs file doesnt not get specified */
	convtype = purple_conversation_get_type(c);
	if (convtype == PURPLE_CONV_TYPE_IM && PREF_IM_VAL) {
		GSList *cur;
		GSList *buddies = NULL;

		/* Find buddies for this conversation. */
		buddies = purple_find_buddies(account, name);

		/* If we found at least one buddy, save the first buddy's alias. */
		if (buddies != NULL)
			alias = purple_buddy_get_contact_alias((PurpleBuddy *)buddies->data);

		for(cur = buddies; cur; cur = cur->next) {
			PurpleBlistNode *node = cur->data;

			if(node && (node->prev || node->next)) {
				PurpleBlistNode *node2;

				for(node2 = node->parent->child; node2; node2 = node2->next) {
					logs = g_list_concat(purple_log_get_logs(PURPLE_LOG_IM,
								purple_buddy_get_name((PurpleBuddy *)node2),
								purple_buddy_get_account((PurpleBuddy *)node2)), logs);
				}

				break;
			}
		}

		g_slist_free(buddies);

		if (logs)
			logs = g_list_sort(logs, purple_log_compare);
		else
			logs = purple_log_get_logs(PURPLE_LOG_IM, name, account);
	} else if (convtype == PURPLE_CONV_TYPE_CHAT && PREF_CHAT_VAL) {
		logs = purple_log_get_logs(PURPLE_LOG_CHAT,
			purple_conversation_get_name(c), purple_conversation_get_account(c));
	}

	gtkconv = PIDGIN_CONVERSATION(c);

	/* The logs are non-existant or the user has disabled this type for log displaying. */
	if (!logs) {
		return;
	}

	/* Keep a pointer to the head of the logs for freeing later */
	logs_head = logs;

	/* If all time prefs are not 0, prepare to check times */
	if (!(PREF_MINS_VAL == 0 && PREF_HOURS_VAL == 0 && PREF_DAYS_VAL == 0)) {
		check_time = 1;

		/* Grab current time and normalize it to UTC */
		t = time(NULL);
		local_tm = gmtime(&t);
		t = mktime(local_tm);

		limit_time = (PREF_MINS_VAL * 60.0) + (PREF_HOURS_VAL * 60.0 * 60.0) +
				(PREF_DAYS_VAL * 60.0 * 60.0 * 24.0);
	}

	/* The protocol will need to be adjusted for each log for correct display,
	   so save the current imhtml protocol_name to restore it later */
	protocol = g_strdup(gtk_imhtml_get_protocol_name(GTK_IMHTML(gtkconv->imhtml)));

	/* Calculate time for the first log */
	log_tm = gmtime(&((PurpleLog*)logs->data)->time);
	log_time = mktime(log_tm);

	/* Continue to add older logs until they run out or the conditions are no
	   longer met */
	while (logs && conv_counter < PREF_NUMBER_VAL
			&& byte_counter < PREF_BYTES_VAL
			&& (!check_time || difftime(t, log_time) < limit_time)) {
		guint flags;

		/* Get the current log's contents as a char* */
		history = purple_log_read((PurpleLog*)logs->data, &flags);
		log_size = strlen(history);

		if (flags & PURPLE_LOG_READ_NO_NEWLINE)
			options |= GTK_IMHTML_NO_NEWLINE;
		else
			options &= ~GTK_IMHTML_NO_NEWLINE;

		/* Update the overall byte count and determine if this log exceeds the limit */
		byte_counter += log_size;
		overshoot = byte_counter - PREF_BYTES_VAL;
		if (overshoot > 0) {
			/* Start looking at the maximum log size for a newline to break at */
			limit_offset = overshoot;
			/* Find the next \n, or stop if the end of the log is reached */
			while (history[limit_offset] && history[limit_offset] != '\n') {
				limit_offset++;
			}
			/* If we're at or very close to the end of the log, forget this log */
			if (!history[limit_offset] || (log_size - limit_offset < 3)) {
				limit_offset = -1;
			}
			else {
				/* Start at the first character after the newline */
				limit_offset++;
			}
		}

		conv_counter++;

		/* If this log won't fit at all, don't display it in the conversation */
		if (limit_offset != -1) {
			/* Set the correct protocol_name for this log */
			gtk_imhtml_set_protocol_name(GTK_IMHTML(gtkconv->imhtml),
					purple_account_get_protocol_name(((PurpleLog*)logs->data)->account));

			/* Prepend the contents of the log starting at the calculated offset */
			gtk_text_buffer_get_iter_at_offset(GTK_IMHTML(gtkconv->imhtml)->text_buffer,
					&start, 0);
			gtk_imhtml_insert_html_at_iter(GTK_IMHTML(gtkconv->imhtml),
						history + limit_offset, options, &start);

			/* Prepend the conversation header */
			if (PREF_DATES_VAL) {
				header = g_strdup_printf(_("<b>Conversation with %s on %s:</b><br>"), alias,
					purple_date_format_full(localtime(&((PurpleLog *)logs->data)->time)));
				gtk_text_buffer_get_iter_at_offset(GTK_IMHTML(gtkconv->imhtml)->text_buffer,
						&start, 0);
				gtk_imhtml_insert_html_at_iter(GTK_IMHTML(gtkconv->imhtml),
						header, options, &start);
				g_free(header);
			}
		}

		g_free(history);

		if (limit_offset > 0) {
			/* This log had to be chopped to fit, so stop after this one */
			break;
		}

		logs = logs->next;

		/* Recalculate log time if we haven't run out of logs */
		if (logs) {
			log_tm = gmtime(&((PurpleLog*)logs->data)->time);
			log_time = mktime(log_tm);
		}
	}

	gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), "<hr>", options);

	/* Restore the original protocol_name */
	gtk_imhtml_set_protocol_name(GTK_IMHTML(gtkconv->imhtml), protocol);
	g_free(protocol);
	
	g_object_ref(G_OBJECT(gtkconv->imhtml));
	g_idle_add(_scroll_imhtml_to_end, gtkconv->imhtml);
	
	/* Clear the allocated memory that the logs are using */
	g_list_foreach(logs_head, (GFunc)purple_log_free, NULL);
	g_list_free(logs_head);
	
}
示例#3
0
static void historize(PurpleConversation *c)
{
	PurpleAccount *account = purple_conversation_get_account(c);
	const char *name = purple_conversation_get_name(c);
	GList *logs = NULL;
	const char *alias = name;
	guint flags;
	char *history;
	PidginConversation *gtkconv;
#if 0
	/* FIXME: WebView has no options */
	GtkIMHtmlOptions options = GTK_IMHTML_NO_COLOURS;
#endif
	char *header;
#if 0
	/* FIXME: WebView has no protocol setting */
	char *protocol;
#endif
	char *escaped_alias;
	const char *header_date;

	gtkconv = PIDGIN_CONVERSATION(c);
	g_return_if_fail(gtkconv != NULL);

	/* An IM which is the first active conversation. */
	g_return_if_fail(gtkconv->convs != NULL);
	if (PURPLE_IS_IM_CONVERSATION(c) && !gtkconv->convs->next)
	{
		GSList *buddies;
		GSList *cur;

		/* If we're not logging, don't show anything.
		 * Otherwise, we might show a very old log. */
		if (!purple_prefs_get_bool("/purple/logging/log_ims"))
			return;

		/* Find buddies for this conversation. */
		buddies = purple_blist_find_buddies(account, name);

		/* If we found at least one buddy, save the first buddy's alias. */
		if (buddies != NULL)
			alias = purple_buddy_get_contact_alias(PURPLE_BUDDY(buddies->data));

		for (cur = buddies; cur != NULL; cur = cur->next)
		{
			PurpleBlistNode *node = cur->data;
			PurpleBlistNode *prev = purple_blist_node_get_sibling_prev(node);
			PurpleBlistNode *next = purple_blist_node_get_sibling_next(node);
			if ((node != NULL) && ((prev != NULL) || (next != NULL)))
			{
				PurpleBlistNode *node2;
				PurpleBlistNode *parent = purple_blist_node_get_parent(node);
				PurpleBlistNode *child = purple_blist_node_get_first_child(parent);

				alias = purple_buddy_get_contact_alias(PURPLE_BUDDY(node));

				/* We've found a buddy that matches this conversation.  It's part of a
				 * PurpleContact with more than one PurpleBuddy.  Loop through the PurpleBuddies
				 * in the contact and get all the logs. */
				for (node2 = child ; node2 != NULL ; node2 = purple_blist_node_get_sibling_next(node2))
				{
					logs = g_list_concat(purple_log_get_logs(PURPLE_LOG_IM,
							purple_buddy_get_name(PURPLE_BUDDY(node2)),
							purple_buddy_get_account(PURPLE_BUDDY(node2))),
							logs);
				}
				break;
			}
		}
		g_slist_free(buddies);

		if (logs == NULL)
			logs = purple_log_get_logs(PURPLE_LOG_IM, name, account);
		else
			logs = g_list_sort(logs, purple_log_compare);
	}
	else if (PURPLE_IS_CHAT_CONVERSATION(c))
	{
		/* If we're not logging, don't show anything.
		 * Otherwise, we might show a very old log. */
		if (!purple_prefs_get_bool("/purple/logging/log_chats"))
			return;

		logs = purple_log_get_logs(PURPLE_LOG_CHAT, name, account);
	}

	if (logs == NULL)
		return;

	history = purple_log_read((PurpleLog*)logs->data, &flags);
	gtkconv = PIDGIN_CONVERSATION(c);
#if 0
	/* FIXME: WebView has no options */
	if (flags & PURPLE_LOG_READ_NO_NEWLINE)
		options |= GTK_IMHTML_NO_NEWLINE;
#endif

#if 0
	/* FIXME: WebView has no protocol setting */
	protocol = g_strdup(gtk_imhtml_get_protocol_name(GTK_IMHTML(gtkconv->imhtml)));
	gtk_imhtml_set_protocol_name(GTK_IMHTML(gtkconv->imhtml),
			purple_account_get_protocol_name(((PurpleLog*)logs->data)->account));
#endif

#if 0
	/* TODO WebKit: Do this properly... */
	if (!pidgin_webview_is_empty(PIDGIN_WEBVIEW(gtkconv->webview)))
		pidgin_webview_append_html(PIDGIN_WEBVIEW(gtkconv->webview), "<BR>");
#endif

	escaped_alias = g_markup_escape_text(alias, -1);

	if (((PurpleLog *)logs->data)->tm)
		header_date = purple_date_format_full(((PurpleLog *)logs->data)->tm);
	else
		header_date = purple_date_format_full(localtime(&((PurpleLog *)logs->data)->time));

	header = g_strdup_printf(_("<b>Conversation with %s on %s:</b><br>"), escaped_alias, header_date);
	pidgin_webview_append_html(PIDGIN_WEBVIEW(gtkconv->webview), header);
	g_free(header);
	g_free(escaped_alias);

	g_strchomp(history);
	pidgin_webview_append_html(PIDGIN_WEBVIEW(gtkconv->webview), history);
	g_free(history);

	pidgin_webview_append_html(PIDGIN_WEBVIEW(gtkconv->webview), "<hr>");

#if 0
	/* FIXME: WebView has no protocol setting */
	gtk_imhtml_set_protocol_name(GTK_IMHTML(gtkconv->imhtml), protocol);
	g_free(protocol);
#endif

	g_object_ref(G_OBJECT(gtkconv->webview));
	g_idle_add(_scroll_webview_to_end, gtkconv->webview);

	g_list_foreach(logs, (GFunc)purple_log_free, NULL);
	g_list_free(logs);
}
示例#4
0
文件: history.c 项目: bf4/pidgin-mac
static void historize(PurpleConversation *c)
{
	PurpleAccount *account = purple_conversation_get_account(c);
	const char *name = purple_conversation_get_name(c);
	PurpleConversationType convtype;
	GList *logs = NULL;
	const char *alias = name;
	guint flags;
	char *history;
	PidginConversation *gtkconv;
	GtkIMHtmlOptions options = GTK_IMHTML_NO_COLOURS;
	char *header;
	char *protocol;
	char *escaped_alias;
	const char *header_date;

	convtype = purple_conversation_get_type(c);
	gtkconv = PIDGIN_CONVERSATION(c);
	g_return_if_fail(gtkconv != NULL);

	/* An IM which is the first active conversation. */
	g_return_if_fail(gtkconv->convs != NULL);
	if (convtype == PURPLE_CONV_TYPE_IM && !gtkconv->convs->next)
	{
		GSList *buddies;
		GSList *cur;

		/* If we're not logging, don't show anything.
		 * Otherwise, we might show a very old log. */
		if (!purple_prefs_get_bool("/purple/logging/log_ims"))
			return;

		/* Find buddies for this conversation. */
	        buddies = purple_find_buddies(account, name);

		/* If we found at least one buddy, save the first buddy's alias. */
		if (buddies != NULL)
			alias = purple_buddy_get_contact_alias((PurpleBuddy *)buddies->data);

	        for (cur = buddies; cur != NULL; cur = cur->next)
	        {
	                PurpleBlistNode *node = cur->data;
	                if ((node != NULL) && ((node->prev != NULL) || (node->next != NULL)))
	                {
				PurpleBlistNode *node2;

				alias = purple_buddy_get_contact_alias((PurpleBuddy *)node);

				/* We've found a buddy that matches this conversation.  It's part of a
				 * PurpleContact with more than one PurpleBuddy.  Loop through the PurpleBuddies
				 * in the contact and get all the logs. */
				for (node2 = node->parent->child ; node2 != NULL ; node2 = node2->next)
				{
					logs = g_list_concat(
						purple_log_get_logs(PURPLE_LOG_IM,
							purple_buddy_get_name((PurpleBuddy *)node2),
							purple_buddy_get_account((PurpleBuddy *)node2)),
						logs);
				}
				break;
	                }
	        }
	        g_slist_free(buddies);

		if (logs == NULL)
			logs = purple_log_get_logs(PURPLE_LOG_IM, name, account);
		else
			logs = g_list_sort(logs, purple_log_compare);
	}
	else if (convtype == PURPLE_CONV_TYPE_CHAT)
	{
		/* If we're not logging, don't show anything.
		 * Otherwise, we might show a very old log. */
		if (!purple_prefs_get_bool("/purple/logging/log_chats"))
			return;

		logs = purple_log_get_logs(PURPLE_LOG_CHAT, name, account);
	}

	if (logs == NULL)
		return;

	history = purple_log_read((PurpleLog*)logs->data, &flags);
	gtkconv = PIDGIN_CONVERSATION(c);
	if (flags & PURPLE_LOG_READ_NO_NEWLINE)
		options |= GTK_IMHTML_NO_NEWLINE;

	protocol = g_strdup(gtk_imhtml_get_protocol_name(GTK_IMHTML(gtkconv->imhtml)));
	gtk_imhtml_set_protocol_name(GTK_IMHTML(gtkconv->imhtml),
							      purple_account_get_protocol_name(((PurpleLog*)logs->data)->account));

	if (gtk_text_buffer_get_char_count(gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtkconv->imhtml))))
		gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), "<BR>", options);

	escaped_alias = g_markup_escape_text(alias, -1);

	if (((PurpleLog *)logs->data)->tm)
		header_date = purple_date_format_full(((PurpleLog *)logs->data)->tm);
	else
		header_date = purple_date_format_full(localtime(&((PurpleLog *)logs->data)->time));

	header = g_strdup_printf(_("<b>Conversation with %s on %s:</b><br>"), escaped_alias, header_date);
	gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), header, options);
	g_free(header);
	g_free(escaped_alias);

	g_strchomp(history);
	gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), history, options);
	g_free(history);

	gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), "<hr>", options);

	gtk_imhtml_set_protocol_name(GTK_IMHTML(gtkconv->imhtml), protocol);
	g_free(protocol);

	g_object_ref(G_OBJECT(gtkconv->imhtml));
	g_idle_add(_scroll_imhtml_to_end, gtkconv->imhtml);

	g_list_foreach(logs, (GFunc)purple_log_free, NULL);
	g_list_free(logs);
}