[latexila/wip/build-tools] Build tools: handle correctly several build views
- From: Sébastien Wilmet <swilmet src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [latexila/wip/build-tools] Build tools: handle correctly several build views
- Date: Mon, 6 Oct 2014 17:27:37 +0000 (UTC)
commit 8d6ce2bb2f6ceeae56ff0065d984cead464f8b40
Author: Sébastien Wilmet <swilmet gnome org>
Date: Mon Oct 6 15:38:40 2014 +0200
Build tools: handle correctly several build views
There can be several main windows, each with a build view.
Before, at most one task was supported per BuildTool and BuildJob, but
it doesn't work well with several build views (showing/hiding the
details worked only for the last task).
Now GTask is used more correctly, so a BuildTool and a BuildJob support
several tasks.
docs/reference/latexila-sections.txt | 3 +-
src/liblatexila/latexila-build-job.c | 302 +++++++++++++++++---------------
src/liblatexila/latexila-build-job.h | 2 -
src/liblatexila/latexila-build-tool.c | 265 ++++++++++++++++-------------
src/liblatexila/latexila-build-tool.h | 2 -
src/main_window_build_tools.vala | 9 +-
6 files changed, 310 insertions(+), 273 deletions(-)
---
diff --git a/docs/reference/latexila-sections.txt b/docs/reference/latexila-sections.txt
index c76bee2..fa84048 100644
--- a/docs/reference/latexila-sections.txt
+++ b/docs/reference/latexila-sections.txt
@@ -69,7 +69,6 @@ latexila_build_tool_get_description
latexila_build_tool_to_xml
latexila_build_tool_run_async
latexila_build_tool_run_finish
-latexila_build_tool_clear
<SUBSECTION Standard>
LATEXILA_BUILD_TOOL
LATEXILA_BUILD_TOOL_CLASS
@@ -91,7 +90,6 @@ latexila_build_job_clone
latexila_build_job_to_xml
latexila_build_job_run_async
latexila_build_job_run_finish
-latexila_build_job_clear
<SUBSECTION Standard>
LATEXILA_BUILD_JOB
LATEXILA_BUILD_JOB_CLASS
@@ -182,6 +180,7 @@ latexila_post_processor_all_output_get_type
<TITLE>LatexilaPostProcessorLatex</TITLE>
LatexilaPostProcessorLatex
latexila_post_processor_latex_new
+latexila_post_processor_latex_get_errors_count
<SUBSECTION Standard>
LATEXILA_IS_POST_PROCESSOR_LATEX
LATEXILA_IS_POST_PROCESSOR_LATEX_CLASS
diff --git a/src/liblatexila/latexila-build-job.c b/src/liblatexila/latexila-build-job.c
index 8daa601..0a9e314 100644
--- a/src/liblatexila/latexila-build-job.c
+++ b/src/liblatexila/latexila-build-job.c
@@ -39,9 +39,13 @@ struct _LatexilaBuildJobPrivate
{
gchar *command;
LatexilaPostProcessorType post_processor_type;
+ guint running_tasks_count;
+};
- /* Used for running the build job. */
- GTask *task;
+/* Used for running the build job. */
+typedef struct _TaskData TaskData;
+struct _TaskData
+{
GFile *file;
LatexilaBuildView *build_view;
GtkTreeIter job_title;
@@ -66,6 +70,26 @@ enum
G_DEFINE_TYPE_WITH_PRIVATE (LatexilaBuildJob, latexila_build_job, G_TYPE_OBJECT)
+static TaskData *
+task_data_new (void)
+{
+ return g_slice_new0 (TaskData);
+}
+
+static void
+task_data_free (TaskData *data)
+{
+ if (data != NULL)
+ {
+ g_clear_object (&data->file);
+ g_clear_object (&data->build_view);
+ g_clear_object (&data->post_processor);
+ g_clear_object (&data->post_processor_result);
+
+ g_slice_free (TaskData, data);
+ }
+}
+
static void
latexila_build_job_get_property (GObject *object,
guint prop_id,
@@ -99,7 +123,7 @@ latexila_build_job_set_property (GObject *object,
LatexilaBuildJob *build_job = LATEXILA_BUILD_JOB (object);
/* The build job can not be modified when it is running. */
- g_return_if_fail (build_job->priv->task == NULL);
+ g_return_if_fail (build_job->priv->running_tasks_count == 0);
switch (prop_id)
{
@@ -119,19 +143,6 @@ latexila_build_job_set_property (GObject *object,
}
static void
-latexila_build_job_dispose (GObject *object)
-{
- LatexilaBuildJob *build_job = LATEXILA_BUILD_JOB (object);
-
- g_clear_object (&build_job->priv->task);
- g_clear_object (&build_job->priv->file);
-
- latexila_build_job_clear (build_job);
-
- G_OBJECT_CLASS (latexila_build_job_parent_class)->dispose (object);
-}
-
-static void
latexila_build_job_finalize (GObject *object)
{
LatexilaBuildJob *build_job = LATEXILA_BUILD_JOB (object);
@@ -148,7 +159,6 @@ latexila_build_job_class_init (LatexilaBuildJobClass *klass)
object_class->get_property = latexila_build_job_get_property;
object_class->set_property = latexila_build_job_set_property;
- object_class->dispose = latexila_build_job_dispose;
object_class->finalize = latexila_build_job_finalize;
g_object_class_install_property (object_class,
@@ -174,9 +184,9 @@ latexila_build_job_class_init (LatexilaBuildJobClass *klass)
}
static void
-latexila_build_job_init (LatexilaBuildJob *self)
+latexila_build_job_init (LatexilaBuildJob *build_job)
{
- self->priv = latexila_build_job_get_instance_private (self);
+ build_job->priv = latexila_build_job_get_instance_private (build_job);
}
/**
@@ -226,10 +236,12 @@ latexila_build_job_to_xml (LatexilaBuildJob *build_job)
}
static gchar **
-get_command_argv (LatexilaBuildJob *build_job,
- gboolean for_printing,
- GError **error)
+get_command_argv (GTask *task,
+ gboolean for_printing,
+ GError **error)
{
+ LatexilaBuildJob *build_job = g_task_get_source_object (task);
+ TaskData *data = g_task_get_task_data (task);
gchar **argv;
gchar *base_filename;
gchar *base_shortname;
@@ -256,7 +268,7 @@ get_command_argv (LatexilaBuildJob *build_job,
}
/* Replace placeholders */
- base_filename = g_file_get_basename (build_job->priv->file);
+ base_filename = g_file_get_basename (data->file);
base_shortname = latexila_utils_get_shortname (base_filename);
for (i = 0; argv[i] != NULL; i++)
@@ -290,12 +302,12 @@ get_command_argv (LatexilaBuildJob *build_job,
}
static gchar *
-get_command_name (LatexilaBuildJob *build_job)
+get_command_name (GTask *task)
{
gchar **argv;
gchar *command_name;
- argv = get_command_argv (build_job, TRUE, NULL);
+ argv = get_command_argv (task, TRUE, NULL);
if (argv == NULL || argv[0] == NULL || argv[0][0] == '\0')
command_name = NULL;
@@ -307,29 +319,30 @@ get_command_name (LatexilaBuildJob *build_job)
}
static void
-display_error (LatexilaBuildJob *build_job,
- const gchar *message,
- GError *error)
+display_error (GTask *task,
+ const gchar *message,
+ GError *error)
{
+ TaskData *data = g_task_get_task_data (task);
LatexilaBuildMsg *build_msg;
g_assert (error != NULL);
- latexila_build_view_set_title_state (build_job->priv->build_view,
- &build_job->priv->job_title,
+ latexila_build_view_set_title_state (data->build_view,
+ &data->job_title,
LATEXILA_BUILD_STATE_FAILED);
build_msg = latexila_build_msg_new ();
build_msg->text = (gchar *) message;
build_msg->type = LATEXILA_BUILD_MSG_TYPE_ERROR;
- latexila_build_view_append_single_message (build_job->priv->build_view,
- &build_job->priv->job_title,
+ latexila_build_view_append_single_message (data->build_view,
+ &data->job_title,
build_msg);
build_msg->text = g_strdup (error->message);
build_msg->type = LATEXILA_BUILD_MSG_TYPE_INFO;
- latexila_build_view_append_single_message (build_job->priv->build_view,
- &build_job->priv->job_title,
+ latexila_build_view_append_single_message (data->build_view,
+ &data->job_title,
build_msg);
/* If the command doesn't seem to be installed, display a more understandable
@@ -338,15 +351,15 @@ display_error (LatexilaBuildJob *build_job,
if (error->domain == G_SPAWN_ERROR &&
error->code == G_SPAWN_ERROR_NOENT)
{
- gchar *command_name = get_command_name (build_job);
+ gchar *command_name = get_command_name (task);
if (command_name != NULL)
{
g_free (build_msg->text);
build_msg->text = g_strdup_printf (_("%s doesn't seem to be installed."), command_name);
- latexila_build_view_append_single_message (build_job->priv->build_view,
- &build_job->priv->job_title,
+ latexila_build_view_append_single_message (data->build_view,
+ &data->job_title,
build_msg);
g_free (command_name);
@@ -355,34 +368,37 @@ display_error (LatexilaBuildJob *build_job,
g_error_free (error);
latexila_build_msg_free (build_msg);
- g_task_return_boolean (build_job->priv->task, FALSE);
+ g_task_return_boolean (task, FALSE);
+ g_object_unref (task);
}
/* Returns TRUE on success. */
static gboolean
-display_command_line (LatexilaBuildJob *build_job)
+display_command_line (GTask *task)
{
+ LatexilaBuildJob *build_job = g_task_get_source_object (task);
+ TaskData *data = g_task_get_task_data (task);
gchar **argv;
gchar *command_line;
GError *error = NULL;
- argv = get_command_argv (build_job, TRUE, &error);
+ argv = get_command_argv (task, TRUE, &error);
if (error != NULL)
{
- build_job->priv->job_title = latexila_build_view_add_job_title (build_job->priv->build_view,
- build_job->priv->command,
- LATEXILA_BUILD_STATE_FAILED);
+ data->job_title = latexila_build_view_add_job_title (data->build_view,
+ build_job->priv->command,
+ LATEXILA_BUILD_STATE_FAILED);
- display_error (build_job, "Failed to parse command line:", error);
+ display_error (task, "Failed to parse command line:", error);
return FALSE;
}
command_line = g_strjoinv (" ", argv);
- build_job->priv->job_title = latexila_build_view_add_job_title (build_job->priv->build_view,
- command_line,
- LATEXILA_BUILD_STATE_RUNNING);
+ data->job_title = latexila_build_view_add_job_title (data->build_view,
+ command_line,
+ LATEXILA_BUILD_STATE_RUNNING);
g_strfreev (argv);
g_free (command_line);
@@ -392,97 +408,102 @@ display_command_line (LatexilaBuildJob *build_job)
static void
show_details_notify_cb (LatexilaBuildView *build_view,
GParamSpec *pspec,
- LatexilaBuildJob *build_job)
+ GTask *task)
{
+ TaskData *data = g_task_get_task_data (task);
const GList *messages;
gboolean show_details;
- latexila_build_view_remove_children (build_view,
- &build_job->priv->job_title);
+ latexila_build_view_remove_children (build_view, &data->job_title);
g_object_get (build_view, "show-details", &show_details, NULL);
- messages = latexila_post_processor_get_messages (build_job->priv->post_processor,
+ messages = latexila_post_processor_get_messages (data->post_processor,
show_details);
latexila_build_view_append_messages (build_view,
- &build_job->priv->job_title,
+ &data->job_title,
messages,
TRUE);
}
static void
-finish_post_processor (LatexilaBuildJob *build_job)
+finish_post_processor (GTask *task)
{
+ TaskData *data = g_task_get_task_data (task);
gboolean has_details;
- g_assert (build_job->priv->succeeded_set);
- g_assert (build_job->priv->post_processor_result != NULL);
+ g_assert (data->succeeded_set);
+ g_assert (data->post_processor_result != NULL);
- latexila_post_processor_process_finish (build_job->priv->post_processor,
- build_job->priv->post_processor_result,
- build_job->priv->succeeded);
+ latexila_post_processor_process_finish (data->post_processor,
+ data->post_processor_result,
+ data->succeeded);
- g_clear_object (&build_job->priv->post_processor_result);
+ g_clear_object (&data->post_processor_result);
- g_object_get (build_job->priv->post_processor,
+ g_object_get (data->post_processor,
"has-details", &has_details,
NULL);
if (has_details)
- g_object_set (build_job->priv->build_view,
+ g_object_set (data->build_view,
"has-details", TRUE,
NULL);
- g_signal_connect (build_job->priv->build_view,
- "notify::show-details",
- G_CALLBACK (show_details_notify_cb),
- build_job);
+ g_signal_connect_object (data->build_view,
+ "notify::show-details",
+ G_CALLBACK (show_details_notify_cb),
+ task,
+ 0);
- show_details_notify_cb (build_job->priv->build_view,
- NULL,
- build_job);
+ show_details_notify_cb (data->build_view, NULL, task);
}
static void
post_processor_cb (LatexilaPostProcessor *pp,
GAsyncResult *result,
- LatexilaBuildJob *build_job)
+ GTask *task)
{
- if (build_job->priv->post_processor_result != NULL)
+ TaskData *data = g_task_get_task_data (task);
+
+ if (data->post_processor_result != NULL)
{
g_warning ("BuildJob: got two post-processor results.");
- g_object_unref (build_job->priv->post_processor_result);
+ g_object_unref (data->post_processor_result);
}
- build_job->priv->post_processor_result = g_object_ref (result);
+ data->post_processor_result = g_object_ref (result);
- if (build_job->priv->succeeded_set)
- finish_post_processor (build_job);
+ if (data->succeeded_set)
+ finish_post_processor (task);
+
+ g_object_unref (task);
}
static void
-subprocess_wait_cb (GSubprocess *subprocess,
- GAsyncResult *result,
- LatexilaBuildJob *build_job)
+subprocess_wait_cb (GSubprocess *subprocess,
+ GAsyncResult *result,
+ GTask *task)
{
+ TaskData *data = g_task_get_task_data (task);
gboolean ret;
LatexilaBuildState state;
ret = g_subprocess_wait_finish (subprocess, result, NULL);
- if (build_job->priv->succeeded_set)
+ if (data->succeeded_set)
g_warning ("BuildJob: subprocess finished two times.");
- build_job->priv->succeeded = g_subprocess_get_successful (subprocess);
- build_job->priv->succeeded_set = TRUE;
+ data->succeeded = g_subprocess_get_successful (subprocess);
+ data->succeeded_set = TRUE;
if (!ret)
{
state = LATEXILA_BUILD_STATE_ABORTED;
g_subprocess_force_exit (subprocess);
}
- else if (build_job->priv->succeeded)
+ else if (data->succeeded)
{
state = LATEXILA_BUILD_STATE_SUCCEEDED;
}
@@ -492,20 +513,24 @@ subprocess_wait_cb (GSubprocess *subprocess,
state = LATEXILA_BUILD_STATE_FAILED;
}
- latexila_build_view_set_title_state (build_job->priv->build_view,
- &build_job->priv->job_title,
+ latexila_build_view_set_title_state (data->build_view,
+ &data->job_title,
state);
- g_task_return_boolean (build_job->priv->task, ret);
- g_object_unref (subprocess);
+ g_task_return_boolean (task, ret);
+
+ if (data->post_processor_result != NULL)
+ finish_post_processor (task);
- if (build_job->priv->post_processor_result != NULL)
- finish_post_processor (build_job);
+ g_object_unref (subprocess);
+ g_object_unref (task);
}
static void
-launch_subprocess (LatexilaBuildJob *build_job)
+launch_subprocess (GTask *task)
{
+ LatexilaBuildJob *build_job = g_task_get_source_object (task);
+ TaskData *data = g_task_get_task_data (task);
GSubprocessLauncher *launcher;
GSubprocess *subprocess;
GFile *parent_dir;
@@ -520,7 +545,7 @@ launch_subprocess (LatexilaBuildJob *build_job)
launcher = g_subprocess_launcher_new (G_SUBPROCESS_FLAGS_STDOUT_PIPE |
G_SUBPROCESS_FLAGS_STDERR_MERGE);
- parent_dir = g_file_get_parent (build_job->priv->file);
+ parent_dir = g_file_get_parent (data->file);
working_directory = g_file_get_path (parent_dir);
g_object_unref (parent_dir);
@@ -528,7 +553,7 @@ launch_subprocess (LatexilaBuildJob *build_job)
g_free (working_directory);
/* The error is already catched in display_command_line(). */
- argv = get_command_argv (build_job, FALSE, NULL);
+ argv = get_command_argv (task, FALSE, NULL);
subprocess = g_subprocess_launcher_spawnv (launcher, (const gchar * const *) argv, &error);
g_strfreev (argv);
@@ -536,11 +561,11 @@ launch_subprocess (LatexilaBuildJob *build_job)
if (error != NULL)
{
- display_error (build_job, "Failed to launch command:", error);
+ display_error (task, "Failed to launch command:", error);
return;
}
- g_clear_object (&build_job->priv->post_processor);
+ g_clear_object (&data->post_processor);
switch (build_job->priv->post_processor_type)
{
@@ -548,33 +573,37 @@ launch_subprocess (LatexilaBuildJob *build_job)
break;
case LATEXILA_POST_PROCESSOR_TYPE_ALL_OUTPUT:
- build_job->priv->post_processor = latexila_post_processor_all_output_new ();
+ data->post_processor = latexila_post_processor_all_output_new ();
break;
case LATEXILA_POST_PROCESSOR_TYPE_LATEX:
- build_job->priv->post_processor = latexila_post_processor_latex_new ();
+ data->post_processor = latexila_post_processor_latex_new ();
break;
case LATEXILA_POST_PROCESSOR_TYPE_LATEXMK:
- build_job->priv->post_processor = latexila_post_processor_latexmk_new ();
+ data->post_processor = latexila_post_processor_latexmk_new ();
break;
default:
g_return_if_reached ();
}
- if (build_job->priv->post_processor != NULL)
- latexila_post_processor_process_async (build_job->priv->post_processor,
- build_job->priv->file,
- g_subprocess_get_stdout_pipe (subprocess),
- g_task_get_cancellable (build_job->priv->task),
- (GAsyncReadyCallback) post_processor_cb,
- build_job);
+ if (data->post_processor != NULL)
+ {
+ g_object_ref (task);
+
+ latexila_post_processor_process_async (data->post_processor,
+ data->file,
+ g_subprocess_get_stdout_pipe (subprocess),
+ g_task_get_cancellable (task),
+ (GAsyncReadyCallback) post_processor_cb,
+ task);
+ }
g_subprocess_wait_async (subprocess,
- g_task_get_cancellable (build_job->priv->task),
+ g_task_get_cancellable (task),
(GAsyncReadyCallback) subprocess_wait_cb,
- build_job);
+ task);
}
/**
@@ -598,25 +627,29 @@ latexila_build_job_run_async (LatexilaBuildJob *build_job,
GAsyncReadyCallback callback,
gpointer user_data)
{
+ GTask *task;
+ TaskData *data;
+
g_return_if_fail (LATEXILA_IS_BUILD_JOB (build_job));
g_return_if_fail (G_IS_FILE (file));
g_return_if_fail (LATEXILA_IS_BUILD_VIEW (build_view));
- g_return_if_fail (build_job->priv->task == NULL);
-
- build_job->priv->task = g_task_new (build_job, cancellable, callback, user_data);
- g_clear_object (&build_job->priv->file);
- build_job->priv->file = g_object_ref (file);
+ task = g_task_new (build_job, cancellable, callback, user_data);
+ build_job->priv->running_tasks_count++;
- latexila_build_job_clear (build_job);
+ data = task_data_new ();
+ g_task_set_task_data (task, data, (GDestroyNotify) task_data_free);
- build_job->priv->build_view = g_object_ref (build_view);
+ data->file = g_object_ref (file);
+ data->build_view = g_object_ref (build_view);
- if (!display_command_line (build_job))
+ if (!display_command_line (task))
return;
- if (!g_task_return_error_if_cancelled (build_job->priv->task))
- launch_subprocess (build_job);
+ if (g_task_return_error_if_cancelled (task))
+ g_object_unref (task);
+ else
+ launch_subprocess (task);
}
/**
@@ -626,53 +659,38 @@ latexila_build_job_run_async (LatexilaBuildJob *build_job,
*
* Finishes the operation started with latexila_build_job_run_async().
*
+ * Before calling this function, you should keep a reference to @result as long
+ * as the build messages are displayed in the build view.
+ *
* Returns: %TRUE if the build job has run successfully.
*/
gboolean
latexila_build_job_run_finish (LatexilaBuildJob *build_job,
GAsyncResult *result)
{
+ GTask *task;
+ TaskData *data;
GCancellable *cancellable;
gboolean succeed;
g_return_if_fail (g_task_is_valid (result, build_job));
- cancellable = g_task_get_cancellable (G_TASK (result));
+ task = G_TASK (result);
+ data = g_task_get_task_data (task);
+
+ cancellable = g_task_get_cancellable (task);
if (g_cancellable_is_cancelled (cancellable))
{
- latexila_build_view_set_title_state (build_job->priv->build_view,
- &build_job->priv->job_title,
+ latexila_build_view_set_title_state (data->build_view,
+ &data->job_title,
LATEXILA_BUILD_STATE_ABORTED);
succeed = FALSE;
}
else
{
- succeed = g_task_propagate_boolean (G_TASK (result), NULL);
+ succeed = g_task_propagate_boolean (task, NULL);
}
- g_clear_object (&build_job->priv->task);
- g_clear_object (&build_job->priv->file);
-
+ build_job->priv->running_tasks_count--;
return succeed;
}
-
-/**
- * latexila_build_job_clear:
- * @build_job: a build job.
- *
- * Clears the last run operation. latexila_build_job_run_finish() must have been
- * called before calling this function.
- */
-void
-latexila_build_job_clear (LatexilaBuildJob *build_job)
-{
- if (build_job->priv->build_view != NULL)
- g_signal_handlers_disconnect_by_func (build_job->priv->build_view,
- show_details_notify_cb,
- build_job);
-
- g_clear_object (&build_job->priv->build_view);
- g_clear_object (&build_job->priv->post_processor);
- g_clear_object (&build_job->priv->post_processor_result);
- build_job->priv->succeeded_set = FALSE;
-}
diff --git a/src/liblatexila/latexila-build-job.h b/src/liblatexila/latexila-build-job.h
index bff5294..f4bef9b 100644
--- a/src/liblatexila/latexila-build-job.h
+++ b/src/liblatexila/latexila-build-job.h
@@ -66,8 +66,6 @@ void latexila_build_job_run_async (LatexilaBuild
gboolean latexila_build_job_run_finish (LatexilaBuildJob *build_job,
GAsyncResult *result);
-void latexila_build_job_clear (LatexilaBuildJob *build_job);
-
G_END_DECLS
#endif /* __LATEXILA_BUILD_JOB_H__ */
diff --git a/src/liblatexila/latexila-build-tool.c b/src/liblatexila/latexila-build-tool.c
index 892fcc3..5bcc903 100644
--- a/src/liblatexila/latexila-build-tool.c
+++ b/src/liblatexila/latexila-build-tool.c
@@ -42,23 +42,34 @@ struct _LatexilaBuildToolPrivate
gchar *extensions;
gchar *icon;
gchar *files_to_open;
+ gchar **files_to_open_split;
gint id;
/* A list of LatexilaBuildJob's. */
GQueue *jobs;
- /* Used for running the build tool. */
- GTask *task;
+ guint running_tasks_count;
+
+ guint enabled : 1;
+};
+
+/* Used for running the build tool. */
+typedef struct _TaskData TaskData;
+struct _TaskData
+{
GFile *file;
LatexilaBuildView *build_view;
GtkTreeIter main_title;
+
+ /* Position in priv->jobs. */
GList *current_job;
- gchar **files_to_open_split;
- gchar **current_file_to_open; /* Position in files_to_open_split */
+ /* Position in priv->files_to_open_split. */
+ gchar **current_file_to_open;
+
GtkTreeIter open_file_job_title;
- guint enabled : 1;
+ GSList *job_results;
};
enum
@@ -76,8 +87,27 @@ enum
G_DEFINE_TYPE_WITH_PRIVATE (LatexilaBuildTool, latexila_build_tool, G_TYPE_OBJECT)
/* Prototypes */
-static void run_job (LatexilaBuildTool *build_tool);
-static void open_file (LatexilaBuildTool *build_tool);
+static void run_job (GTask *task);
+static void open_file (GTask *task);
+
+static TaskData *
+task_data_new (void)
+{
+ return g_slice_new0 (TaskData);
+}
+
+static void
+task_data_free (TaskData *data)
+{
+ if (data != NULL)
+ {
+ g_clear_object (&data->file);
+ g_clear_object (&data->build_view);
+ g_slist_free_full (data->job_results, g_object_unref);
+
+ g_slice_free (TaskData, data);
+ }
+}
static void
latexila_build_tool_get_property (GObject *object,
@@ -132,7 +162,7 @@ latexila_build_tool_set_property (GObject *object,
LatexilaBuildTool *build_tool = LATEXILA_BUILD_TOOL (object);
/* The build tool can not be modified when it is running. */
- g_return_if_fail (build_tool->priv->task == NULL);
+ g_return_if_fail (build_tool->priv->running_tasks_count == 0);
switch (prop_id)
{
@@ -191,10 +221,6 @@ latexila_build_tool_dispose (GObject *object)
build_tool->priv->jobs = NULL;
}
- g_clear_object (&build_tool->priv->task);
- g_clear_object (&build_tool->priv->file);
- g_clear_object (&build_tool->priv->build_view);
-
G_OBJECT_CLASS (latexila_build_tool_parent_class)->dispose (object);
}
@@ -392,7 +418,7 @@ latexila_build_tool_add_job (LatexilaBuildTool *build_tool,
g_return_if_fail (LATEXILA_IS_BUILD_JOB (build_job));
/* The build tool can not be modified when it is running. */
- g_return_if_fail (build_tool->priv->task == NULL);
+ g_return_if_fail (build_tool->priv->running_tasks_count == 0);
g_queue_push_tail (build_tool->priv->jobs, build_job);
g_object_ref (build_job);
@@ -464,29 +490,32 @@ latexila_build_tool_to_xml (LatexilaBuildTool *tool)
}
static void
-failed (LatexilaBuildTool *build_tool)
+failed (GTask *task)
{
+ TaskData *data = g_task_get_task_data (task);
GCancellable *cancellable;
LatexilaBuildState state;
- cancellable = g_task_get_cancellable (build_tool->priv->task);
+ cancellable = g_task_get_cancellable (task);
if (g_cancellable_is_cancelled (cancellable))
state = LATEXILA_BUILD_STATE_ABORTED;
else
state = LATEXILA_BUILD_STATE_FAILED;
- latexila_build_view_set_title_state (build_tool->priv->build_view,
- &build_tool->priv->main_title,
+ latexila_build_view_set_title_state (data->build_view,
+ &data->main_title,
state);
- g_task_return_boolean (build_tool->priv->task, FALSE);
+ g_task_return_boolean (task, FALSE);
+ g_object_unref (task);
}
static void
-query_exists_cb (GFile *file,
- GAsyncResult *result,
- LatexilaBuildTool *build_tool)
+query_exists_cb (GFile *file,
+ GAsyncResult *result,
+ GTask *task)
{
+ TaskData *data = g_task_get_task_data (task);
gboolean file_exists;
GCancellable *cancellable;
gchar *uri = NULL;
@@ -494,13 +523,13 @@ query_exists_cb (GFile *file,
file_exists = latexila_utils_file_query_exists_finish (file, result);
- cancellable = g_task_get_cancellable (build_tool->priv->task);
+ cancellable = g_task_get_cancellable (task);
if (g_cancellable_is_cancelled (cancellable))
{
- latexila_build_view_set_title_state (build_tool->priv->build_view,
- &build_tool->priv->open_file_job_title,
+ latexila_build_view_set_title_state (data->build_view,
+ &data->open_file_job_title,
LATEXILA_BUILD_STATE_ABORTED);
- failed (build_tool);
+ failed (task);
goto out;
}
@@ -510,26 +539,26 @@ query_exists_cb (GFile *file,
{
LatexilaBuildMsg *msg;
- latexila_build_view_set_title_state (build_tool->priv->build_view,
- &build_tool->priv->open_file_job_title,
+ latexila_build_view_set_title_state (data->build_view,
+ &data->open_file_job_title,
LATEXILA_BUILD_STATE_FAILED);
msg = latexila_build_msg_new ();
msg->text = g_strdup_printf (_("The file '%s' doesn't exist."), uri);
msg->type = LATEXILA_BUILD_MSG_TYPE_ERROR;
- latexila_build_view_append_single_message (build_tool->priv->build_view,
- &build_tool->priv->open_file_job_title,
+ latexila_build_view_append_single_message (data->build_view,
+ &data->open_file_job_title,
msg);
latexila_build_msg_free (msg);
- failed (build_tool);
+ failed (task);
goto out;
}
/* Show URI */
- gtk_show_uri (gtk_widget_get_screen (GTK_WIDGET (build_tool->priv->build_view)),
+ gtk_show_uri (gtk_widget_get_screen (GTK_WIDGET (data->build_view)),
uri,
GDK_CURRENT_TIME,
&error);
@@ -538,39 +567,39 @@ query_exists_cb (GFile *file,
{
LatexilaBuildMsg *msg;
- latexila_build_view_set_title_state (build_tool->priv->build_view,
- &build_tool->priv->open_file_job_title,
+ latexila_build_view_set_title_state (data->build_view,
+ &data->open_file_job_title,
LATEXILA_BUILD_STATE_FAILED);
msg = latexila_build_msg_new ();
msg->text = g_strdup_printf (_("Failed to open '%s':"), uri);
msg->type = LATEXILA_BUILD_MSG_TYPE_ERROR;
- latexila_build_view_append_single_message (build_tool->priv->build_view,
- &build_tool->priv->open_file_job_title,
+ latexila_build_view_append_single_message (data->build_view,
+ &data->open_file_job_title,
msg);
g_free (msg->text);
msg->text = g_strdup (error->message);
msg->type = LATEXILA_BUILD_MSG_TYPE_INFO;
- latexila_build_view_append_single_message (build_tool->priv->build_view,
- &build_tool->priv->open_file_job_title,
+ latexila_build_view_append_single_message (data->build_view,
+ &data->open_file_job_title,
msg);
latexila_build_msg_free (msg);
g_error_free (error);
- failed (build_tool);
+ failed (task);
goto out;
}
- latexila_build_view_set_title_state (build_tool->priv->build_view,
- &build_tool->priv->open_file_job_title,
+ latexila_build_view_set_title_state (data->build_view,
+ &data->open_file_job_title,
LATEXILA_BUILD_STATE_SUCCEEDED);
- build_tool->priv->current_file_to_open++;
- open_file (build_tool);
+ data->current_file_to_open++;
+ open_file (task);
out:
g_object_unref (file);
@@ -578,8 +607,9 @@ out:
}
static void
-open_file (LatexilaBuildTool *build_tool)
+open_file (GTask *task)
{
+ TaskData *data = g_task_get_task_data (task);
const gchar *file_to_open;
gchar *filename;
gchar *shortname;
@@ -590,32 +620,33 @@ open_file (LatexilaBuildTool *build_tool)
while (TRUE)
{
- if (build_tool->priv->current_file_to_open == NULL ||
- build_tool->priv->current_file_to_open[0] == NULL)
+ if (data->current_file_to_open == NULL ||
+ data->current_file_to_open[0] == NULL)
{
/* Finished */
- latexila_build_view_set_title_state (build_tool->priv->build_view,
- &build_tool->priv->main_title,
+ latexila_build_view_set_title_state (data->build_view,
+ &data->main_title,
LATEXILA_BUILD_STATE_SUCCEEDED);
- g_task_return_boolean (build_tool->priv->task, TRUE);
+ g_task_return_boolean (task, TRUE);
+ g_object_unref (task);
return;
}
/* Check if the file to open is an empty string. It happens if there are
* two contiguous spaces in priv->files_to_open for example.
*/
- if (build_tool->priv->current_file_to_open[0][0] == '\0')
- build_tool->priv->current_file_to_open++;
+ if (data->current_file_to_open[0][0] == '\0')
+ data->current_file_to_open++;
else
break;
}
- file_to_open = build_tool->priv->current_file_to_open[0];
+ file_to_open = data->current_file_to_open[0];
/* Replace placeholders */
- filename = g_file_get_uri (build_tool->priv->file);
+ filename = g_file_get_uri (data->file);
shortname = latexila_utils_get_shortname (filename);
if (strstr (file_to_open, "$filename") != NULL)
@@ -630,18 +661,18 @@ open_file (LatexilaBuildTool *build_tool)
basename = g_path_get_basename (uri);
message = g_strdup_printf (_("Open %s"), basename);
- build_tool->priv->open_file_job_title = latexila_build_view_add_job_title (build_tool->priv->build_view,
- message,
- LATEXILA_BUILD_STATE_RUNNING);
+ data->open_file_job_title = latexila_build_view_add_job_title (data->build_view,
+ message,
+ LATEXILA_BUILD_STATE_RUNNING);
/* Check if the file exists */
file = g_file_new_for_uri (uri);
latexila_utils_file_query_exists_async (file,
- g_task_get_cancellable (build_tool->priv->task),
+ g_task_get_cancellable (task),
(GAsyncReadyCallback) query_exists_cb,
- build_tool);
+ task);
g_free (filename);
g_free (shortname);
@@ -651,54 +682,65 @@ open_file (LatexilaBuildTool *build_tool)
}
static void
-open_files (LatexilaBuildTool *build_tool)
+open_files (GTask *task)
{
- build_tool->priv->current_file_to_open = build_tool->priv->files_to_open_split;
- open_file (build_tool);
+ TaskData *data = g_task_get_task_data (task);
+ LatexilaBuildTool *build_tool = g_task_get_source_object (task);
+
+ data->current_file_to_open = build_tool->priv->files_to_open_split;
+ open_file (task);
}
static void
-run_job_cb (LatexilaBuildJob *build_job,
- GAsyncResult *result,
- LatexilaBuildTool *build_tool)
+run_job_cb (LatexilaBuildJob *build_job,
+ GAsyncResult *result,
+ GTask *task)
{
+ TaskData *data = g_task_get_task_data (task);
gboolean success;
+ data->job_results = g_slist_prepend (data->job_results,
+ g_object_ref (result));
+
success = latexila_build_job_run_finish (build_job, result);
if (success)
{
- build_tool->priv->current_job = build_tool->priv->current_job->next;
- run_job (build_tool);
+ data->current_job = data->current_job->next;
+ run_job (task);
}
else
{
- failed (build_tool);
+ failed (task);
}
}
static void
-run_job (LatexilaBuildTool *build_tool)
+run_job (GTask *task)
{
+ TaskData *data = g_task_get_task_data (task);
LatexilaBuildJob *build_job;
- if (g_task_return_error_if_cancelled (build_tool->priv->task))
- return;
+ if (g_task_return_error_if_cancelled (task))
+ {
+ g_object_unref (task);
+ return;
+ }
- if (build_tool->priv->current_job == NULL)
+ if (data->current_job == NULL)
{
- open_files (build_tool);
+ open_files (task);
return;
}
- build_job = build_tool->priv->current_job->data;
+ build_job = data->current_job->data;
latexila_build_job_run_async (build_job,
- build_tool->priv->file,
- build_tool->priv->build_view,
- g_task_get_cancellable (build_tool->priv->task),
+ data->file,
+ data->build_view,
+ g_task_get_cancellable (task),
(GAsyncReadyCallback) run_job_cb,
- build_tool);
+ task);
}
/**
@@ -720,27 +762,30 @@ latexila_build_tool_run_async (LatexilaBuildTool *build_tool,
GAsyncReadyCallback callback,
gpointer user_data)
{
+ GTask *task;
+ TaskData *data;
+
g_return_if_fail (LATEXILA_IS_BUILD_TOOL (build_tool));
g_return_if_fail (G_IS_FILE (file));
g_return_if_fail (LATEXILA_IS_BUILD_VIEW (build_view));
- g_return_if_fail (build_tool->priv->task == NULL);
- build_tool->priv->task = g_task_new (build_tool, cancellable, callback, user_data);
+ task = g_task_new (build_tool, cancellable, callback, user_data);
+ build_tool->priv->running_tasks_count++;
- g_clear_object (&build_tool->priv->file);
- build_tool->priv->file = g_object_ref (file);
+ data = task_data_new ();
+ g_task_set_task_data (task, data, (GDestroyNotify) task_data_free);
- g_clear_object (&build_tool->priv->build_view);
- build_tool->priv->build_view = g_object_ref (build_view);
+ data->file = g_object_ref (file);
+ data->build_view = g_object_ref (build_view);
latexila_build_view_clear (build_view);
- build_tool->priv->main_title = latexila_build_view_add_main_title (build_view,
- build_tool->priv->label,
- LATEXILA_BUILD_STATE_RUNNING);
+ data->main_title = latexila_build_view_add_main_title (build_view,
+ build_tool->priv->label,
+ LATEXILA_BUILD_STATE_RUNNING);
- build_tool->priv->current_job = build_tool->priv->jobs->head;
- run_job (build_tool);
+ data->current_job = build_tool->priv->jobs->head;
+ run_job (task);
}
/**
@@ -749,48 +794,30 @@ latexila_build_tool_run_async (LatexilaBuildTool *build_tool,
* @result: a #GAsyncResult.
*
* Finishes the operation started with latexila_build_tool_run_async().
+ *
+ * Before calling this function you should keep a reference to @result as long
+ * as the build messages are displayed in the build view. @result is needed for
+ * example to show/hide some messages when the "More details" button is toggled.
*/
void
latexila_build_tool_run_finish (LatexilaBuildTool *build_tool,
GAsyncResult *result)
{
+ GTask *task;
+ TaskData *data;
GCancellable *cancellable;
g_return_if_fail (g_task_is_valid (result, build_tool));
- cancellable = g_task_get_cancellable (G_TASK (result));
+ task = G_TASK (result);
+ data = g_task_get_task_data (task);
+
+ cancellable = g_task_get_cancellable (task);
if (g_cancellable_is_cancelled (cancellable))
- latexila_build_view_set_title_state (build_tool->priv->build_view,
- &build_tool->priv->main_title,
+ latexila_build_view_set_title_state (data->build_view,
+ &data->main_title,
LATEXILA_BUILD_STATE_ABORTED);
- g_task_propagate_boolean (G_TASK (result), NULL);
-
- g_clear_object (&build_tool->priv->task);
- g_clear_object (&build_tool->priv->file);
- g_clear_object (&build_tool->priv->build_view);
-}
-
-/**
- * latexila_build_tool_clear:
- * @build_tool: a build tool
- *
- * Clears the last run operation. latexila_build_tool_run_finish() must have
- * been called before calling this function.
- *
- * The build tool can keep build messages or other information in memory. For
- * example if a build job contains detailed messages, the two trees of messages
- * must be kept in memory so it can switch between them when the "More details"
- * button is toggled.
- */
-void
-latexila_build_tool_clear (LatexilaBuildTool *build_tool)
-{
- GList *l;
-
- for (l = build_tool->priv->jobs->head; l != NULL; l = l->next)
- {
- LatexilaBuildJob *build_job = l->data;
- latexila_build_job_clear (build_job);
- }
+ g_task_propagate_boolean (task, NULL);
+ build_tool->priv->running_tasks_count--;
}
diff --git a/src/liblatexila/latexila-build-tool.h b/src/liblatexila/latexila-build-tool.h
index b497fe8..32c5dc6 100644
--- a/src/liblatexila/latexila-build-tool.h
+++ b/src/liblatexila/latexila-build-tool.h
@@ -72,8 +72,6 @@ void latexila_build_tool_run_async (LatexilaBui
void latexila_build_tool_run_finish (LatexilaBuildTool *build_tool,
GAsyncResult *result);
-void latexila_build_tool_clear (LatexilaBuildTool *build_tool);
-
G_END_DECLS
#endif /* __LATEXILA_BUILD_TOOL_H__ */
diff --git a/src/main_window_build_tools.vala b/src/main_window_build_tools.vala
index e67fc78..a615168 100644
--- a/src/main_window_build_tools.vala
+++ b/src/main_window_build_tools.vala
@@ -59,8 +59,8 @@ public class MainWindowBuildTools
private BottomPanel _bottom_panel;
// Used for running a build tool, and clear it when running another build tool.
- private Latexila.BuildTool? _build_tool;
private Cancellable? _cancellable;
+ private AsyncResult? _build_tool_result;
private Gtk.ActionGroup _static_action_group;
private Gtk.ActionGroup _dynamic_action_group;
@@ -377,18 +377,15 @@ public class MainWindowBuildTools
Utils.flush_queue ();
}
- if (_build_tool != null)
- _build_tool.clear ();
-
- _build_tool = tool;
-
/* Run the build tool */
File main_file = active_doc.get_main_file ();
_cancellable = new Cancellable ();
+ _build_tool_result = null;
update_sensitivity ();
tool.run_async.begin (main_file, _build_view, _cancellable, (obj, result) =>
{
+ _build_tool_result = result;
tool.run_async.end (result);
_cancellable = null;
update_sensitivity ();
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]