/soc/2015/igor.gajowiak/chatlog: 4e79be028d92: Implemented log i...

Igor Gajowiak <[email protected]>
Newsgroups gmane.comp.gnome.gaim.cvs
Message-ID <[email protected]>
Changeset: 4e79be028d92a4565da3a29de9a8d235f1d65c2e
Author:	 Igor Gajowiak <[email protected]>
Date:	 2015-08-08 20:47 +0200
Branch:	 default
URL: https://hg.pidgin.im/soc/2015/igor.gajowiak/chatlog/rev/4e79be028d92

Description:

Implemented log import UI.

diffstat:

 libpurple/genericlog.c |   18 ++-
 libpurple/genericlog.h |   15 ++-
 pidgin/gtkgenericlog.c |  268 ++++++++++++++++++++++++++++++++++++++++++++++--
 pidgin/gtkgenericlog.h |   17 +++
 4 files changed, 297 insertions(+), 21 deletions(-)

diffs (truncated from 420 to 300 lines):

diff --git a/libpurple/genericlog.c b/libpurple/genericlog.c
--- a/libpurple/genericlog.c
+++ b/libpurple/genericlog.c
@@ -26,7 +26,11 @@
 #define PURPLE_GENERICLOG_GET_PRIVATE(obj) \
 	(G_TYPE_INSTANCE_GET_PRIVATE((obj), PURPLE_TYPE_GENERICLOG, PurpleGenericLogPrivate))
 
