cpw.nader.asynclogging-3: f3f2ce13: Work on gobjectifying PidginLogViewer, s...
morshed.nader at gmail.com
morshed.nader at gmail.com
Thu Jan 13 21:05:55 EST 2011
----------------------------------------------------------------------
Revision: f3f2ce131743f7b3cb698e6204e35d1bff343d3c
Parent: c5a14fed2c83244f9bb6a70a1ad5ade6dbbc2861
Author: morshed.nader at gmail.com
Date: 01/13/11 17:00:00
Branch: im.pidgin.cpw.nader.asynclogging-3
URL: http://d.pidgin.im/viewmtn/revision/info/f3f2ce131743f7b3cb698e6204e35d1bff343d3c
Changelog:
Work on gobjectifying PidginLogViewer, still needs all the properties/getters/setters
Changes against parent c5a14fed2c83244f9bb6a70a1ad5ade6dbbc2861
patched libpurple/log.c
patched libpurple/log.h
patched pidgin/gtklog.c
patched pidgin/gtklog.h
-------------- next part --------------
============================================================
--- libpurple/log.c 47bcfc2d0cb70cad28c6d701d2d1895cbabcf152
+++ libpurple/log.c e3600bffa8ead07dc65de588d879d09d731fd779
@@ -39,6 +39,7 @@
#include "imgstore.h"
#include "time.h"
+
#if ! GLIB_CHECK_VERSION(2, 19, 8)
//Fixes strict-aliasing warning
#undef g_static_mutex_get_mutex_impl_shortcut
@@ -80,6 +81,7 @@ struct _PurpleLogPrivate {
struct tm *tm; /**< The time this conversation started */
};
+
typedef struct {
PurpleAccount *account;
gchar *name;
============================================================
--- libpurple/log.h 78d3847d34d9645be44819ad6df5a01f4e460dec
+++ libpurple/log.h b04587886b1503cbef63701a37e8fec56a46fd82
@@ -218,6 +218,11 @@ struct _PurpleLogSet {
/* IMPORTANT: Some code in log.c allocates these without zeroing them.
* IMPORTANT: Update that code if you add members here. */
+
+ void (*_purple_reserved1)(void);
+ void (*_purple_reserved2)(void);
+ void (*_purple_reserved3)(void);
+ void (*_purple_reserved4)(void);
};
/***************************************/
============================================================
--- pidgin/gtklog.c 950222a881f7915ca37ce3f65d20d5e202a49b02
+++ pidgin/gtklog.c cd450e7397fc939752f81d9dac07149c8398c6f1
@@ -40,24 +40,57 @@
#include "gtkutils.h"
-// PidginLogViewer members are stored here to avoid an ABI break, will be moved back in 3.x
-typedef struct {
- PidginLogViewer *lv; /**< The rest of the struct */
+#if ! GLIB_CHECK_VERSION(2, 19, 8)
+//Fixes strict-aliasing warning
+#undef g_static_mutex_get_mutex_impl_shortcut
+
+#define g_static_mutex_get_mutex_impl_shortcut(mutex) \
+ (g_atomic_pointer_get (mutex) ? *(mutex) : \
+ g_static_mutex_get_mutex_impl (mutex))
+
+#endif
+
+
+G_DEFINE_TYPE (PidginLogViewer, pidgin_log_viewer, GTK_TYPE_DIALOG)
+static void pidgin_log_viewer_get_property(GObject *, guint, GValue *, GParamSpec *);
+static void pidgin_log_viewer_set_property(GObject *, guint, const GValue *, GParamSpec *);
+static void pidgin_log_viewer_finalize(GObject *);
+
+enum {
+ PROP_0,
+ LAST_PROP
+};
+
+static GParamSpec *properties[LAST_PROP] = { 0 };
+
+#define PIDGIN_LOG_VIEWER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), PIDGIN_TYPE_LOG_VIEWER, PidginLogViewerPrivate))
+typedef struct _PidginLogViewerPrivate PidginLogViewerPrivate;
+
+struct _PidginLogViewerPrivate {
+ GList *logs; /**< The list of logs viewed in this viewer */
+ GtkTreeStore *treestore; /**< The treestore containing said logs */
+ GtkWidget *treeview; /**< The treeview representing said treestore */
+ GtkWidget *imhtml; /**< The imhtml to display said logs */
+ GtkWidget *entry; /**< The search entry, in which search terms are entered */
+ gchar *search; /**< The string currently being searched for */
+ GtkWidget *label; /**< The label at the top of the log viewer */
+ GtkWidget *size_label; /**< The label with total log size */
gsize size; /**< The actual value of the total log size */
GtkWidget *list_bar; /**< The progress bar */
GtkWidget *search_bar; /**< The progess bar for searches */
- GCancellable *read_cancel; /**< A GCancellable to stop any reads */
GCancellable *search_cancel; /**< A GCancellable to stop any searches */
GCancellable *list_cancel; /**< A GCancellable to stop any folder listings */
+ GCancellable *read_cancel; /**< A GCancellable to stop any reads */
gboolean selected; /**< A gboolean to indicate the user has already selected a log */
- PurpleLogChatType type; /**< The log type of the window */
+ PurpleLogChatType chat_type; /**< The log type of the window */
#if GTK_CHECK_VERSION(2, 20, 0)
GtkWidget *spinner; /**< A spinner to indicate a read is in progress */
#endif
-} PidginLogViewerEx;
+};
+
typedef struct {
- PidginLogViewerEx *log_viewer;
+ PidginLogViewer *log_viewer;
PurpleLog *log;
gboolean is_window_open;
@@ -69,11 +102,6 @@ typedef struct {
typedef struct {
_pidgin_log_data *log_data;
- PurpleLog *log;
-} _pidgin_search_callback_data;
-
-typedef struct {
- _pidgin_log_data *log_data;
GtkMenuPositionFunc func;
GtkTreeIter *iter;
} log_menu_callback_data;
@@ -87,7 +115,7 @@ typedef struct {
typedef struct {
PurpleAccount *account;
PurpleContact *contact;
- PurpleLogChatType type;
+ PurpleLogChatType chat_type;
gchar *buddyname;
} log_viewer_hash_t;
@@ -96,12 +124,12 @@ static gboolean log_viewer_equal(gconstp
static void pidgin_window_destroy_cb(_pidgin_log_data *);
static guint log_viewer_hash(gconstpointer);
static gboolean log_viewer_equal(gconstpointer, gconstpointer);
-static void select_first_log(PidginLogViewerEx *);
+static void select_first_log(PidginLogViewer *);
static const gchar *log_get_date(PurpleLog *);
static void pidgin_log_search_done_cb(_pidgin_log_data *);
static void pidgin_log_search_cb(GObject *, GAsyncResult *, gpointer);
-static void search_cb(GtkWidget *, PidginLogViewerEx *);
-static void destroy_cb(GtkWidget *, gint, log_viewer_hash_t *);
+static void search_cb(GtkWidget *, PidginLogViewer *);
+static void destroy_cb(PidginLogViewer *, gint, log_viewer_hash_t *);
static void log_row_activated_cb(GtkTreeView *, GtkTreePath *, GtkTreeViewColumn *);
static void delete_log_cleanup_cb(log_delete_callback_data *);
static void pidgin_log_delete_log_cb(GObject *, GAsyncResult *, gpointer);
@@ -109,17 +137,16 @@ static void log_menu_callback_data_free(
static void remove_delete_log_window(void *);
static void log_delete_log_cb(GtkWidget *, log_menu_callback_data *);
static void log_menu_callback_data_free(log_menu_callback_data *);
-static void log_show_popup_menu(GtkWidget *, GdkEventButton *, log_menu_callback_data *);
-static gboolean log_button_press_cb(GtkWidget *, GdkEventButton *, PidginLogViewerEx *);
-static gboolean log_popup_menu_cb(GtkWidget *, PidginLogViewerEx *);
+static void log_show_popup_menu(GdkEventButton *, log_menu_callback_data *);
+static gboolean log_button_press_cb(GtkTreeView *, GdkEventButton *, PidginLogViewer *);
+static gboolean log_popup_menu_cb(GtkTreeView *, PidginLogViewer *);
static gboolean search_find_cb(gpointer);
static void pidgin_log_read_cb(GObject *, GAsyncResult *, gpointer);
-static void log_select_cb(GtkTreeSelection *, PidginLogViewerEx *);
-static void populate_log_tree(PidginLogViewerEx *);
-static PidginLogViewerEx *display_log_viewer_nonblocking(log_viewer_hash_t *,
+static void log_select_cb(GtkTreeSelection *, PidginLogViewer *);
+static void populate_log_tree(PidginLogViewer *);
+static PidginLogViewer *pidgin_log_viewer_new(log_viewer_hash_t *,
const gchar *, GtkWidget *, gboolean);
-static void insert_log_viewer_log(PidginLogViewerEx *, PurpleLog *);
-static void append_log_viewer_logs(PidginLogViewerEx *, GList *);
+static void insert_log_viewer_log(PidginLogViewer *, PurpleLog *);
static void pidgin_log_done_cb(_pidgin_log_data *);
static void pidgin_log_viewer_update_list_bar(_pidgin_log_data *);
static void pidgin_log_viewer_update_search_bar(_pidgin_log_data *);
@@ -128,14 +155,19 @@ static void pidgin_log_system_list_cb(GO
static void pidgin_log_system_list_cb(GObject *, GAsyncResult *, gpointer);
+G_LOCK_DEFINE(log_viewers);
+G_LOCK_DEFINE(syslog_viewer);
+
+
static GHashTable *log_viewers = NULL;
-static PidginLogViewerEx *syslog_viewer = NULL;
+static PidginLogViewer *syslog_viewer = NULL;
+
static void
pidgin_log_data_free(_pidgin_log_data *data)
{
if (data->destroy_handler_id > 0)
- g_signal_handler_disconnect(data->log_viewer->lv->window,
+ g_signal_handler_disconnect(GTK_WINDOW(data->log_viewer),
data->destroy_handler_id);
g_free(data);
@@ -148,46 +180,67 @@ pidgin_window_destroy_cb(_pidgin_log_dat
data->is_window_open = FALSE;
}
-static void
-pidgin_log_viewer_ex_set_read_cancel(PidginLogViewerEx *lv_ex, GCancellable *cancel)
+void
+pidgin_log_viewer_set_read_cancel(PidginLogViewer *lv, GCancellable *cancel)
{
- if (lv_ex->read_cancel != NULL) {
- g_cancellable_cancel(lv_ex->read_cancel);
- g_object_unref(lv_ex->read_cancel);
+ PidginLogViewerPrivate *priv;
+
+ g_return_if_fail(PIDGIN_IS_LOG_VIEWER(lv));
+ g_return_if_fail(cancel == NULL || G_IS_CANCELLABLE(cancel));
+
+ priv = PIDGIN_LOG_VIEWER_GET_PRIVATE(lv);
+
+ if (priv->read_cancel != NULL) {
+ g_cancellable_cancel(priv->read_cancel);
+ g_object_unref(priv->read_cancel);
}
if (cancel != NULL)
g_object_ref(cancel);
- lv_ex->read_cancel = cancel;
+ priv->read_cancel = cancel;
}
-static void
-pidgin_log_viewer_ex_set_search_cancel(PidginLogViewerEx *lv_ex, GCancellable *cancel)
+void
+pidgin_log_viewer_set_search_cancel(PidginLogViewer *lv, GCancellable *cancel)
{
- if (lv_ex->search_cancel != NULL) {
- g_cancellable_cancel(lv_ex->search_cancel);
- g_object_unref(lv_ex->search_cancel);
+ PidginLogViewerPrivate *priv;
+
+ g_return_if_fail(PIDGIN_IS_LOG_VIEWER(lv));
+ g_return_if_fail(cancel == NULL || G_IS_CANCELLABLE(cancel));
+
+ priv = PIDGIN_LOG_VIEWER_GET_PRIVATE(lv);
+
+ if (priv->search_cancel != NULL) {
+ g_cancellable_cancel(priv->search_cancel);
+ g_object_unref(priv->search_cancel);
}
if (cancel != NULL)
g_object_ref(cancel);
- lv_ex->search_cancel = cancel;
+ priv->search_cancel = cancel;
}
-static void
-pidgin_log_viewer_ex_set_list_cancel(PidginLogViewerEx *lv_ex, GCancellable *cancel)
+void
+pidgin_log_viewer_set_list_cancel(PidginLogViewer *lv, GCancellable *cancel)
{
- if (lv_ex->list_cancel != NULL) {
- g_cancellable_cancel(lv_ex->list_cancel);
- g_object_unref(lv_ex->list_cancel);
+ PidginLogViewerPrivate *priv;
+
+ g_return_if_fail(PIDGIN_IS_LOG_VIEWER(lv));
+ g_return_if_fail(cancel == NULL || G_IS_CANCELLABLE(cancel));
+
+ priv = PIDGIN_LOG_VIEWER_GET_PRIVATE(lv);
+
+ if (priv->list_cancel != NULL) {
+ g_cancellable_cancel(priv->list_cancel);
+ g_object_unref(priv->list_cancel);
}
if (cancel != NULL)
g_object_ref(cancel);
- lv_ex->list_cancel = cancel;
+ priv->list_cancel = cancel;
}
static guint
@@ -211,7 +264,7 @@ log_viewer_equal(gconstpointer y, gconst
if (a->contact != NULL) {
if (b->contact != NULL)
- return (a->contact == b->contact);
+ return a->contact == b->contact;
else
return FALSE;
} else if (b->contact != NULL)
@@ -226,10 +279,10 @@ static void
}
static void
-select_first_log(PidginLogViewerEx *lv_ex)
+select_first_log(PidginLogViewer *lv)
{
- PidginLogViewer *lv = lv_ex->lv;
- GtkTreeModel *model = GTK_TREE_MODEL(lv->treestore);
+ PidginLogViewerPrivate *priv = PIDGIN_LOG_VIEWER_GET_PRIVATE(lv);
+ GtkTreeModel *model = GTK_TREE_MODEL(priv->treestore);
GtkTreeIter iter, it;
GtkTreePath *path;
@@ -239,11 +292,11 @@ select_first_log(PidginLogViewerEx *lv_e
path = gtk_tree_model_get_path(model, &iter);
if (gtk_tree_model_iter_children(model, &it, &iter)) {
- gtk_tree_view_expand_row(GTK_TREE_VIEW(lv->treeview), path, TRUE);
+ gtk_tree_view_expand_row(GTK_TREE_VIEW(priv->treeview), path, TRUE);
path = gtk_tree_model_get_path(model, &it);
}
- gtk_tree_selection_select_path(gtk_tree_view_get_selection(GTK_TREE_VIEW(lv->treeview)), path);
+ gtk_tree_selection_select_path(gtk_tree_view_get_selection(GTK_TREE_VIEW(priv->treeview)), path);
gtk_tree_path_free(path);
}
@@ -264,12 +317,13 @@ pidgin_log_search_done_cb(_pidgin_log_da
pidgin_log_search_done_cb(_pidgin_log_data *pidgin_log_data)
{
if (pidgin_log_data->is_window_open) {
- PidginLogViewerEx *lv_ex = pidgin_log_data->log_viewer;
+ PidginLogViewer *lv = pidgin_log_data->log_viewer;
+ PidginLogViewerPrivate *priv = PIDGIN_LOG_VIEWER_GET_PRIVATE(lv);
- if (!lv_ex->selected)
- select_first_log(lv_ex);
+ if (!priv->selected)
+ select_first_log(lv);
- gtk_widget_hide(lv_ex->search_bar);
+ gtk_widget_hide(priv->search_bar);
}
pidgin_log_data_free(pidgin_log_data);
@@ -278,136 +332,123 @@ pidgin_log_search_cb(GObject *object, GA
static void
pidgin_log_search_cb(GObject *object, GAsyncResult *res, gpointer userdata)
{
- _pidgin_search_callback_data *callback_data = userdata;
- _pidgin_log_data *pidgin_log_data = callback_data->log_data;
- PurpleLog *log = callback_data->log;
- GError *err = NULL;
+ _pidgin_log_data *pidgin_log_data = userdata;
+ PurpleLog *log = PURPLE_LOG(object);
+ GError *error = NULL;
gchar *text;
- text = purple_log_read_finish(log, res, NULL, &err);
+ text = purple_log_read_finish(log, res, NULL, &error);
pidgin_log_data->count--;
if (text == NULL) {
- if (err->code != G_IO_ERROR_CANCELLED)
- purple_debug_error("gtklog", "Error reading file during search: %s\n", err->message);
+ if (error->code != G_IO_ERROR_CANCELLED)
+ purple_debug_error("gtklog", "Error reading file during search: %s\n",
+ error->message);
} else if (pidgin_log_data->is_window_open) {
- PidginLogViewer *lv = pidgin_log_data->log_viewer->lv;
+ PidginLogViewer *lv = pidgin_log_data->log_viewer;
+ GtkTreeStore *treestore = pidgin_log_viewer_get_tree_store(lv);
GtkTreeIter iter;
+ const gchar *search = pidgin_log_viewer_get_search_string(lv);
- if (*text && purple_strcasestr(text, lv->search)) {
- gtk_tree_store_append(lv->treestore, &iter, NULL);
- gtk_tree_store_set(lv->treestore, &iter, 0, log_get_date(log), 1, log, -1);
+ if (*text && purple_strcasestr(text, search)) {
+ gtk_tree_store_append(treestore, &iter, NULL);
+ gtk_tree_store_set(treestore, &iter, 0, log_get_date(log), 1, log, -1);
}
}
- g_clear_error(&err);
+ g_clear_error(&error);
pidgin_log_viewer_update_search_bar(pidgin_log_data);
if (pidgin_log_data->count < 1)
pidgin_log_search_done_cb(pidgin_log_data);
-
- g_free(callback_data);
}
static void
-search_cb(GtkWidget *button, PidginLogViewerEx *lv_ex)
+search_cb(GtkWidget *button, PidginLogViewer *lv)
{
_pidgin_log_data *pidgin_log_data;
- PidginLogViewer *lv = lv_ex->lv;
- GtkIMHtml *imhtml;
+ GtkIMHtml *imhtml = GTK_IMHTML(pidgin_log_viewer_get_text_area(lv));
+ GtkTreeStore *treestore = pidgin_log_viewer_get_tree_store(lv);
+ GtkWidget *bar, *entry;
GCancellable *cancel;
GList *logs;
- const gchar *search_term;
+ const gchar *search_term, *old_search;
guint length;
- search_term = gtk_entry_get_text(GTK_ENTRY(lv->entry));
- imhtml = GTK_IMHTML(lv->imhtml);
+ entry = pidgin_log_viewer_get_entry(lv);
+ search_term = gtk_entry_get_text(GTK_ENTRY(entry));
if (!(*search_term)) {
/* reset the tree */
- pidgin_log_viewer_ex_set_search_cancel(lv_ex, NULL);
+ pidgin_log_viewer_set_search_cancel(lv, NULL);
- gtk_tree_store_clear(lv->treestore);
- populate_log_tree(lv_ex);
+ gtk_tree_store_clear(treestore);
+ populate_log_tree(lv);
- g_free(lv->search);
- lv->search = NULL;
+ pidgin_log_viewer_set_search_string(lv, NULL);
gtk_imhtml_search_clear(imhtml);
- select_first_log(lv_ex);
+ select_first_log(lv);
return;
}
- if (lv->search != NULL && !strcmp(lv->search, search_term)) {
+ old_search = pidgin_log_viewer_get_search_string(lv);
+
+ if (old_search != NULL && !strcmp(old_search, search_term)) {
/* Searching for the same term acts as "Find Next" */
- gtk_imhtml_search_find(imhtml, lv->search);
+ gtk_imhtml_search_find(imhtml, old_search);
return;
}
- length = g_list_length(lv->logs);
+ logs = pidgin_log_viewer_get_logs(lv);
+ length = g_list_length(logs);
if (length < 1)
return;
- g_free(lv->search);
- lv->search = g_strdup(search_term);
-
- gtk_tree_store_clear(lv->treestore);
+ pidgin_log_viewer_set_search_string(lv, search_term);
+ gtk_tree_store_clear(treestore);
gtk_imhtml_clear(imhtml);
- lv_ex->selected = FALSE;
+ pidgin_log_viewer_set_selected(lv, FALSE);
pidgin_log_data = g_new0(_pidgin_log_data, 1);
pidgin_log_data->is_window_open = TRUE;
- pidgin_log_data->log_viewer = lv_ex;
+ pidgin_log_data->log_viewer = lv;
pidgin_log_data->count = pidgin_log_data->total = length;
- pidgin_log_data->destroy_handler_id = g_signal_connect_swapped(lv->window,
+ pidgin_log_data->destroy_handler_id = g_signal_connect_swapped(GTK_WINDOW(lv),
"destroy", G_CALLBACK(pidgin_window_destroy_cb), pidgin_log_data);
- gtk_widget_show(lv_ex->search_bar);
- gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(lv_ex->search_bar), 0.0);
+ bar = pidgin_log_viewer_get_search_bar(lv);
+ gtk_widget_show(bar);
+ gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(bar), 0.0);
cancel = g_cancellable_new();
- pidgin_log_viewer_ex_set_search_cancel(lv_ex, cancel);
+ pidgin_log_viewer_set_search_cancel(lv, cancel);
- for (logs = lv->logs; logs != NULL; logs = g_list_next(logs)) {
- _pidgin_search_callback_data *callback_data;
- PurpleLog *log = logs->data;
+ for ( ; logs != NULL; logs = g_list_next(logs))
+ purple_log_read_async(logs->data, G_PRIORITY_DEFAULT_IDLE, cancel,
+ pidgin_log_search_cb, pidgin_log_data);
- callback_data = g_new0(_pidgin_search_callback_data, 1);
- callback_data->log_data = pidgin_log_data;
- callback_data->log = log;
-
- purple_log_read_async(log, G_PRIORITY_DEFAULT_IDLE, cancel,
- pidgin_log_search_cb, callback_data);
- }
-
g_object_unref(cancel);
}
static void
-destroy_cb(GtkWidget *w, gint resp, log_viewer_hash_t *ht)
+destroy_cb(PidginLogViewer *lv, gint resp, log_viewer_hash_t *ht)
{
- PidginLogViewerEx *lv_ex = syslog_viewer;
- PidginLogViewer *lv;
-
#ifdef G_OS_WIN32
if (resp == GTK_RESPONSE_HELP) {
GtkTreeSelection *sel;
GtkTreeIter iter;
- GtkTreeModel *model;
+ GtkTreeModel *model = GTK_TREE_MODEL(pidgin_log_viewer_get_tree_store(lv));
+ GtkWidget *view = pidgin_log_viewer_get_tree_view(lv);
PurpleLog *log = NULL;
gchar *logdir;
- if (ht != NULL)
- lv_ex = g_hash_table_lookup(log_viewers, ht);
+ sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(view));
- lv = lv_ex->lv;
- model = GTK_TREE_MODEL(lv->treestore);
- sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(lv->treeview));
-
if (gtk_tree_selection_get_selected(sel, &model, &iter))
gtk_tree_model_get(model, &iter, 1, &log, -1);
@@ -425,40 +466,18 @@ destroy_cb(GtkWidget *w, gint resp, log_
#endif
if (ht != NULL) {
- lv_ex = g_hash_table_lookup(log_viewers, ht);
+ G_LOCK(log_viewers);
+ lv = g_hash_table_lookup(log_viewers, ht);
g_hash_table_remove(log_viewers, ht);
+ G_UNLOCK(log_viewers);
g_free(ht->buddyname);
g_free(ht);
- } else
+ } else {
+ G_LOCK(syslog_viewer);
syslog_viewer = NULL;
-
- lv = lv_ex->lv;
-
- purple_request_close_with_handle(lv);
-
- g_list_foreach(lv->logs, (GFunc) g_object_unref, NULL);
- g_list_free(lv->logs);
- g_free(lv->search);
- g_free(lv);
-
- if (lv_ex->read_cancel != NULL) {
- g_cancellable_cancel(lv_ex->read_cancel);
- g_object_unref(lv_ex->read_cancel);
+ G_UNLOCK(syslog_viewer);
}
-
- if (lv_ex->search_cancel != NULL) {
- g_cancellable_cancel(lv_ex->search_cancel);
- g_object_unref(lv_ex->search_cancel);
- }
-
- if (lv_ex->list_cancel != NULL) {
- g_cancellable_cancel(lv_ex->list_cancel);
- g_object_unref(lv_ex->list_cancel);
- }
-
- g_free(lv_ex);
- gtk_widget_destroy(w);
}
static void
@@ -474,7 +493,7 @@ delete_log_cleanup_cb(log_delete_callbac
delete_log_cleanup_cb(log_delete_callback_data *data)
{
if (data->destroy_handler_id > 0)
- g_signal_handler_disconnect(data->log_data->log_viewer->lv->window,
+ g_signal_handler_disconnect(GTK_WINDOW(data->log_data->log_viewer),
data->destroy_handler_id);
pidgin_log_data_free(data->log_data);
@@ -497,7 +516,8 @@ pidgin_log_delete_log_cb(GObject *object
purple_notify_error(NULL, NULL, "Log Deletion Failed",
err->message);
else {
- GtkTreeStore *treestore = temp->log_data->log_viewer->lv->treestore;
+ PidginLogViewer *lv = temp->log_data->log_viewer;
+ GtkTreeStore *treestore = pidgin_log_viewer_get_tree_store(lv);
GtkTreeIter *iter = temp->iter;
GtkTreePath *path = gtk_tree_model_get_path(GTK_TREE_MODEL(treestore), iter);
gboolean first = !gtk_tree_path_prev(path);
@@ -535,7 +555,7 @@ log_delete_log_cb(GtkWidget *menuitem, l
log_delete_log_cb(GtkWidget *menuitem, log_menu_callback_data *data)
{
log_delete_callback_data *data2;
- PidginLogViewerEx *lv_ex = data->log_data->log_viewer;
+ PidginLogViewer *lv = data->log_data->log_viewer;
PurpleBuddy *buddy;
PurpleChat *chat;
PurpleLog *log = data->log_data->log;
@@ -590,7 +610,7 @@ log_delete_log_cb(GtkWidget *menuitem, l
*(data2->iter) = *(data->iter);
data2->log_data->count++;
- handle = purple_request_action(lv_ex, NULL, _("Delete Log?"), str, 0,
+ handle = purple_request_action(lv, NULL, _("Delete Log?"), str, 0,
NULL, NULL, NULL, data2, 2,
_("Delete"), delete_log_cb,
_("Cancel"), delete_log_cleanup_cb);
@@ -598,7 +618,7 @@ log_delete_log_cb(GtkWidget *menuitem, l
g_free(str);
/* Close the dialog window when the log viewer is closed */
- data2->destroy_handler_id = g_signal_connect_swapped(lv_ex->lv->window,
+ data2->destroy_handler_id = g_signal_connect_swapped(lv,
"destroy", G_CALLBACK(remove_delete_log_window), handle);
}
@@ -617,10 +637,10 @@ static void
}
static void
-log_show_popup_menu(GtkWidget *treeview, GdkEventButton *event, log_menu_callback_data *data)
+log_show_popup_menu(GdkEventButton *event, log_menu_callback_data *data)
{
_pidgin_log_data *pidgin_log_data = data->log_data;
- PidginLogViewer *lv = pidgin_log_data->log_viewer->lv;
+ PidginLogViewer *lv = pidgin_log_data->log_viewer;
GtkWidget *menu, *menuitem;
menu = gtk_menu_new();
@@ -637,7 +657,7 @@ log_show_popup_menu(GtkWidget *treeview,
pidgin_log_data->count = 1;
pidgin_log_data->is_window_open = TRUE;
- pidgin_log_data->destroy_handler_id = g_signal_connect_swapped(lv->window,
+ pidgin_log_data->destroy_handler_id = g_signal_connect_swapped(lv,
"destroy", G_CALLBACK(pidgin_window_destroy_cb), pidgin_log_data);
gtk_menu_popup(GTK_MENU(menu), NULL, NULL, data->func, NULL,
@@ -646,23 +666,23 @@ static gboolean
}
static gboolean
-log_button_press_cb(GtkWidget *treeview, GdkEventButton *event, PidginLogViewerEx *lv_ex)
+log_button_press_cb(GtkTreeView *treeview, GdkEventButton *event, PidginLogViewer *lv)
{
if (event->type == GDK_BUTTON_PRESS && event->button == 3) {
log_menu_callback_data *data;
- GtkTreeModel *model = GTK_TREE_MODEL(lv_ex->lv->treestore);
+ GtkTreeModel *model = GTK_TREE_MODEL(pidgin_log_viewer_get_tree_store(lv));
GtkTreeSelection *selection;
GtkTreePath *path;
GtkTreeIter *iter;
PurpleLog *log;
- if (!gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(treeview), event->x, event->y,
+ if (!gtk_tree_view_get_path_at_pos(treeview, event->x, event->y,
&path, NULL, NULL, NULL))
return FALSE;
iter = g_new(GtkTreeIter, 1);
gtk_tree_model_get_iter(model, iter, path);
- selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview));
+ selection = gtk_tree_view_get_selection(treeview);
gtk_tree_selection_select_iter(selection, iter);
gtk_tree_model_get(model, iter, 1, &log, -1);
gtk_tree_path_free(path);
@@ -674,12 +694,12 @@ log_button_press_cb(GtkWidget *treeview,
data = g_new(log_menu_callback_data, 1);
data->log_data = g_new0(_pidgin_log_data, 1);
- data->log_data->log_viewer = lv_ex;
+ data->log_data->log_viewer = lv;
data->log_data->log = log;
data->func = NULL;
data->iter = iter;
- log_show_popup_menu(treeview, event, data);
+ log_show_popup_menu(event, data);
return TRUE;
}
@@ -688,23 +708,22 @@ static gboolean
}
static gboolean
-log_popup_menu_cb(GtkWidget *treeview, PidginLogViewerEx *lv_ex)
+log_popup_menu_cb(GtkTreeView *treeview, PidginLogViewer *lv)
{
log_menu_callback_data *data;
- PidginLogViewer *lv = lv_ex->lv;
GtkTreeSelection *sel;
GtkTreeIter *iter;
PurpleLog *log;
iter = g_new(GtkTreeIter, 1);
- sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(lv->treeview));
+ sel = gtk_tree_view_get_selection(treeview);
if (!gtk_tree_selection_get_selected(sel, NULL, iter)) {
g_free(iter);
return FALSE;
}
- gtk_tree_model_get(GTK_TREE_MODEL(lv->treestore), iter, NODE_COLUMN, &log, -1);
+ gtk_tree_model_get(GTK_TREE_MODEL(pidgin_log_viewer_get_tree_store(lv)), iter, NODE_COLUMN, &log, -1);
if (log == NULL) {
g_free(iter);
@@ -713,12 +732,12 @@ log_popup_menu_cb(GtkWidget *treeview, P
data = g_new(log_menu_callback_data, 1);
data->log_data = g_new0(_pidgin_log_data, 1);
- data->log_data->log_viewer = lv_ex;
+ data->log_data->log_viewer = lv;
data->log_data->log = log;
data->func = pidgin_treeview_popup_menu_position_func;
data->iter = iter;
- log_show_popup_menu(treeview, NULL, data);
+ log_show_popup_menu(NULL, data);
return TRUE;
}
@@ -729,9 +748,11 @@ search_find_cb(gpointer userdata)
_pidgin_log_data *pidgin_log_data = userdata;
if (pidgin_log_data->is_window_open) {
- PidginLogViewer *lv = pidgin_log_data->log_viewer->lv;
+ PidginLogViewer *lv = pidgin_log_data->log_viewer;
+ GtkIMHtml *imhtml = GTK_IMHTML(pidgin_log_viewer_get_text_area(lv));
+ const gchar *search = pidgin_log_viewer_get_search_string(lv);
- gtk_imhtml_search_find(GTK_IMHTML(lv->imhtml), lv->search);
+ gtk_imhtml_search_find(imhtml, search);
}
pidgin_log_data_free(pidgin_log_data);
@@ -746,28 +767,32 @@ pidgin_log_read_cb(GObject *object, GAsy
if (pidgin_log_data->is_window_open) {
PurpleLog *log = pidgin_log_data->log;
- PidginLogViewerEx *lv_ex = pidgin_log_data->log_viewer;
- PidginLogViewer *lv = lv_ex->lv;
- GtkIMHtml *imhtml = GTK_IMHTML(lv->imhtml);
- GError *err = NULL;
+ PurpleLogReadFlags flags;
+ PidginLogViewer *lv = pidgin_log_data->log_viewer;
+ GtkIMHtml *imhtml = GTK_IMHTML(pidgin_log_viewer_get_text_area(lv));
+ GError *error = NULL;
+ const gchar *search = pidgin_log_viewer_get_search_string(lv);
gchar *text;
- text = purple_log_read_finish(log, res, &lv->flags, &err);
+ text = purple_log_read_finish(log, res, &flags, &error);
if (text == NULL) {
- if (err->code == G_IO_ERROR_CANCELLED) {
+ if (error->code == G_IO_ERROR_CANCELLED) {
pidgin_log_data_free(pidgin_log_data);
- g_clear_error(&err);
+ g_clear_error(&error);
return;
}
- text = err->message;
+ text = error->message;
}
#if GTK_CHECK_VERSION(2, 20, 0)
- gtk_widget_show(lv->imhtml);
- gtk_widget_hide(lv_ex->spinner);
+ {
+ PidginLogViewerPrivate *priv = PIDGIN_LOG_VIEWER_GET_PRIVATE(lv);
+ gtk_widget_show(priv->imhtml);
+ gtk_widget_hide(priv->spinner);
+ }
#endif
gtk_imhtml_clear(imhtml);
@@ -779,35 +804,34 @@ pidgin_log_read_cb(GObject *object, GAsy
//gtk_imhtml_append_text is a time killer in loading logs, annoyingly
gtk_imhtml_append_text(imhtml, text,
GTK_IMHTML_NO_COMMENTS | GTK_IMHTML_NO_TITLE | GTK_IMHTML_NO_SCROLL |
- (lv->flags & PURPLE_LOG_READ_NO_NEWLINE ? GTK_IMHTML_NO_NEWLINE : 0));
+ (flags & PURPLE_LOG_READ_NO_NEWLINE ? GTK_IMHTML_NO_NEWLINE : 0));
/* If we have something in the search bar, scroll to it in the current log */
- if (lv->search != NULL) {
+ if (search != NULL) {
gtk_imhtml_search_clear(imhtml);
g_idle_add(search_find_cb, pidgin_log_data);
} else
pidgin_log_data_free(pidgin_log_data);
- g_clear_error(&err);
+ g_clear_error(&error);
} else
pidgin_log_data_free(pidgin_log_data);
}
static void
-log_select_cb(GtkTreeSelection *sel, PidginLogViewerEx *lv_ex)
+log_select_cb(GtkTreeSelection *sel, PidginLogViewer *lv)
{
_pidgin_log_data *pidgin_log_data;
- PidginLogViewer *lv = lv_ex->lv;
PurpleLog *log = NULL;
PurpleLogChatType chat_type;
- GtkTreeModel *model = GTK_TREE_MODEL(lv->treestore);
+ GtkTreeModel *model = GTK_TREE_MODEL(pidgin_log_viewer_get_tree_store(lv));
GtkTreeIter iter;
GCancellable *cancel;
if (!gtk_tree_selection_get_selected(sel, &model, &iter))
return;
- lv_ex->selected = TRUE;
+ pidgin_log_viewer_set_selected(lv, TRUE);
gtk_tree_model_get(model, &iter, 1, &log, -1);
if (log == NULL)
@@ -816,6 +840,7 @@ log_select_cb(GtkTreeSelection *sel, Pid
chat_type = purple_log_get_chat_type(log);
if (chat_type != PURPLE_LOG_SYSTEM) {
+ GtkWidget *label = pidgin_log_viewer_get_label(lv);
const gchar *log_name = purple_log_get_name(log);
gchar *title;
@@ -826,24 +851,27 @@ log_select_cb(GtkTreeSelection *sel, Pid
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(lv->label), title);
+ gtk_label_set_markup(GTK_LABEL(label), title);
g_free(title);
}
pidgin_log_data = g_new0(_pidgin_log_data, 1);
pidgin_log_data->is_window_open = TRUE;
pidgin_log_data->count = 1;
- pidgin_log_data->log_viewer = lv_ex;
+ pidgin_log_data->log_viewer = lv;
pidgin_log_data->log = log;
- pidgin_log_data->destroy_handler_id = g_signal_connect_swapped(lv->window,
+ pidgin_log_data->destroy_handler_id = g_signal_connect_swapped(lv,
"destroy", G_CALLBACK(pidgin_window_destroy_cb), pidgin_log_data);
cancel = g_cancellable_new();
- pidgin_log_viewer_ex_set_read_cancel(lv_ex, cancel);
+ pidgin_log_viewer_set_read_cancel(lv, cancel);
#if GTK_CHECK_VERSION(2, 20, 0)
- gtk_widget_hide(lv->imhtml);
- gtk_widget_show(lv_ex->spinner);
+ {
+ PidginLogViewerPrivate *priv = PIDGIN_LOG_VIEWER_GET_PRIVATE(lv);
+ gtk_widget_hide(priv->imhtml);
+ gtk_widget_show(priv->spinner);
+ }
#endif
purple_log_read_async(log, G_PRIORITY_DEFAULT, cancel,
@@ -859,19 +887,19 @@ static void
* For now, I'll just make it a flat list.
*/
static void
-populate_log_tree(PidginLogViewerEx *lv_ex)
+populate_log_tree(PidginLogViewer *lv)
/* Logs are made from trees in real life.
This is a tree made from logs */
{
- PidginLogViewer *lv = lv_ex->lv;
GtkTreeIter toplevel, child;
- GList *logs;
+ GtkTreeStore *treestore = pidgin_log_viewer_get_tree_store(lv);
+ GList *logs = pidgin_log_viewer_get_logs(lv);
const gchar *month;
gchar prev_top_month[30] = "";
- gtk_tree_store_clear(lv->treestore);
+ gtk_tree_store_clear(treestore);
- for (logs = lv->logs; logs != NULL; logs = g_list_next(logs)) {
+ for ( ; logs != NULL; logs = g_list_next(logs)) {
PurpleLog *log = logs->data;
const struct tm *log_tm;
time_t log_time;
@@ -882,176 +910,46 @@ populate_log_tree(PidginLogViewerEx *lv_
if (strcmp(month, prev_top_month) != 0) {
/* top level */
- gtk_tree_store_append(lv->treestore, &toplevel, NULL);
- gtk_tree_store_set(lv->treestore, &toplevel, 0, month, 1, NULL, 2, log_tm, -1);
+ gtk_tree_store_append(treestore, &toplevel, NULL);
+ gtk_tree_store_set(treestore, &toplevel, 0, month, 1, NULL, 2, log_tm, -1);
strncpy(prev_top_month, month, sizeof(prev_top_month));
}
/* sub */
- gtk_tree_store_append(lv->treestore, &child, &toplevel);
- gtk_tree_store_set(lv->treestore, &child,
+ gtk_tree_store_append(treestore, &child, &toplevel);
+ gtk_tree_store_set(treestore, &child,
0, log_get_date(log), 1, log, -1);
}
}
-static PidginLogViewerEx *
-display_log_viewer_nonblocking(log_viewer_hash_t *ht,
- const gchar *title, GtkWidget *icon, gboolean need_log_size)
+PidginLogViewer *
+pidgin_log_viewer_new(log_viewer_hash_t *ht, const gchar *title,
+ GtkWidget *icon, gboolean need_log_size)
{
- PidginLogViewerEx *lv_ex;
PidginLogViewer *lv;
- GtkCellRenderer *rend;
- GtkTreeViewColumn *col;
- GtkTreeSelection *sel;
- GtkWidget *title_box, *pane, *sw, *frame, *find_button, *content_area, *vbox, *hbox;
- gchar *text;
- lv_ex = g_new0(PidginLogViewerEx, 1);
- lv = g_new0(PidginLogViewer, 1);
- lv->logs = NULL;
- lv_ex->lv = lv;
+ lv = g_object_new(PIDGIN_TYPE_LOG_VIEWER,
+ "title", title,
+ "viewer-type", ht != NULL ? ht->chat_type : PURPLE_LOG_SYSTEM,
+ "icon", icon,
+ "need-log-size", need_log_size,
+ NULL);
+ /* Store the information to later prevent duplicate windows from popping up */
if (ht != NULL) {
- lv_ex->type = ht->type;
- g_hash_table_insert(log_viewers, ht, lv_ex);
- } else
- lv_ex->type = PURPLE_LOG_SYSTEM;
-
- /* Window ***********/
- lv->window = gtk_dialog_new_with_buttons(title, NULL, 0,
- GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, NULL);
- content_area = gtk_dialog_get_content_area(GTK_DIALOG(lv->window));
-
-#ifdef G_OS_WIN32
- /* Steal the "HELP" response and use it to trigger browsing to the logs folder */
- gtk_dialog_add_button(GTK_DIALOG(lv->window), _("_Browse logs folder"), GTK_RESPONSE_HELP);
-#endif
- gtk_container_set_border_width (GTK_CONTAINER(lv->window), PIDGIN_HIG_BOX_SPACE);
- gtk_dialog_set_has_separator(GTK_DIALOG(lv->window), FALSE);
- gtk_box_set_spacing(GTK_BOX(content_area), 0);
- g_signal_connect(lv->window, "response", G_CALLBACK(destroy_cb), ht);
- gtk_window_set_role(GTK_WINDOW(lv->window), "log_viewer");
-
- /* Icon *************/
- if (icon != NULL) {
- title_box = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
- gtk_container_set_border_width(GTK_CONTAINER(title_box), PIDGIN_HIG_BOX_SPACE);
- gtk_box_pack_start(GTK_BOX(content_area), title_box, FALSE, FALSE, 0);
-
- gtk_box_pack_start(GTK_BOX(title_box), icon, FALSE, FALSE, 0);
- } else
- title_box = content_area;
-
- /* Label ************/
- lv->label = gtk_label_new(NULL);
-
- text = g_strdup_printf("<span size='larger' weight='bold'>%s</span>", title);
-
- gtk_label_set_markup(GTK_LABEL(lv->label), text);
- gtk_misc_set_alignment(GTK_MISC(lv->label), 0, 0);
- gtk_box_pack_start(GTK_BOX(title_box), lv->label, FALSE, FALSE, 0);
- g_free(text);
-
- /* Pane *************/
- pane = gtk_hpaned_new();
- gtk_container_set_border_width(GTK_CONTAINER(pane), PIDGIN_HIG_BOX_SPACE);
- gtk_box_pack_start(GTK_BOX(content_area), 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(3, G_TYPE_STRING, G_TYPE_OBJECT, PURPLE_TYPE_STRUCT_TM);
- lv->treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(lv->treestore));
- gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(lv->treeview), FALSE);
- pidgin_set_accessible_label(lv->treeview, lv->label);
- g_object_unref(lv->treestore);
-
- rend = gtk_cell_renderer_text_new();
- 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_container_add (GTK_CONTAINER (sw), lv->treeview);
-
- sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(lv->treeview));
-
- g_signal_connect(sel, "changed", G_CALLBACK (log_select_cb), lv_ex);
- g_signal_connect(lv->treeview, "row-activated", G_CALLBACK(log_row_activated_cb), NULL);
- g_signal_connect(lv->treeview, "button-press-event", G_CALLBACK(log_button_press_cb), lv_ex);
- g_signal_connect(lv->treeview, "popup-menu", G_CALLBACK(log_popup_menu_cb), lv_ex);
-
- /* Log size ************/
- if (need_log_size) {
- lv->size_label = gtk_label_new(NULL);
- lv_ex->size = 0;
-
- text = g_strdup_printf("<span weight='bold'>%s</span> %s", _("Total log size:"), _("calculating..."));
- gtk_label_set_markup(GTK_LABEL(lv->size_label), text);
- g_free(text);
-
- gtk_misc_set_alignment(GTK_MISC(lv->size_label), 0, 0);
- gtk_box_pack_end(GTK_BOX(content_area), lv->size_label, FALSE, FALSE, 0);
+ G_LOCK(log_viewers);
+ g_hash_table_insert(log_viewers, ht, g_object_ref(lv));
+ G_UNLOCK(log_viewers);
}
- /* A fancy little box ************/
- vbox = gtk_vbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
- gtk_paned_add2(GTK_PANED(pane), vbox);
+ g_signal_connect(lv, "response", G_CALLBACK(destroy_cb), ht);
- /* Viewer ************/
- frame = pidgin_create_imhtml(FALSE, &lv->imhtml, NULL, NULL);
- gtk_widget_set_name(lv->imhtml, "pidgin_log_imhtml");
- gtk_widget_set_size_request(lv->imhtml, 320, 200);
- gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0);
- gtk_widget_show(frame);
-
-#if GTK_CHECK_VERSION(2, 20, 0)
- lv_ex->spinner = gtk_spinner_new();
- gtk_spinner_start(GTK_SPINNER(lv_ex->spinner));
- gtk_box_pack_start(GTK_BOX(vbox), lv_ex->spinner, TRUE, FALSE, 0);
-#endif
-
- /* Search box **********/
- hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
- gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
-
- lv->entry = gtk_entry_new();
- find_button = gtk_button_new_from_stock(GTK_STOCK_FIND);
-
- gtk_box_pack_start(GTK_BOX(hbox), lv->entry, TRUE, TRUE, 0);
- gtk_box_pack_start(GTK_BOX(hbox), find_button, FALSE, FALSE, 0);
-
- g_signal_connect(lv->entry, "activate", G_CALLBACK(search_cb), lv_ex);
- g_signal_connect(find_button, "clicked", G_CALLBACK(search_cb), lv_ex);
-
- /* Progress bars **********/
- lv_ex->list_bar = gtk_progress_bar_new();
- lv_ex->search_bar = gtk_progress_bar_new();
-
- gtk_progress_bar_set_text(GTK_PROGRESS_BAR(lv_ex->list_bar), _("Waiting for logs ..."));
- gtk_progress_bar_set_text(GTK_PROGRESS_BAR(lv_ex->search_bar), _("Searching logs ..."));
-
- gtk_box_pack_start(GTK_BOX(vbox), lv_ex->list_bar, FALSE, FALSE, 0);
- gtk_box_pack_start(GTK_BOX(vbox), lv_ex->search_bar, FALSE, FALSE, 0);
-
- gtk_widget_show_all(lv->window);
- gtk_widget_hide(lv_ex->search_bar);
-#if GTK_CHECK_VERSION(2, 20, 0)
- gtk_widget_hide(lv_ex->spinner);
-#endif
-
- lv_ex->read_cancel = NULL;
- lv_ex->search_cancel = NULL;
- lv_ex->list_cancel = NULL;
-
- lv_ex->selected = FALSE;
-
- return lv_ex;
+ return lv;
}
static void
-insert_log_viewer_log(PidginLogViewerEx *lv_ex, PurpleLog *log)
+insert_log_viewer_log(PidginLogViewer *lv, PurpleLog *log)
{
/* It runs about twice as quick to insert the logs, rather than re-populate the entire tree
@@ -1059,18 +957,14 @@ insert_log_viewer_log(PidginLogViewerEx
populate_log_tree if the tree format is to ever be changed
*/
PurpleLog *child_log;
- GtkTreeModel *model;
- GtkTreeStore *store;
+ GtkTreeStore *store = pidgin_log_viewer_get_tree_store(lv);
+ GtkTreeModel *model = GTK_TREE_MODEL(store);
GtkTreeIter insertion, inserted_month, month_iter, child;
const gchar *month;
- const struct tm *log_tm;
+ const struct tm *log_tm = purple_log_get_tm(log);
struct tm *tm;
- time_t log_time;
+ time_t log_time = purple_log_get_time(log);
- store = lv_ex->lv->treestore;
- model = GTK_TREE_MODEL(store);
- log_tm = purple_log_get_tm(log);
- log_time = purple_log_get_time(log);
month = purple_utf8_strftime(_("%B %Y"), log_tm != NULL ? log_tm : localtime(&log_time));
if (!gtk_tree_model_get_iter_first(model, &month_iter)) {
@@ -1137,55 +1031,57 @@ insert_log_viewer_log(PidginLogViewerEx
gtk_tree_store_set(store, &insertion, 0, log_get_date(log), 1, log, -1);
}
-static void
-append_log_viewer_logs(PidginLogViewerEx *lv_ex, GList *logs)
+void
+pidgin_log_viewer_add_logs(PidginLogViewer *lv, GList *logs)
{
- PidginLogViewer *lv = lv_ex->lv;
+ PidginLogViewerPrivate *priv = PIDGIN_LOG_VIEWER_GET_PRIVATE(lv);
GList *list;
logs = g_list_sort(logs, purple_log_compare);
for (list = logs; list != NULL; list = g_list_next(list))
- insert_log_viewer_log(lv_ex, list->data);
+ insert_log_viewer_log(lv, list->data);
- lv->logs = g_list_concat(lv->logs, logs);
- lv->logs = g_list_sort(lv->logs, purple_log_compare);
+ priv->logs = g_list_concat(priv->logs, logs);
+ priv->logs = g_list_sort(priv->logs, purple_log_compare);
}
static void
pidgin_log_done_cb(_pidgin_log_data *pidgin_log_data)
{
if (pidgin_log_data->is_window_open) {
- PidginLogViewerEx *lv_ex = pidgin_log_data->log_viewer;
- PidginLogViewer *lv = lv_ex->lv;
+ PidginLogViewer *lv = pidgin_log_data->log_viewer;
+ GtkWidget *bar = pidgin_log_viewer_get_list_bar(lv);
+ GList *logs = pidgin_log_viewer_get_logs(lv);
- gtk_widget_hide(lv_ex->list_bar);
+ gtk_widget_hide(bar);
- if (lv->logs == NULL) {
+ if (logs == NULL) {
/* No logs were found. */
+ PurpleLogChatType type = pidgin_log_viewer_get_viewer_type(lv);
const gchar *log_preferences = NULL;
- if (lv_ex->type == PURPLE_LOG_SYSTEM) {
+ if (type == PURPLE_LOG_SYSTEM) {
if (!purple_prefs_get_bool("/purple/logging/log_system"))
log_preferences = _("System events will only be logged if "
"the \"Log all status changes to system log\" "
"preference is enabled.");
- } else if (lv_ex->type == PURPLE_LOG_IM) {
+ } else if (type == PURPLE_LOG_IM) {
if (!purple_prefs_get_bool("/purple/logging/log_ims"))
log_preferences = _("Instant messages will only be logged "
"if the \"Log all instant messages\" "
"preference is enabled.");
- } else if (lv_ex->type == PURPLE_LOG_CHAT) {
+ } else if (type == PURPLE_LOG_CHAT) {
if (!purple_prefs_get_bool("/purple/logging/log_chats"))
log_preferences = _("Chats will only be logged if the "
"\"Log all chats\" preference is enabled.");
}
- purple_notify_info(NULL, gtk_window_get_title(GTK_WINDOW(lv->window)),
+ purple_notify_info(NULL, gtk_window_get_title(GTK_WINDOW(lv)),
_("No logs were found"), log_preferences);
- gtk_dialog_response(GTK_DIALOG(lv->window), GTK_RESPONSE_CLOSE);
- } else if (!lv_ex->selected)
- select_first_log(lv_ex);
+ gtk_dialog_response(GTK_DIALOG(lv), GTK_RESPONSE_CLOSE);
+ } else if (!pidgin_log_viewer_is_selected(lv))
+ select_first_log(lv);
}
pidgin_log_data_free(pidgin_log_data);
@@ -1195,12 +1091,13 @@ pidgin_log_viewer_update_list_bar(_pidgi
pidgin_log_viewer_update_list_bar(_pidgin_log_data *pidgin_log_data)
{
if (pidgin_log_data->is_window_open) {
- PidginLogViewerEx *lv_ex = pidgin_log_data->log_viewer;
+ PidginLogViewer *lv = pidgin_log_data->log_viewer;
+ GtkWidget *bar = pidgin_log_viewer_get_list_bar(lv);
gdouble fraction;
fraction = (gdouble) pidgin_log_data->count /
(gdouble) pidgin_log_data->total;
- gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(lv_ex->list_bar), 1.0 - fraction);
+ gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(bar), 1.0 - fraction);
}
}
@@ -1208,12 +1105,13 @@ pidgin_log_viewer_update_search_bar(_pid
pidgin_log_viewer_update_search_bar(_pidgin_log_data *pidgin_log_data)
{
if (pidgin_log_data->is_window_open) {
- PidginLogViewerEx *lv_ex = pidgin_log_data->log_viewer;
+ PidginLogViewer *lv = pidgin_log_data->log_viewer;
+ GtkWidget *bar = pidgin_log_viewer_get_search_bar(lv);
gdouble fraction;
fraction = (gdouble) pidgin_log_data->count /
(gdouble) pidgin_log_data->total;
- gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(lv_ex->search_bar), 1.0 - fraction);
+ gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(bar), 1.0 - fraction);
}
}
@@ -1232,23 +1130,22 @@ pidgin_log_size_cb(GObject *object, GAsy
purple_debug_error("gtklog", "Error getting total log size: %s\n",
error->message);
} else if (pidgin_log_data->is_window_open) {
- PidginLogViewerEx *lv_ex = pidgin_log_data->log_viewer;
+ PidginLogViewer *lv = pidgin_log_data->log_viewer;
gchar *sz_txt, *text;
gsize total;
- total = lv_ex->size;
+ total = pidgin_log_viewer_get_total_size(lv);
total += log_size;
+ pidgin_log_viewer_set_total_size(lv, total);
- lv_ex->size = total;
+ // sz_txt = purple_str_size_to_units(total);
+ // text = g_strdup_printf("<span weight='bold'>%s</span> %s",
+ // _("Total log size:"), sz_txt);
- sz_txt = purple_str_size_to_units(total);
- text = g_strdup_printf("<span weight='bold'>%s</span> %s",
- _("Total log size:"), sz_txt);
+ // gtk_label_set_markup(GTK_LABEL(lv_ex->lv->size_label), text);
- gtk_label_set_markup(GTK_LABEL(lv_ex->lv->size_label), text);
-
- g_free(sz_txt);
- g_free(text);
+ // g_free(sz_txt);
+ // g_free(text);
}
g_clear_error(&error);
@@ -1272,7 +1169,7 @@ pidgin_log_list_cb(GObject *object, GAsy
if (error != NULL && error->code != G_IO_ERROR_CANCELLED)
purple_debug_error("gtklog", "Error getting logs: %s\n", error->message);
} else if (pidgin_log_data->is_window_open)
- append_log_viewer_logs(pidgin_log_data->log_viewer, list);
+ pidgin_log_viewer_add_logs(pidgin_log_data->log_viewer, list);
g_clear_error(&error);
pidgin_log_viewer_update_search_bar(pidgin_log_data);
@@ -1295,7 +1192,7 @@ pidgin_log_system_list_cb(GObject *objec
if (error != NULL && error->code != G_IO_ERROR_CANCELLED)
purple_debug_error("gtklog", "Error getting system logs: %s\n", error->message);
} else if (pidgin_log_data->is_window_open)
- append_log_viewer_logs(pidgin_log_data->log_viewer, list);
+ pidgin_log_viewer_add_logs(pidgin_log_data->log_viewer, list);
g_clear_error(&error);
pidgin_log_viewer_update_search_bar(pidgin_log_data);
@@ -1305,18 +1202,18 @@ void
}
void
-pidgin_log_show(PurpleLogChatType type, const gchar *buddyname, PurpleAccount *account)
+pidgin_log_show(PurpleLogChatType chat_type, const gchar *buddyname, PurpleAccount *account)
{
log_viewer_hash_t *ht;
_pidgin_log_data *pidgin_log_data;
- PidginLogViewerEx *lv_ex;
+ PidginLogViewer *lv;
GdkPixbuf *prpl_icon;
GtkWidget *image;
GCancellable *cancel;
const gchar *name;
gchar *title;
- if (type != PURPLE_LOG_IM) {
+ if (chat_type != PURPLE_LOG_IM) {
g_return_if_fail(account != NULL);
g_return_if_fail(buddyname != NULL);
}
@@ -1324,22 +1221,24 @@ pidgin_log_show(PurpleLogChatType type,
name = buddyname;
ht = g_new0(log_viewer_hash_t, 1);
- ht->type = type;
+ ht->chat_type = chat_type;
ht->buddyname = g_strdup(buddyname);
ht->account = account;
- if (log_viewers == NULL)
- log_viewers = g_hash_table_new(log_viewer_hash, log_viewer_equal);
- else if ((lv_ex = g_hash_table_lookup(log_viewers, ht)) != NULL) {
- gtk_window_present(GTK_WINDOW(lv_ex->lv->window));
+ G_LOCK(log_viewers);
+ lv = g_hash_table_lookup(log_viewers, ht);
+ G_UNLOCK(log_viewers);
+ if (lv != NULL) {
+ gtk_window_present(GTK_WINDOW(lv));
+
g_free(ht->buddyname);
g_free(ht);
return;
}
- if (type == PURPLE_LOG_CHAT) {
+ if (chat_type == PURPLE_LOG_CHAT) {
PurpleChat *chat = purple_blist_find_chat(account, buddyname);
if (chat != NULL)
@@ -1361,23 +1260,22 @@ pidgin_log_show(PurpleLogChatType type,
prpl_icon = pidgin_create_prpl_icon(account, PIDGIN_PRPL_ICON_MEDIUM);
image = gtk_image_new_from_pixbuf(prpl_icon);
- lv_ex = pidgin_log_data->log_viewer =
- display_log_viewer_nonblocking(ht, title, image, TRUE);
-
+ lv = pidgin_log_data->log_viewer = pidgin_log_viewer_new(ht, title, image, TRUE);
g_free(title);
+ gtk_widget_show(GTK_WIDGET(lv));
if (prpl_icon != NULL)
g_object_unref(prpl_icon);
- pidgin_log_data->destroy_handler_id = g_signal_connect_swapped(lv_ex->lv->window,
+ pidgin_log_data->destroy_handler_id = g_signal_connect_swapped(GTK_WINDOW(lv),
"destroy", G_CALLBACK(pidgin_window_destroy_cb), pidgin_log_data);
cancel = g_cancellable_new();
- pidgin_log_viewer_ex_set_list_cancel(lv_ex, cancel);
+ pidgin_log_viewer_set_list_cancel(lv, cancel);
- purple_logs_get_logs_async(type, buddyname, account, G_PRIORITY_DEFAULT,
+ purple_logs_get_logs_async(chat_type, buddyname, account, G_PRIORITY_DEFAULT,
cancel, pidgin_log_list_cb, pidgin_log_data);
- purple_logs_get_total_size_async(type, buddyname, account, G_PRIORITY_DEFAULT,
+ purple_logs_get_total_size_async(chat_type, buddyname, account, G_PRIORITY_DEFAULT,
cancel, pidgin_log_size_cb, pidgin_log_data);
g_object_unref(cancel);
@@ -1389,7 +1287,7 @@ pidgin_log_show_contact(PurpleContact *c
log_viewer_hash_t *ht;
_pidgin_log_data *pidgin_log_data;
PurpleBlistNode *child;
- PidginLogViewerEx *lv_ex;
+ PidginLogViewer *lv;
GCancellable *cancel;
GdkPixbuf *pixbuf;
GtkWidget *image;
@@ -1399,14 +1297,16 @@ pidgin_log_show_contact(PurpleContact *c
g_return_if_fail(contact != NULL);
ht = g_new0(log_viewer_hash_t, 1);
- ht->type = PURPLE_LOG_IM;
+ ht->chat_type = PURPLE_LOG_IM;
ht->contact = contact;
- if (log_viewers == NULL) {
- log_viewers = g_hash_table_new(log_viewer_hash, log_viewer_equal);
- } else if ((lv_ex = g_hash_table_lookup(log_viewers, ht)) != NULL) {
- gtk_window_present(GTK_WINDOW(lv_ex->lv->window));
+ G_LOCK(log_viewers);
+ lv = g_hash_table_lookup(log_viewers, ht);
+ G_UNLOCK(log_viewers);
+ if (lv != NULL) {
+ gtk_window_present(GTK_WINDOW(lv));
+
g_free(ht);
return;
@@ -1443,16 +1343,16 @@ pidgin_log_show_contact(PurpleContact *c
pidgin_log_data->is_window_open = TRUE;
title = g_strdup_printf(_("Conversations with %s"), name);
- lv_ex = pidgin_log_data->log_viewer = display_log_viewer_nonblocking(ht, title, image, TRUE);
-
+ lv = pidgin_log_data->log_viewer = pidgin_log_viewer_new(ht, title, image, TRUE);
g_free(title);
+ gtk_widget_show(GTK_WIDGET(lv));
- pidgin_log_data->destroy_handler_id = g_signal_connect_swapped(lv_ex->lv->window,
+ pidgin_log_data->destroy_handler_id = g_signal_connect_swapped(GTK_WINDOW(lv),
"destroy", G_CALLBACK(pidgin_window_destroy_cb), pidgin_log_data);
pidgin_log_data->count = pidgin_log_data->total = 0;
cancel = g_cancellable_new();
- pidgin_log_viewer_ex_set_list_cancel(lv_ex, cancel);
+ pidgin_log_viewer_set_list_cancel(lv, cancel);
for (child = contact->node.child; child != NULL; child = child->next) {
if (PURPLE_BLIST_NODE_IS_BUDDY(child)) {
@@ -1475,25 +1375,31 @@ pidgin_syslog_show(void)
{
_pidgin_log_data *pidgin_log_data;
PurpleAccount *account;
+ PidginLogViewer *lv;
GCancellable *cancel;
GList *accounts;
- if (syslog_viewer != NULL) {
- gtk_window_present(GTK_WINDOW(syslog_viewer->lv->window));
+ G_LOCK(syslog_viewer);
+ lv = syslog_viewer;
+ G_UNLOCK(syslog_viewer);
+
+ if (lv != NULL) {
+ gtk_window_present(GTK_WINDOW(lv));
return;
}
pidgin_log_data = g_new0(_pidgin_log_data, 1);
pidgin_log_data->is_window_open = TRUE;
- syslog_viewer = pidgin_log_data->log_viewer = display_log_viewer_nonblocking(NULL,
+ lv = pidgin_log_data->log_viewer = pidgin_log_viewer_new(NULL,
_("System Log"), NULL, FALSE);
+ gtk_widget_show(GTK_WIDGET(lv));
- pidgin_log_data->destroy_handler_id = g_signal_connect_swapped(syslog_viewer->lv->window,
+ pidgin_log_data->destroy_handler_id = g_signal_connect_swapped(GTK_WINDOW(lv),
"destroy", G_CALLBACK(pidgin_window_destroy_cb), pidgin_log_data);
cancel = g_cancellable_new();
- pidgin_log_viewer_ex_set_list_cancel(syslog_viewer, cancel);
+ pidgin_log_viewer_set_list_cancel(lv, cancel);
pidgin_log_data->count = pidgin_log_data->total = 0;
for(accounts = purple_accounts_get_all(); accounts != NULL; accounts = g_list_next(accounts)) {
@@ -1509,8 +1415,211 @@ pidgin_syslog_show(void)
}
g_object_unref(cancel);
+
+ G_LOCK(syslog_viewer);
+ syslog_viewer = lv;
+ G_UNLOCK(syslog_viewer);
}
+static void
+pidgin_log_viewer_finalize(GObject *object)
+{
+ PidginLogViewer *lv = PIDGIN_LOG_VIEWER(object);
+ // PidginLogViewerPrivate *priv = PIDGIN_LOG_VIEWER_GET_PRIVATE(lv);
+
+ purple_request_close_with_handle(lv);
+
+ // Move these into a finalize function
+ pidgin_log_viewer_clear_logs(lv);
+ pidgin_log_viewer_set_search_string(lv, NULL);
+ pidgin_log_viewer_set_read_cancel(lv, NULL);
+ pidgin_log_viewer_set_search_cancel(lv, NULL);
+ pidgin_log_viewer_set_list_cancel(lv, NULL);
+ g_object_unref(lv);
+
+ // gtk_widget_destroy(w);
+}
+
+static void
+pidgin_log_viewer_class_init(PidginLogViewerClass *class)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS(class);
+
+ gobject_class->set_property = pidgin_log_viewer_set_property;
+ gobject_class->get_property = pidgin_log_viewer_get_property;
+ gobject_class->finalize = pidgin_log_viewer_finalize;
+
+ // properties[PROP_LOG_CHAT_TYPE] =
+ // g_param_spec_enum("chat-type",
+ // "Chat Type",
+ // "The chat type of the log",
+ // PURPLE_TYPE_LOG_CHAT_TYPE,
+ // PURPLE_LOG_SYSTEM,
+ // G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
+
+ // Icon : Constructor only
+
+ // g_object_class_install_property(gobject_class,
+ // PROP_LOG_CHAT_TYPE,
+ // properties[PROP_LOG_CHAT_TYPE]);
+
+ g_type_class_add_private(gobject_class, sizeof(PidginLogViewerPrivate));
+}
+
+static void
+pidgin_log_viewer_init(PidginLogViewer *lv)
+{
+ PidginLogViewerPrivate *priv = PIDGIN_LOG_VIEWER_GET_PRIVATE(lv);
+
+ priv->logs = NULL;
+ priv->size = 0;
+ priv->read_cancel = NULL;
+ priv->search_cancel = NULL;
+ priv->list_cancel = NULL;
+ priv->selected = FALSE;
+}
+
+static void
+pidgin_log_viewer_constructed(PidginLogViewer *lv)
+{
+ PidginLogViewerPrivate *priv = PIDGIN_LOG_VIEWER_GET_PRIVATE(lv);
+ GtkCellRenderer *rend;
+ GtkTreeViewColumn *col;
+ GtkTreeSelection *sel;
+ GtkDialog *dialog = GTK_DIALOG(lv);
+ GtkWindow *window = GTK_WINDOW(lv);
+ GtkWidget *icon, *title_box, *pane, *sw, *frame;
+ GtkWidget *find_button, *content_area, *vbox, *hbox;
+ gchar *text;
+ gboolean need_log_size;
+
+ /* Window ***********/
+ gtk_dialog_add_buttons(dialog, GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, NULL);
+#ifdef G_OS_WIN32
+ /* Steal the "HELP" response and use it to trigger browsing to the logs folder */
+ gtk_dialog_add_button(dialog, _("_Browse logs folder"), GTK_RESPONSE_HELP);
+#endif
+
+ gtk_container_set_border_width (GTK_CONTAINER(lv), PIDGIN_HIG_BOX_SPACE);
+ gtk_dialog_set_has_separator(dialog, FALSE);
+ content_area = gtk_dialog_get_content_area(dialog);
+ gtk_box_set_spacing(GTK_BOX(content_area), 0);
+ gtk_window_set_role(window, "log_viewer");
+
+ /* Icon *************/
+ icon = pidgin_log_viewer_get_icon(lv);
+
+ if (icon != NULL) {
+ title_box = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
+ gtk_container_set_border_width(GTK_CONTAINER(title_box), PIDGIN_HIG_BOX_SPACE);
+ gtk_box_pack_start(GTK_BOX(content_area), title_box, FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(title_box), icon, FALSE, FALSE, 0);
+ } else
+ title_box = content_area;
+
+ /* Label ************/
+ priv->label = gtk_label_new(NULL);
+
+ text = g_strdup_printf("<span size='larger' weight='bold'>%s</span>",
+ gtk_window_get_title(window));
+
+ gtk_label_set_markup(GTK_LABEL(priv->label), text);
+ gtk_misc_set_alignment(GTK_MISC(priv->label), 0, 0);
+ gtk_box_pack_start(GTK_BOX(title_box), priv->label, FALSE, FALSE, 0);
+ g_free(text);
+
+ /* Pane *************/
+ pane = gtk_hpaned_new();
+ gtk_container_set_border_width(GTK_CONTAINER(pane), PIDGIN_HIG_BOX_SPACE);
+ gtk_box_pack_start(GTK_BOX(content_area), 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);
+
+ priv->treestore = gtk_tree_store_new(3, G_TYPE_STRING, G_TYPE_OBJECT, PURPLE_TYPE_STRUCT_TM);
+ priv->treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(priv->treestore));
+ gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(priv->treeview), FALSE);
+ pidgin_set_accessible_label(priv->treeview, priv->label);
+ // g_object_unref(priv->treestore);
+
+ rend = gtk_cell_renderer_text_new();
+ col = gtk_tree_view_column_new_with_attributes ("time", rend, "markup", 0, NULL);
+ gtk_tree_view_append_column (GTK_TREE_VIEW(priv->treeview), col);
+ gtk_container_add (GTK_CONTAINER (sw), priv->treeview);
+
+ sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(priv->treeview));
+
+ g_signal_connect(sel, "changed", G_CALLBACK (log_select_cb), lv);
+ g_signal_connect(priv->treeview, "row-activated", G_CALLBACK(log_row_activated_cb), NULL);
+ g_signal_connect(priv->treeview, "button-press-event", G_CALLBACK(log_button_press_cb), lv);
+ g_signal_connect(priv->treeview, "popup-menu", G_CALLBACK(log_popup_menu_cb), lv);
+
+ /* Log size ************/
+ need_log_size = pidgin_log_viewer_get_need_log_size(lv);
+
+ if (need_log_size) {
+ priv->size_label = gtk_label_new(NULL);
+
+ text = g_strdup_printf("<span weight='bold'>%s</span> %s",
+ _("Total log size:"), _("calculating..."));
+ gtk_label_set_markup(GTK_LABEL(priv->size_label), text);
+ g_free(text);
+
+ gtk_misc_set_alignment(GTK_MISC(priv->size_label), 0, 0);
+ gtk_box_pack_end(GTK_BOX(content_area), priv->size_label, FALSE, FALSE, 0);
+ }
+
+ /* A fancy little box ************/
+ vbox = gtk_vbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
+ gtk_paned_add2(GTK_PANED(pane), vbox);
+
+ /* Viewer ************/
+ frame = pidgin_create_imhtml(FALSE, &priv->imhtml, NULL, NULL);
+ gtk_widget_set_name(priv->imhtml, "pidgin_log_imhtml");
+ gtk_widget_set_size_request(priv->imhtml, 320, 200);
+ gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0);
+ gtk_widget_show(frame);
+
+#if GTK_CHECK_VERSION(2, 20, 0)
+ priv->spinner = gtk_spinner_new();
+ gtk_spinner_start(GTK_SPINNER(priv->spinner));
+ gtk_box_pack_start(GTK_BOX(vbox), priv->spinner, TRUE, FALSE, 0);
+#endif
+
+ /* Search box **********/
+ hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
+ gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
+
+ priv->entry = gtk_entry_new();
+ find_button = gtk_button_new_from_stock(GTK_STOCK_FIND);
+
+ gtk_box_pack_start(GTK_BOX(hbox), priv->entry, TRUE, TRUE, 0);
+ gtk_box_pack_start(GTK_BOX(hbox), find_button, FALSE, FALSE, 0);
+
+ g_signal_connect(priv->entry, "activate", G_CALLBACK(search_cb), lv);
+ g_signal_connect(find_button, "clicked", G_CALLBACK(search_cb), lv);
+
+ /* Progress bars **********/
+ priv->list_bar = gtk_progress_bar_new();
+ priv->search_bar = gtk_progress_bar_new();
+
+ gtk_progress_bar_set_text(GTK_PROGRESS_BAR(priv->list_bar), _("Waiting for logs ..."));
+ gtk_progress_bar_set_text(GTK_PROGRESS_BAR(priv->search_bar), _("Searching logs ..."));
+
+ gtk_box_pack_start(GTK_BOX(vbox), priv->list_bar, FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(vbox), priv->search_bar, FALSE, FALSE, 0);
+
+ gtk_widget_show_all(GTK_WIDGET(lv));
+ gtk_widget_hide(GTK_WIDGET(lv));
+ gtk_widget_hide(priv->search_bar);
+#if GTK_CHECK_VERSION(2, 20, 0)
+ gtk_widget_hide(priv->spinner);
+#endif
+}
+
/****************************************************************************
* GTK+ LOG SUBSYSTEM *******************************************************
****************************************************************************/
@@ -1528,6 +1637,11 @@ pidgin_log_init(void)
{
void *handle = pidgin_log_get_handle();
+ G_LOCK(log_viewers);
+ // Is the ht stuff leaking?
+ log_viewers = g_hash_table_new_full(log_viewer_hash, log_viewer_equal, NULL, g_object_unref);
+ G_UNLOCK(log_viewers);
+
purple_signal_register(handle, "log-displaying",
purple_marshal_VOID__POINTER_POINTER,
NULL, 2,
@@ -1539,4 +1653,14 @@ pidgin_log_uninit(void)
pidgin_log_uninit(void)
{
purple_signals_unregister_by_instance(pidgin_log_get_handle());
+
+ if (log_viewers != NULL) {
+ g_hash_table_destroy(log_viewers);
+ log_viewers = NULL;
+ }
+
+ if (syslog_viewer != NULL) {
+ g_object_unref(syslog_viewer);
+ syslog_viewer = NULL;
+ }
}
============================================================
--- pidgin/gtklog.h 908b652405ccb703cfc5985446da0478f087fdab
+++ pidgin/gtklog.h 8a817ee7c6fc35869d32dbf88ee7887ad33fcc1e
@@ -27,13 +27,25 @@
#ifndef _PIDGINLOG_H_
#define _PIDGINLOG_H_
+#include <glib-object.h>
+
#include "pidgin.h"
#include "log.h"
+#include "account.h"
-#include "account.h"
+G_BEGIN_DECLS
+#define PIDGIN_TYPE_LOG_VIEWER (pidgin_log_viewer_get_type())
+#define PIDGIN_LOG_VIEWER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), PIDGIN_TYPE_LOG_VIEWER, PidginLogViewer))
+#define PIDGIN_LOG_VIEWER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), PIDGIN_TYPE_LOG_VIEWER, PidginLogViewerClass))
+#define PIDGIN_IS_LOG_VIEWER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), PIDGIN_TYPE_LOG_VIEWER))
+#define PIDGIN_IS_LOG_VIEWER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE((k), PIDGIN_TYPE_LOG_VIEWER))
+#define PIDGIN_LOG_VIEWER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS((o), PIDGIN_TYPE_LOG_VIEWER, PidginLogViewerClass))
+
/** @copydoc _PidginLogViewer */
typedef struct _PidginLogViewer PidginLogViewer;
+/** @copydoc _PidginLogViewerClass */
+typedef struct _PidginLogViewerClass PidginLogViewerClass;
/********************************************************
* DATA STRUCTURES **************************************
@@ -43,26 +55,79 @@ struct _PidginLogViewer {
* A GTK+ Log Viewer. You can look at logs with it.
*/
struct _PidginLogViewer {
- GList *logs; /**< The list of logs viewed in this viewer */
- GtkWidget *window; /**< The viewer's window */
- GtkTreeStore *treestore; /**< The treestore containing said logs */
- GtkWidget *treeview; /**< The treeview representing said treestore */
- GtkWidget *imhtml; /**< The imhtml to display said logs */
- GtkWidget *entry; /**< The search entry, in which search terms are entered */
- PurpleLogReadFlags flags; /**< The most recently used log read flags */
- gchar *search; /**< The string currently being searched for */
- GtkWidget *label; /**< The label at the top of the log viewer */
- GtkWidget *size_label; /**< The label with total log size */
+ GtkDialog parent_instance;
};
-G_BEGIN_DECLS
+// Should this extend something else? Like GtkObject or GtkDialog?
+struct _PidginLogViewerClass {
+ GtkDialogClass parent_class;
+ void (*_purple_reserved1)(void);
+ void (*_purple_reserved2)(void);
+ void (*_purple_reserved3)(void);
+ void (*_purple_reserved4)(void);
+};
+
+
+//
+GList *pidgin_log_viewer_get_logs(PidginLogViewer *lv);
+//
+GtkTreeStore *pidgin_log_viewer_get_tree_store(PidginLogViewer *lv);
+//
+GtkWidget *pidgin_log_viewer_get_tree_view(PidginLogViewer *lv);
+//
+GtkWidget *pidgin_log_viewer_get_text_area(PidginLogViewer *lv);
+//
+GtkWidget *pidgin_log_viewer_get_entry(PidginLogViewer *lv);
+//
+G_CONST_RETURN gchar *pidgin_log_viewer_get_search_string(PidginLogViewer *lv);
+// Better name?
+GtkWidget *pidgin_log_viewer_get_label(PidginLogViewer *lv);
+// Better name?
+GtkWidget *pidgin_log_viewer_get_size_label(PidginLogViewer *lv);
+//
+gssize pidgin_log_viewer_get_total_size(PidginLogViewer *lv);
+//
+GtkWidget *pidgin_log_viewer_get_list_bar(PidginLogViewer *lv);
+//
+GtkWidget *pidgin_log_viewer_get_search_bar(PidginLogViewer *lv);
+//
+GCancellable *pidgin_log_viewer_get_search_cancel(PidginLogViewer *lv);
+//
+GCancellable *pidgin_log_viewer_get_list_cancel(PidginLogViewer *lv);
+//
+GCancellable *pidgin_log_viewer_get_read_cancel(PidginLogViewer *lv);
+//
+gboolean pidgin_log_viewer_is_selected(PidginLogViewer *lv);
+//
+PurpleLogChatType pidgin_log_viewer_get_viewer_type(PidginLogViewer *lv);
+
+//
+void pidgin_log_viewer_clear_logs(PidginLogViewer *lv);
+//
+void pidgin_log_viewer_add_logs(PidginLogViewer *lv, GList *logs);
+//
+void pidgin_log_viewer_set_search_string(PidginLogViewer *lv, const gchar *string);
+//
+void pidgin_log_viewer_set_total_size(PidginLogViewer *lv, gssize total);
+//
+void pidgin_log_viewer_set_search_cancel(PidginLogViewer *lv, GCancellable *cancellable);
+//
+void pidgin_log_viewer_set_list_cancel(PidginLogViewer *lv, GCancellable *cancellable);
+//
+void pidgin_log_viewer_set_read_cancel(PidginLogViewer *lv, GCancellable *cancellable);
+//
+void pidgin_log_viewer_set_selected(PidginLogViewer *lv, gboolean selected);
+
+
/**************************************************************************/
/** @name Log Viewer Creators */
/**************************************************************************/
/*@{*/
+GType pidgin_log_viewer_get_type(void);
+
/**
* Displays the logs of a certain type for a buddy or chat on an account
*
More information about the Commits
mailing list