-#define PURPLE_GENERICLOG_IMPORT_CHUNK_SIZE 500
+/* Defines how many messages should be imported in a single chunk */
+#define PURPLE_GENERICLOG_IMPORT_CHUNK_SIZE 200
+
+/* Defines how much time to wait between importing next chunk */
+#define PURPLE_GENERICLOG_IMPORT_TIMESLICE  20
 
 typedef struct
 {
@@ -53,6 +57,7 @@ typedef struct
 {
 	PurpleGenericLog *src_log;
 	PurpleGenericLog_OnImportFinished on_finished;
+	gpointer user_data;
 	void *export_state;
 	guint timer;
 	guint imported_messages_count;
@@ -353,7 +358,8 @@ run_import_iteration(gpointer unused)
 		uninit_import_state(import_state);
 
 		import_state->on_finished(status,
-			import_state->imported_messages_count);
+			import_state->imported_messages_count,
+			import_state->user_data);
 
 		g_free(import_state);
 		import_state = NULL;
@@ -380,7 +386,8 @@ run_import_iteration(gpointer unused)
 
 gboolean
 purple_genericlog_import_msgs(PurpleGenericLog *src_log,
-	PurpleGenericLog_OnImportFinished on_finished, GError **error)
+	PurpleGenericLog_OnImportFinished on_finished, gpointer user_data,
+	GError **error)
 {
 	if (!purple_genericlog_inuse) {
 		if (!error) return FALSE;
@@ -431,10 +438,11 @@ purple_genericlog_import_msgs(PurpleGene
 	import_state = g_new0(PurpleGenericLogImportState, 1);
 	import_state->src_log = src_log;
 	import_state->on_finished = on_finished;
+	import_state->user_data = user_data;
 	import_state->export_state = export_state;
 
-	import_state->timer = purple_timeout_add(1, run_import_iteration,
-		import_state);
+	import_state->timer = purple_timeout_add(PURPLE_GENERICLOG_IMPORT_TIMESLICE,
+		run_import_iteration, import_state);
 
 	return TRUE;
 }
diff --git a/libpurple/genericlog.h b/libpurple/genericlog.h
--- a/libpurple/genericlog.h
+++ b/libpurple/genericlog.h
@@ -140,7 +140,15 @@ struct _PurpleGenericLogClass
 	void (*reserved4)(void);
 };
 
-typedef void (*PurpleGenericLog_OnImportFinished)(gboolean, guint);
+/**
+ * PurpleGenericLog_OnImportFinished:
+ * @1: The status.
+ * @2: The number of imported messages.
+ * @3: The user data.
+ *
+ * Called after import had finished.
+ */
+typedef void (*PurpleGenericLog_OnImportFinished)(gboolean, guint, gpointer);
 
 #define PURPLE_GENERICLOG_DEFAULT "genericlog-sqlitelog"
 
@@ -185,7 +193,7 @@ purple_genericlog_get_name(const PurpleG
  * Returns: A #GList of elements of type #PurpleGenericLog.
  */
 GList*
-purple_genericlog_get_registered_logs();
+purple_genericlog_get_registered_logs(void);
 
 /**
  * purple_genericlog_find_by_id:
@@ -404,7 +412,8 @@ purple_genericlog_wipe_log_for_buddy(Pur
  */
 gboolean
 purple_genericlog_import_msgs(PurpleGenericLog *src_log,
-	PurpleGenericLog_OnImportFinished on_finished, GError **error);
+	PurpleGenericLog_OnImportFinished on_finished, gpointer user_data,
+	GError **error);
 
 /**************************************************************************/
 /* Error Codes                                                            */
diff --git a/pidgin/gtkgenericlog.c b/pidgin/gtkgenericlog.c
--- a/pidgin/gtkgenericlog.c
+++ b/pidgin/gtkgenericlog.c
@@ -34,6 +34,254 @@
 static PidginGenericLogViewer *generic_log_viewer = NULL;
 
 /******************************************************************************/
+/* Import window                                                              */
+/******************************************************************************/
+
+static const gchar * const  labels[] =
+{
+	"Importing   ",
+	"Importing.  ",
+	"Importing.. ",
+	"Importing..."
+};
+
+typedef enum
+{
+	LOGS_LIST_STORE_LOGID = 0,
+	LOGS_LIST_STORE_COLS  = 1,
+} LogsListStore;
+
+static GtkListStore *
+create_logs_store()
+{
+	/* Stores generic log ids */
+	return gtk_list_store_new(LOGS_LIST_STORE_COLS,
+		G_TYPE_STRING);
+}
+
+static void
+populate_logs_store(GtkListStore *store)
+{
+	g_assert(store);
+
+	gtk_list_store_clear(store);
+
+	PurpleGenericLog *inuse = purple_genericlog_get_inuse();
+
+	GList *logs = purple_genericlog_get_registered_logs();
+	for (; logs != NULL; logs = logs->next) {
+		PurpleGenericLog *log = PURPLE_GENERICLOG(logs->data);
+
+		if (log == inuse)
+			continue;
+
+		GtkTreeIter iter;
+		gtk_list_store_append(store, &iter);
+		gtk_list_store_set(store, &iter,
+			LOGS_LIST_STORE_LOGID, purple_genericlog_get_id(log), -1);
+	}
+}
+
+static GtkWidget *
+create_logs_combobox(GtkListStore *store)
+{
+	g_assert(store);
+
+	GtkWidget *combobox = gtk_combo_box_new_with_model(GTK_TREE_MODEL(store));
+
+	GtkCellRenderer *renderer = gtk_cell_renderer_text_new();
+	gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combobox), renderer, TRUE);
+	gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combobox), renderer,
+		"text", 0, NULL);
+
+	return combobox;
+}
+
+static gboolean
+start_import(PidginGenericLogViewer *viewer);
+
+static void
+update_sensitivity(PidginGenericLogViewer *viewer, gboolean sensitive)
+{
+	g_assert(viewer);
+
+	gtk_widget_set_sensitive(viewer->window, sensitive);
+	gtk_widget_set_sensitive(viewer->importer->import_button, sensitive);
+	gtk_widget_set_sensitive(viewer->importer->close_button, sensitive);
+}
+
+static void
+on_import_window_response(GtkWidget *widget, gint resp, gpointer data)
+{
+	g_assert(data);
+
+	PidginGenericLogViewer *viewer = (PidginGenericLogViewer*) data;
+
+	switch (resp) {
+		case GTK_RESPONSE_ACCEPT:
+		{
+			if (start_import(viewer)) {
+				/* Block log window until import is done */
+				update_sensitivity(viewer, FALSE);
+			}
+			return;
+		}
+		case GTK_RESPONSE_CLOSE:
+		{
+			gtk_widget_hide(viewer->importer->window);
+			return;
+		}
+	}
+
+	/* Not reachable */
+	g_assert(FALSE);
+}
+
+static GtkWidget *
+create_import_window(PidginGenericLogViewer *viewer,
+	GtkWindow *parent_window, GtkWidget **logs_combobox_res,
+	GtkListStore **logs_store_res, GtkWidget **status_label_res,
+	GtkWidget **import_button_res, GtkWidget **close_button_res)
+{
+	g_assert(viewer);
+	g_assert(parent_window);
+	g_assert(logs_combobox_res);
+	g_assert(logs_store_res);
+	g_assert(status_label_res);
+	g_assert(import_button_res);
+	g_assert(close_button_res);
+
+	GtkWidget *window = gtk_dialog_new();
+	gtk_window_set_title(GTK_WINDOW(window), "Import messages");
+	gtk_window_set_transient_for(GTK_WINDOW(window), parent_window);
+
+	GtkWidget *import_button = gtk_dialog_add_button(GTK_DIALOG(window),
+		"_Import", GTK_RESPONSE_ACCEPT);
+	GtkWidget *close_button = gtk_dialog_add_button(GTK_DIALOG(window),
+		"_Close", GTK_RESPONSE_CLOSE);
+
+	g_signal_connect(G_OBJECT(window), "response",
+		G_CALLBACK(on_import_window_response), viewer);
+
+	GtkListStore *logs_store = create_logs_store();
+	populate_logs_store(logs_store);
+	GtkWidget *logs_combobox = create_logs_combobox(logs_store);
+	gtk_combo_box_set_active(GTK_COMBO_BOX(logs_combobox), 0);
+	gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(window))),
+		logs_combobox, FALSE, FALSE, 0);
+
+	GtkWidget *status_label = gtk_label_new("");
+	gtk_box_pack_end(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(window))),
+		status_label, FALSE, FALSE, 0);
+
+	*logs_combobox_res = logs_combobox;
+	*logs_store_res = logs_store;
+	*status_label_res = status_label;
+	*import_button_res = import_button;
+	*close_button_res = close_button;
+
+	return window;
+}
+
+static PidginGenericLogImporter *
+create_log_importer(PidginGenericLogViewer *viewer)
+{
+	PidginGenericLogImporter *importer = g_new0(PidginGenericLogImporter, 1);
+
+	importer->iterator = 0;
+	importer->window = create_import_window(viewer, GTK_WINDOW(viewer->window),
+		&importer->logs_combobox, &importer->logs_store,
+		&importer->status_label, &importer->import_button,
+		&importer->close_button);
+
+	return importer;
+}
+
+static gboolean
+update_importer_label(gpointer data)
+{
+	g_assert(data);
+
+	PidginGenericLogImporter *importer = (PidginGenericLogImporter*) data;
+
+	importer->iterator = (importer->iterator + 1) %
+		(sizeof(labels) / sizeof(labels[0]));
+	gtk_label_set_markup(GTK_LABEL(importer->status_label),
+		labels[importer->iterator]);
+
+	return TRUE;
+}
+
+static void
+on_import_finished(gboolean status, guint msg_count, gpointer data)
+{
+	g_assert(data);
+
+	PidginGenericLogViewer *viewer = (PidginGenericLogViewer*) data;
+	PidginGenericLogImporter *importer = viewer->importer;
+
+	g_assert(importer);
+
+	purple_timeout_remove(importer->timer);
+	importer->iterator = 0;
+
+	const gchar *format = status ? "Import succeeded, imported %u messages\n"
+		: "Error occured during import, imported %u messages\n";
+
+	gchar *text = g_strdup_printf(format, msg_count);
+	gtk_label_set_markup(GTK_LABEL(importer->status_label), text);

_______________________________________________
Commits mailing list
[email protected]
https://pidgin.im/cgi-bin/mailman/listinfo/commits
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.