[latexila/wip/build-tools-revamp] LatexilaBuildTools classes (not finished)



commit c3299cb5f02bc0b88b2c186d051abb33c1d82e78
Author: Sébastien Wilmet <swilmet gnome org>
Date:   Sat Apr 19 15:44:23 2014 +0200

    LatexilaBuildTools classes (not finished)
    
    And add a latexila-types.h for convenience.

 src/liblatexila/Makefile.am                        |   11 +-
 src/liblatexila/latexila-build-tools-default.c     |   84 +++
 src/liblatexila/latexila-build-tools-default.h     |   58 ++
 src/liblatexila/latexila-build-tools-personal.c    |  205 ++++++++
 src/liblatexila/latexila-build-tools-personal.h    |   58 ++
 src/liblatexila/latexila-build-tools.c             |  545 ++++++++++++++++++++
 src/liblatexila/latexila-build-tools.h             |  104 ++++
 .../latexila-post-processor-all-output.h           |    3 +-
 src/liblatexila/latexila-post-processor.h          |    2 +-
 src/liblatexila/latexila-types.h                   |   35 ++
 10 files changed, 1102 insertions(+), 3 deletions(-)
---
diff --git a/src/liblatexila/Makefile.am b/src/liblatexila/Makefile.am
index 78f7716..35372b0 100644
--- a/src/liblatexila/Makefile.am
+++ b/src/liblatexila/Makefile.am
@@ -1,9 +1,18 @@
+AM_CPPFLAGS = $(WARN_CFLAGS)
+
 noinst_LTLIBRARIES = liblatexila.la
 
 liblatexila_la_SOURCES =                       \
+       latexila-build-tools.c                  \
+       latexila-build-tools.h                  \
+       latexila-build-tools-default.c          \
+       latexila-build-tools-default.h          \
+       latexila-build-tools-personal.c         \
+       latexila-build-tools-personal.h         \
        latexila-post-processor.c               \
        latexila-post-processor.h               \
        latexila-post-processor-all-output.c    \
-       latexila-post-processor-all-output.h
+       latexila-post-processor-all-output.h    \
+       latexila-types.h
 
 -include $(top_srcdir)/git.mk
diff --git a/src/liblatexila/latexila-build-tools-default.c b/src/liblatexila/latexila-build-tools-default.c
new file mode 100644
index 0000000..0e551d2
--- /dev/null
+++ b/src/liblatexila/latexila-build-tools-default.c
@@ -0,0 +1,84 @@
+/*
+ * This file is part of LaTeXila.
+ *
+ * Copyright (C) 2014 - Sébastien Wilmet <swilmet gnome org>
+ *
+ * LaTeXila is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * LaTeXila is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with LaTeXila.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+#include "latexila-build-tools-default.h"
+#include <gio/gio.h>
+
+static LatexilaBuildToolsDefault *instance = NULL;
+
+struct _LatexilaBuildToolsDefaultPrivate
+{
+  gint something;
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE (LatexilaBuildToolsDefault, latexila_build_tools_default, 
LATEXILA_TYPE_BUILD_TOOLS)
+
+static void
+latexila_build_tools_default_dispose (GObject *object)
+{
+
+  G_OBJECT_CLASS (latexila_build_tools_default_parent_class)->dispose (object);
+}
+
+static void
+latexila_build_tools_default_finalize (GObject *object)
+{
+
+  G_OBJECT_CLASS (latexila_build_tools_default_parent_class)->finalize (object);
+}
+
+static void
+latexila_build_tools_default_class_init (LatexilaBuildToolsDefaultClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->dispose = latexila_build_tools_default_dispose;
+  object_class->finalize = latexila_build_tools_default_finalize;
+}
+
+static void
+latexila_build_tools_default_init (LatexilaBuildToolsDefault *build_tools)
+{
+  build_tools->priv = latexila_build_tools_default_get_instance_private (build_tools);
+}
+
+static GFile *
+get_xml_file (void)
+{
+  gchar *path;
+  GFile *file;
+
+  path = g_build_filename (DATA_DIR, "build_tools.xml", NULL);
+  file = g_file_new_for_path (path);
+  g_free (path);
+
+  return file;
+}
+
+LatexilaBuildToolsDefault *
+latexila_build_tools_default_get_instance (void)
+{
+  if (instance == NULL)
+    {
+      instance = g_object_new (LATEXILA_TYPE_BUILD_TOOLS_DEFAULT, NULL);
+    }
+
+  return instance;
+}
diff --git a/src/liblatexila/latexila-build-tools-default.h b/src/liblatexila/latexila-build-tools-default.h
new file mode 100644
index 0000000..c010aaa
--- /dev/null
+++ b/src/liblatexila/latexila-build-tools-default.h
@@ -0,0 +1,58 @@
+/*
+ * This file is part of LaTeXila.
+ *
+ * Copyright (C) 2014 - Sébastien Wilmet <swilmet gnome org>
+ *
+ * LaTeXila is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * LaTeXila is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with LaTeXila.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __LATEXILA_BUILD_TOOLS_DEFAULT_H__
+#define __LATEXILA_BUILD_TOOLS_DEFAULT_H__
+
+#include <glib-object.h>
+#include "latexila-build-tools.h"
+#include "latexila-types.h"
+
+G_BEGIN_DECLS
+
+#define LATEXILA_TYPE_BUILD_TOOLS_DEFAULT             (latexila_build_tools_default_get_type ())
+#define LATEXILA_BUILD_TOOLS_DEFAULT(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), 
LATEXILA_TYPE_BUILD_TOOLS_DEFAULT, LatexilaBuildToolsDefault))
+#define LATEXILA_BUILD_TOOLS_DEFAULT_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), 
LATEXILA_TYPE_BUILD_TOOLS_DEFAULT, LatexilaBuildToolsDefaultClass))
+#define LATEXILA_IS_BUILD_TOOLS_DEFAULT(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), 
LATEXILA_TYPE_BUILD_TOOLS_DEFAULT))
+#define LATEXILA_IS_BUILD_TOOLS_DEFAULT_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), 
LATEXILA_TYPE_BUILD_TOOLS_DEFAULT))
+#define LATEXILA_BUILD_TOOLS_DEFAULT_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), 
LATEXILA_TYPE_BUILD_TOOLS_DEFAULT, LatexilaBuildToolsDefaultClass))
+
+typedef struct _LatexilaBuildToolsDefaultClass   LatexilaBuildToolsDefaultClass;
+typedef struct _LatexilaBuildToolsDefaultPrivate LatexilaBuildToolsDefaultPrivate;
+
+struct _LatexilaBuildToolsDefault
+{
+  LatexilaBuildTools parent;
+
+  LatexilaBuildToolsDefaultPrivate *priv;
+};
+
+struct _LatexilaBuildToolsDefaultClass
+{
+  LatexilaBuildToolsClass parent_class;
+};
+
+GType               latexila_build_tools_default_get_type           (void) G_GNUC_CONST;
+
+LatexilaBuildToolsDefault *
+                    latexila_build_tools_default_get_instance       (void);
+
+G_END_DECLS
+
+#endif /* __LATEXILA_BUILD_TOOLS_DEFAULT_H__ */
diff --git a/src/liblatexila/latexila-build-tools-personal.c b/src/liblatexila/latexila-build-tools-personal.c
new file mode 100644
index 0000000..d55eaac
--- /dev/null
+++ b/src/liblatexila/latexila-build-tools-personal.c
@@ -0,0 +1,205 @@
+/*
+ * This file is part of LaTeXila.
+ *
+ * Copyright (C) 2014 - Sébastien Wilmet <swilmet gnome org>
+ *
+ * LaTeXila is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * LaTeXila is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with LaTeXila.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "latexila-build-tools-personal.h"
+#include <gio/gio.h>
+
+static LatexilaBuildToolsPersonal *instance = NULL;
+
+struct _LatexilaBuildToolsPersonalPrivate
+{
+  /* Used for saving */
+  GString *xml_file_contents;
+
+  guint modified : 1;
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE (LatexilaBuildToolsPersonal, latexila_build_tools_personal, 
LATEXILA_TYPE_BUILD_TOOLS)
+
+static void
+latexila_build_tools_personal_finalize (GObject *object)
+{
+  LatexilaBuildToolsPersonal *build_tools = LATEXILA_BUILD_TOOLS_PERSONAL (object);
+
+  if (build_tools->priv->xml_file_contents != NULL)
+    {
+      g_string_free (build_tools->priv->xml_file_contents, TRUE);
+      build_tools->priv->xml_file_contents = NULL;
+    }
+
+  G_OBJECT_CLASS (latexila_build_tools_personal_parent_class)->finalize (object);
+}
+
+static void
+latexila_build_tools_personal_class_init (LatexilaBuildToolsPersonalClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->finalize = latexila_build_tools_personal_finalize;
+}
+
+static void
+latexila_build_tools_personal_init (LatexilaBuildToolsPersonal *build_tools)
+{
+  build_tools->priv = latexila_build_tools_personal_get_instance_private (build_tools);
+}
+
+LatexilaBuildToolsPersonal *
+latexila_build_tools_personal_get_instance (void)
+{
+  if (instance == NULL)
+    {
+      instance = g_object_new (LATEXILA_TYPE_BUILD_TOOLS_PERSONAL, NULL);
+    }
+
+  return instance;
+}
+
+static GFile *
+get_xml_file (void)
+{
+  gchar *path;
+  GFile *file;
+
+  path = g_build_filename (g_get_user_config_dir (),
+                           "latexila",
+                           "build_tools.xml",
+                           NULL);
+
+  file = g_file_new_for_path (path);
+  g_free (path);
+
+  return file;
+}
+
+static void
+save_cb (GFile                      *xml_file,
+         GAsyncResult               *result,
+         LatexilaBuildToolsPersonal *build_tools)
+{
+  GError *error = NULL;
+
+  g_file_replace_contents_finish (xml_file, result, NULL, &error);
+
+  if (error != NULL)
+    {
+      g_warning ("Error while saving the personal build tools: %s",
+                 error->message);
+      g_error_free (error);
+    }
+  else
+    {
+      build_tools->priv->modified = FALSE;
+    }
+
+  g_string_free (build_tools->priv->xml_file_contents, TRUE);
+  build_tools->priv->xml_file_contents = NULL;
+
+  g_object_unref (build_tools);
+}
+
+static void
+latexila_build_tools_save (LatexilaBuildToolsPersonal *build_tools)
+{
+  LatexilaBuildTools *build_tools_parent = LATEXILA_BUILD_TOOLS (build_tools);
+  GString *contents;
+  GList *cur_build_tool;
+  GFile *xml_file;
+
+  g_return_if_fail (LATEXILA_IS_BUILD_TOOLS (build_tools));
+
+  if (!build_tools->priv->modified)
+    {
+      return;
+    }
+
+  if (build_tools->priv->xml_file_contents != NULL)
+    {
+      g_string_free (build_tools->priv->xml_file_contents, TRUE);
+    }
+
+  contents = g_string_new ("<tools>");
+  build_tools->priv->xml_file_contents = contents;
+
+  for (cur_build_tool = build_tools_parent->build_tools;
+       cur_build_tool != NULL;
+       cur_build_tool = cur_build_tool->next)
+    {
+      LatexilaBuildTool *build_tool = cur_build_tool->data;
+      gchar *escaped_text;
+      GSList *cur_build_job;
+
+      g_string_append_printf (contents,
+                              "\n  <tool enabled=\"%s\" extensions=\"%s\" icon=\"%s\">\n",
+                              build_tool->enabled ? "true" : "false",
+                              build_tool->extensions != NULL ? build_tool->extensions : "",
+                              build_tool->icon != NULL ? build_tool->icon : "");
+
+      escaped_text = g_markup_printf_escaped ("    <label>%s</label>\n"
+                                              "    <description>%s</description>\n",
+                                              build_tool->label != NULL ? build_tool->label : "",
+                                              build_tool->description != NULL ? build_tool->description : 
"");
+
+      g_string_append (contents, escaped_text);
+      g_free (escaped_text);
+
+      for (cur_build_job = build_tool->jobs;
+           cur_build_job != NULL;
+           cur_build_job = cur_build_job->next)
+        {
+          LatexilaBuildJob *build_job = cur_build_job->data;
+
+          escaped_text = g_markup_printf_escaped ("    <job postProcessor=\"%s\">%s</job>\n",
+                                                  latexila_get_post_processor_name_from_type 
(build_job->post_processor_type),
+                                                  build_job->command != NULL ? build_job->command : "");
+
+          g_string_append (contents, escaped_text);
+          g_free (escaped_text);
+        }
+
+      escaped_text = g_markup_printf_escaped ("    <open>%s</open>\n",
+                                              build_tool->files_to_open != NULL ? build_tool->files_to_open 
: "");
+      g_string_append (contents, escaped_text);
+      g_free (escaped_text);
+
+      g_string_append (contents, "  </tool>\n");
+    }
+
+  g_string_append (contents, "</tools>\n");
+
+  /* Avoid finalization of build_tools during the async operation. The latexila
+   * API for save() doesn't follow the GIO conventions for async operations, so
+   * a g_object_ref() is needed.
+   */
+  g_object_ref (build_tools);
+
+  xml_file = get_xml_file ();
+
+  g_file_replace_contents_async (xml_file,
+                                 contents->str,
+                                 contents->len,
+                                 NULL,
+                                 TRUE, /* make a backup */
+                                 G_FILE_CREATE_NONE,
+                                 NULL,
+                                 (GAsyncReadyCallback) save_cb,
+                                 build_tools);
+
+  g_object_unref (xml_file);
+}
diff --git a/src/liblatexila/latexila-build-tools-personal.h b/src/liblatexila/latexila-build-tools-personal.h
new file mode 100644
index 0000000..b63341c
--- /dev/null
+++ b/src/liblatexila/latexila-build-tools-personal.h
@@ -0,0 +1,58 @@
+/*
+ * This file is part of LaTeXila.
+ *
+ * Copyright (C) 2014 - Sébastien Wilmet <swilmet gnome org>
+ *
+ * LaTeXila is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * LaTeXila is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with LaTeXila.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __LATEXILA_BUILD_TOOLS_PERSONAL_H__
+#define __LATEXILA_BUILD_TOOLS_PERSONAL_H__
+
+#include <glib-object.h>
+#include "latexila-build-tools.h"
+#include "latexila-types.h"
+
+G_BEGIN_DECLS
+
+#define LATEXILA_TYPE_BUILD_TOOLS_PERSONAL             (latexila_build_tools_personal_get_type ())
+#define LATEXILA_BUILD_TOOLS_PERSONAL(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), 
LATEXILA_TYPE_BUILD_TOOLS_PERSONAL, LatexilaBuildToolsPersonal))
+#define LATEXILA_BUILD_TOOLS_PERSONAL_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), 
LATEXILA_TYPE_BUILD_TOOLS_PERSONAL, LatexilaBuildToolsPersonalClass))
+#define LATEXILA_IS_BUILD_TOOLS_PERSONAL(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), 
LATEXILA_TYPE_BUILD_TOOLS_PERSONAL))
+#define LATEXILA_IS_BUILD_TOOLS_PERSONAL_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), 
LATEXILA_TYPE_BUILD_TOOLS_PERSONAL))
+#define LATEXILA_BUILD_TOOLS_PERSONAL_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), 
LATEXILA_TYPE_BUILD_TOOLS_PERSONAL, LatexilaBuildToolsPersonalClass))
+
+typedef struct _LatexilaBuildToolsPersonalClass   LatexilaBuildToolsPersonalClass;
+typedef struct _LatexilaBuildToolsPersonalPrivate LatexilaBuildToolsPersonalPrivate;
+
+struct _LatexilaBuildToolsPersonal
+{
+  LatexilaBuildTools parent;
+
+  LatexilaBuildToolsPersonalPrivate *priv;
+};
+
+struct _LatexilaBuildToolsPersonalClass
+{
+  LatexilaBuildToolsClass parent_class;
+};
+
+GType               latexila_build_tools_personal_get_type            (void) G_GNUC_CONST;
+
+LatexilaBuildToolsPersonal *
+                    latexila_build_tools_personal_get_instance        (void);
+
+G_END_DECLS
+
+#endif /* __LATEXILA_BUILD_TOOLS_PERSONAL_H__ */
diff --git a/src/liblatexila/latexila-build-tools.c b/src/liblatexila/latexila-build-tools.c
new file mode 100644
index 0000000..5e125e5
--- /dev/null
+++ b/src/liblatexila/latexila-build-tools.c
@@ -0,0 +1,545 @@
+/*
+ * This file is part of LaTeXila.
+ *
+ * Copyright (C) 2014 - Sébastien Wilmet <swilmet gnome org>
+ *
+ * LaTeXila is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * LaTeXila is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with LaTeXila.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* Load build tools from an XML file into data structures in memory. The build
+ * tools can be modified in memory, and then saved into the XML file.
+ */
+
+#include "latexila-build-tools.h"
+#include <gio/gio.h>
+#include <glib/gi18n.h>
+#include "latexila-build-tools-default.h"
+
+struct _LatexilaBuildToolsPrivate
+{
+  /* Used during the XML file parsing to load the build tools. */
+  LatexilaBuildTool *cur_tool;
+  LatexilaBuildJob *cur_job;
+};
+
+enum
+{
+  SIGNAL_CHANGED,
+  LAST_SIGNAL
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE (LatexilaBuildTools, latexila_build_tools, G_TYPE_OBJECT)
+
+static guint signals[LAST_SIGNAL];
+
+static LatexilaBuildJob *
+build_job_new (void)
+{
+  return g_slice_new0 (LatexilaBuildJob);
+}
+
+static void
+build_job_free (LatexilaBuildJob *build_job)
+{
+  if (build_job != NULL)
+    {
+      g_free (build_job->command);
+      g_slice_free (LatexilaBuildJob, build_job);
+    }
+}
+
+static LatexilaBuildTool *
+build_tool_new (void)
+{
+  return g_slice_new0 (LatexilaBuildTool);
+}
+
+static void
+build_tool_free (LatexilaBuildTool *build_tool)
+{
+  if (build_tool != NULL)
+    {
+      g_free (build_tool->label);
+      g_free (build_tool->description);
+      g_free (build_tool->extensions);
+      g_free (build_tool->icon);
+      g_free (build_tool->files_to_open);
+
+      g_slist_free_full (build_tool->jobs, (GDestroyNotify) build_job_free);
+
+      g_slice_free (LatexilaBuildTool, build_tool);
+    }
+}
+
+/**
+ * latexila_build_tool_get_description:
+ * @build_tool: a #LatexilaBuildTool.
+ *
+ * Gets the description. The label is returned if the description is empty.
+ *
+ * Returns: the description.
+ */
+const gchar *
+latexila_build_tool_get_description (LatexilaBuildTool *build_tool)
+{
+  if (build_tool->description == NULL ||
+      build_tool->description[0] == '\0')
+    {
+      return build_tool->label;
+    }
+
+  return build_tool->description;
+}
+
+/**
+ * latexila_get_post_processor_type_from_name:
+ * @name: the name of the post-processor.
+ * @type: the output post-processor type.
+ *
+ * Returns: %TRUE on success, %FALSE otherwise.
+ */
+gboolean
+latexila_get_post_processor_type_from_name (const gchar               *name,
+                                            LatexilaPostProcessorType *type)
+{
+  g_assert (type != NULL);
+
+  if (g_str_equal (name, "latexmk"))
+    {
+      *type = LATEXILA_POST_PROCESSOR_TYPE_LATEXMK;
+      return TRUE;
+    }
+
+  if (g_str_equal (name, "latex"))
+    {
+      *type = LATEXILA_POST_PROCESSOR_TYPE_LATEX;
+      return TRUE;
+    }
+
+  if (g_str_equal (name, "all-output"))
+    {
+      *type = LATEXILA_POST_PROCESSOR_TYPE_ALL_OUTPUT;
+      return TRUE;
+    }
+
+  if (g_str_equal (name, "no-output"))
+    {
+      *type = LATEXILA_POST_PROCESSOR_TYPE_NO_OUTPUT;
+      return TRUE;
+    }
+
+  return FALSE;
+}
+
+/**
+ * latexila_get_post_processor_name_from_type:
+ * @type: the post-processor type.
+ *
+ * Returns: the post-processor name.
+ */
+const gchar *
+latexila_get_post_processor_name_from_type (LatexilaPostProcessorType type)
+{
+  switch (type)
+    {
+    case LATEXILA_POST_PROCESSOR_TYPE_LATEXMK:
+      return "latexmk";
+
+    case LATEXILA_POST_PROCESSOR_TYPE_LATEX:
+      return "latex";
+
+    case LATEXILA_POST_PROCESSOR_TYPE_ALL_OUTPUT:
+      return "all-output";
+
+    case LATEXILA_POST_PROCESSOR_TYPE_NO_OUTPUT:
+      return "no-output";
+
+    default:
+      g_return_val_if_reached (NULL);
+    }
+}
+
+static void
+latexila_build_tools_finalize (GObject *object)
+{
+  LatexilaBuildTools *build_tools = LATEXILA_BUILD_TOOLS (object);
+
+  g_list_free_full (build_tools->build_tools, (GDestroyNotify) build_tool_free);
+  build_tool_free (build_tools->priv->cur_tool);
+  build_job_free (build_tools->priv->cur_job);
+
+  G_OBJECT_CLASS (latexila_build_tools_parent_class)->finalize (object);
+}
+
+static void
+latexila_build_tools_class_init (LatexilaBuildToolsClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->finalize = latexila_build_tools_finalize;
+
+  /**
+   * LatexilaBuildTools::changed:
+   * @build_tools: a #LatexilaBuildTools object.
+   *
+   * The ::changed signal is emitted when the build tools contents has changed.
+   * For example when the XML file is fully loaded, or when a build tool is
+   * modified.
+   */
+  signals[SIGNAL_CHANGED] = g_signal_new ("changed",
+                                          LATEXILA_TYPE_BUILD_TOOLS,
+                                          G_SIGNAL_RUN_LAST,
+                                          0, NULL, NULL, NULL,
+                                          G_TYPE_NONE, 0);
+}
+
+static void
+latexila_build_tools_init (LatexilaBuildTools *build_tools)
+{
+  build_tools->priv = latexila_build_tools_get_instance_private (build_tools);
+}
+
+static void
+parser_start_element (GMarkupParseContext  *context,
+                      const gchar          *element_name,
+                      const gchar         **attribute_names,
+                      const gchar         **attribute_values,
+                      gpointer              user_data,
+                      GError              **error)
+{
+  LatexilaBuildTools *build_tools = user_data;
+
+  if (g_str_equal (element_name, "tools") ||
+      g_str_equal (element_name, "label") ||
+      g_str_equal (element_name, "description") ||
+      g_str_equal (element_name, "open"))
+    {
+      /* do nothing */
+    }
+
+  else if (g_str_equal (element_name, "tool"))
+    {
+      LatexilaBuildTool *cur_tool;
+      gint i;
+
+      build_tool_free (build_tools->priv->cur_tool);
+      cur_tool = build_tool_new ();
+      build_tools->priv->cur_tool = cur_tool;
+
+      for (i = 0; attribute_names[i] != NULL; i++)
+        {
+          if (g_str_equal (attribute_names[i], "id"))
+            {
+              cur_tool->id = g_strtod (attribute_values[i], NULL);
+            }
+          /* "show" was the previous name of "enabled" */
+          else if (g_str_equal (attribute_names[i], "show") ||
+                   g_str_equal (attribute_names[i], "enabled"))
+            {
+              cur_tool->enabled = g_str_equal (attribute_values[i], "true");
+            }
+          else if (g_str_equal (attribute_names[i], "extensions"))
+            {
+              cur_tool->extensions = g_strdup (attribute_values[i]);
+            }
+          else if (g_str_equal (attribute_names[i], "icon"))
+            {
+              cur_tool->icon = g_strdup (attribute_values[i]);
+            }
+          else if (error != NULL)
+            {
+              *error = g_error_new (G_MARKUP_ERROR,
+                                    G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE,
+                                    "unknown attribute \"%s\"",
+                                    attribute_names[i]);
+            }
+        }
+    }
+
+  else if (g_str_equal (element_name, "job"))
+    {
+      LatexilaBuildJob *cur_job;
+      gint i;
+
+      build_job_free (build_tools->priv->cur_job);
+      cur_job = build_job_new ();
+      build_tools->priv->cur_job = cur_job;
+
+      for (i = 0; attribute_names[i] != NULL; i++)
+        {
+          if (g_str_equal (attribute_names[i], "postProcessor"))
+            {
+              LatexilaPostProcessorType type;
+
+              if (latexila_get_post_processor_type_from_name (attribute_values[i], &type))
+                {
+                  cur_job->post_processor_type = type;
+                }
+              else if (error != NULL)
+                {
+                  *error = g_error_new (G_MARKUP_ERROR,
+                                        G_MARKUP_ERROR_INVALID_CONTENT,
+                                        "unknown post processor \"%s\"",
+                                        attribute_values[i]);
+                }
+            }
+
+          /* For compatibility (no longer used) */
+          else if (g_str_equal (attribute_names[i], "mustSucceed"))
+            {
+            }
+
+          else if (error != NULL)
+            {
+              *error = g_error_new (G_MARKUP_ERROR,
+                                    G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE,
+                                    "unknown attribute \"%s\"",
+                                    attribute_names[i]);
+            }
+        }
+    }
+
+  else if (error != NULL)
+    {
+      *error = g_error_new (G_MARKUP_ERROR,
+                            G_MARKUP_ERROR_UNKNOWN_ELEMENT,
+                            "unknown element \"%s\"",
+                            element_name);
+    }
+}
+
+static void
+parser_end_element (GMarkupParseContext  *context,
+                    const gchar          *element_name,
+                    gpointer              user_data,
+                    GError              **error)
+{
+  LatexilaBuildTools *build_tools = user_data;
+
+  if (g_str_equal (element_name, "tools") ||
+      g_str_equal (element_name, "label") ||
+      g_str_equal (element_name, "description") ||
+      g_str_equal (element_name, "open"))
+    {
+      /* do nothing */
+    }
+
+  else if (g_str_equal (element_name, "tool"))
+    {
+      LatexilaBuildTool *cur_tool = build_tools->priv->cur_tool;
+
+      cur_tool->jobs = g_slist_reverse (cur_tool->jobs);
+
+      build_tools->build_tools = g_list_prepend (build_tools->build_tools, cur_tool);
+
+      build_tools->priv->cur_tool = NULL;
+    }
+
+  else if (g_str_equal (element_name, "job"))
+    {
+      LatexilaBuildTool *cur_tool = build_tools->priv->cur_tool;
+
+      cur_tool->jobs = g_slist_prepend (cur_tool->jobs,
+                                        build_tools->priv->cur_job);
+
+      build_tools->priv->cur_job = NULL;
+    }
+
+  else if (error != NULL)
+    {
+      *error = g_error_new (G_MARKUP_ERROR,
+                            G_MARKUP_ERROR_UNKNOWN_ELEMENT,
+                            "unknown element \"%s\"",
+                            element_name);
+    }
+}
+
+static void
+parser_text (GMarkupParseContext  *context,
+             const gchar          *text,
+             gsize                 text_len,
+             gpointer              user_data,
+             GError              **error)
+{
+  LatexilaBuildTools *build_tools = user_data;
+  const gchar *element_name = g_markup_parse_context_get_element (context);
+  gchar *stripped_text = g_strdup (text);
+  stripped_text = g_strstrip (stripped_text);
+
+  if (g_str_equal (element_name, "job") &&
+      build_tools->priv->cur_job != NULL)
+    {
+      g_free (build_tools->priv->cur_job->command);
+      build_tools->priv->cur_job->command = stripped_text;
+    }
+
+  else if (g_str_equal (element_name, "label") &&
+           build_tools->priv->cur_tool != NULL)
+    {
+      g_free (build_tools->priv->cur_tool->label);
+      build_tools->priv->cur_tool->label = g_strdup (_(stripped_text));
+
+      g_free (stripped_text);
+    }
+
+  else if (g_str_equal (element_name, "description") &&
+           build_tools->priv->cur_tool != NULL)
+    {
+      g_free (build_tools->priv->cur_tool->description);
+      build_tools->priv->cur_tool->description = g_strdup (_(stripped_text));
+
+      g_free (stripped_text);
+    }
+
+  else if (g_str_equal (element_name, "open") &&
+           build_tools->priv->cur_tool != NULL)
+    {
+      g_free (build_tools->priv->cur_tool->files_to_open);
+      build_tools->priv->cur_tool->files_to_open = stripped_text;
+    }
+
+  else
+    {
+      g_free (stripped_text);
+    }
+}
+
+static void
+parse_contents (LatexilaBuildTools *build_tools,
+                gchar              *contents)
+{
+  GMarkupParser parser;
+  GMarkupParseContext *context;
+  GError *error = NULL;
+
+  parser.start_element = parser_start_element;
+  parser.end_element = parser_end_element;
+  parser.text = parser_text;
+  parser.passthrough = NULL;
+  parser.error = NULL;
+
+  context = g_markup_parse_context_new (&parser, 0, build_tools, NULL);
+
+  g_markup_parse_context_parse (context, contents, -1, &error);
+
+  if (error != NULL)
+    {
+      g_warning ("Error while parsing build tools: %s", error->message);
+      g_error_free (error);
+      error = NULL;
+      goto out;
+    }
+
+  g_markup_parse_context_end_parse (context, &error);
+
+  if (error != NULL)
+    {
+      g_warning ("Error while ending build tools parser: %s", error->message);
+      g_error_free (error);
+      error = NULL;
+      goto out;
+    }
+
+out:
+  build_tools->build_tools = g_list_reverse (build_tools->build_tools);
+
+  g_markup_parse_context_free (context);
+  g_free (contents);
+
+  g_signal_emit (build_tools, signals[SIGNAL_CHANGED], 0);
+}
+
+static void
+load_contents_cb (GFile              *xml_file,
+                  GAsyncResult       *result,
+                  LatexilaBuildTools *build_tools)
+{
+  gchar *contents = NULL;
+  GError *error = NULL;
+
+  g_file_load_contents_finish (xml_file, result, &contents, NULL, NULL, &error);
+
+  if (error != NULL)
+    {
+      if (error->domain == G_IO_ERROR &&
+          error->code == G_IO_ERROR_NOT_FOUND)
+        {
+          if (LATEXILA_IS_BUILD_TOOLS_DEFAULT (build_tools))
+            {
+              g_warning ("XML file not found for the default build tools: %s",
+                         g_file_get_parse_name (xml_file));
+            }
+
+          /* For the personal build tools it means that there is simply no
+           * personal build tools, it is not an error.
+           */
+        }
+      else
+        {
+          g_warning ("Error while loading the contents of the build tools XML file: %s",
+                     error->message);
+        }
+
+      g_error_free (error);
+      return;
+    }
+
+  if (contents != NULL)
+    {
+      parse_contents (build_tools, contents);
+    }
+}
+
+/**
+ * latexila_build_tools_load:
+ * @build_tools:
+ * @xml_file:
+ *
+ * Loads asynchronously the XML file contents and parses it.
+ * Used by subclasses of #LatexilaBuildTools.
+ */
+void
+latexila_build_tools_load (LatexilaBuildTools *build_tools,
+                           GFile              *xml_file)
+{
+  g_return_if_fail (LATEXILA_IS_BUILD_TOOLS (build_tools));
+  g_return_if_fail (G_IS_FILE (xml_file));
+
+  g_file_load_contents_async (xml_file,
+                              NULL,
+                              (GAsyncReadyCallback) load_contents_cb,
+                              build_tools);
+}
+
+/**
+ * latexila_build_tools_set_enabled:
+ * @build_tools:
+ * @tool_num:
+ * @enabled:
+ */
+void
+latexila_build_tools_set_enabled (LatexilaBuildTools *build_tools,
+                                  guint               tool_num,
+                                  gboolean            enabled)
+{
+  LatexilaBuildTool *build_tool = g_list_nth_data (build_tools->build_tools, tool_num);
+
+  g_return_if_fail (build_tool != NULL);
+
+  if (build_tool->enabled != enabled)
+    {
+      build_tool->enabled = enabled;
+      g_signal_emit (build_tools, signals[SIGNAL_CHANGED], 0);
+    }
+}
diff --git a/src/liblatexila/latexila-build-tools.h b/src/liblatexila/latexila-build-tools.h
new file mode 100644
index 0000000..2f678af
--- /dev/null
+++ b/src/liblatexila/latexila-build-tools.h
@@ -0,0 +1,104 @@
+/*
+ * This file is part of LaTeXila.
+ *
+ * Copyright (C) 2014 - Sébastien Wilmet <swilmet gnome org>
+ *
+ * LaTeXila is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * LaTeXila is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with LaTeXila.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __LATEXILA_BUILD_TOOLS_H__
+#define __LATEXILA_BUILD_TOOLS_H__
+
+#include <gio/gio.h>
+#include "latexila-types.h"
+
+G_BEGIN_DECLS
+
+#define LATEXILA_TYPE_BUILD_TOOLS             (latexila_build_tools_get_type ())
+#define LATEXILA_BUILD_TOOLS(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), LATEXILA_TYPE_BUILD_TOOLS, 
LatexilaBuildTools))
+#define LATEXILA_BUILD_TOOLS_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), LATEXILA_TYPE_BUILD_TOOLS, 
LatexilaBuildToolsClass))
+#define LATEXILA_IS_BUILD_TOOLS(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), LATEXILA_TYPE_BUILD_TOOLS))
+#define LATEXILA_IS_BUILD_TOOLS_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), LATEXILA_TYPE_BUILD_TOOLS))
+#define LATEXILA_BUILD_TOOLS_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), LATEXILA_TYPE_BUILD_TOOLS, 
LatexilaBuildToolsClass))
+
+typedef struct _LatexilaBuildToolsClass   LatexilaBuildToolsClass;
+typedef struct _LatexilaBuildToolsPrivate LatexilaBuildToolsPrivate;
+
+struct _LatexilaBuildTools
+{
+  GObject parent;
+
+  /* A list of LatexilaBuildTool's */
+  GList *build_tools;
+
+  LatexilaBuildToolsPrivate *priv;
+};
+
+struct _LatexilaBuildToolsClass
+{
+  GObjectClass parent_class;
+};
+
+typedef enum
+{
+  LATEXILA_POST_PROCESSOR_TYPE_NO_OUTPUT,
+  LATEXILA_POST_PROCESSOR_TYPE_ALL_OUTPUT,
+  LATEXILA_POST_PROCESSOR_TYPE_LATEX,
+  LATEXILA_POST_PROCESSOR_TYPE_LATEXMK
+} LatexilaPostProcessorType;
+
+typedef struct
+{
+  LatexilaPostProcessorType post_processor_type;
+  gchar *command;
+} LatexilaBuildJob;
+
+typedef struct
+{
+  gchar *label;
+  gchar *description;
+  gchar *extensions;
+  gchar *icon;
+  gchar *files_to_open;
+
+  /* A list of LatexilaBuildJob's */
+  GSList *jobs;
+
+  /* The id is used only by the default build tools.
+   * It is used to save those are enabled or disabled.
+   */
+  gint id;
+
+  guint enabled : 1;
+} LatexilaBuildTool;
+
+GType                 latexila_build_tools_get_type                 (void) G_GNUC_CONST;
+
+const gchar *         latexila_build_tool_get_description           (LatexilaBuildTool *build_tool);
+
+gboolean              latexila_get_post_processor_type_from_name    (const gchar               *name,
+                                                                     LatexilaPostProcessorType *type);
+
+const gchar *         latexila_get_post_processor_name_from_type    (LatexilaPostProcessorType type);
+
+void                  latexila_build_tools_load                     (LatexilaBuildTools *build_tools,
+                                                                     GFile              *xml_file);
+
+void                  latexila_build_tools_set_enabled              (LatexilaBuildTools *build_tools,
+                                                                     guint               tool_num,
+                                                                     gboolean            enabled);
+
+G_END_DECLS
+
+#endif /* __LATEXILA_BUILD_TOOLS_H__ */
diff --git a/src/liblatexila/latexila-post-processor-all-output.h 
b/src/liblatexila/latexila-post-processor-all-output.h
index 44c4926..6ae5d67 100644
--- a/src/liblatexila/latexila-post-processor-all-output.h
+++ b/src/liblatexila/latexila-post-processor-all-output.h
@@ -20,7 +20,9 @@
 #ifndef __LATEXILA_POST_PROCESSOR_ALL_OUTPUT_H__
 #define __LATEXILA_POST_PROCESSOR_ALL_OUTPUT_H__
 
+#include <glib-object.h>
 #include "latexila-post-processor.h"
+#include "latexila-types.h"
 
 G_BEGIN_DECLS
 
@@ -31,7 +33,6 @@ G_BEGIN_DECLS
 #define LATEXILA_IS_POST_PROCESSOR_ALL_OUTPUT_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), 
LATEXILA_TYPE_POST_PROCESSOR_ALL_OUTPUT))
 #define LATEXILA_POST_PROCESSOR_ALL_OUTPUT_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), 
LATEXILA_TYPE_POST_PROCESSOR_ALL_OUTPUT, LatexilaPostProcessorAllOutputClass))
 
-typedef struct _LatexilaPostProcessorAllOutput        LatexilaPostProcessorAllOutput;
 typedef struct _LatexilaPostProcessorAllOutputClass   LatexilaPostProcessorAllOutputClass;
 typedef struct _LatexilaPostProcessorAllOutputPrivate LatexilaPostProcessorAllOutputPrivate;
 
diff --git a/src/liblatexila/latexila-post-processor.h b/src/liblatexila/latexila-post-processor.h
index f8096bc..b889d38 100644
--- a/src/liblatexila/latexila-post-processor.h
+++ b/src/liblatexila/latexila-post-processor.h
@@ -22,6 +22,7 @@
 
 #include <glib.h>
 #include <glib-object.h>
+#include "latexila-types.h"
 
 G_BEGIN_DECLS
 
@@ -32,7 +33,6 @@ G_BEGIN_DECLS
 #define LATEXILA_IS_POST_PROCESSOR_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), 
LATEXILA_TYPE_POST_PROCESSOR))
 #define LATEXILA_POST_PROCESSOR_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), 
LATEXILA_TYPE_POST_PROCESSOR, LatexilaPostProcessorClass))
 
-typedef struct _LatexilaPostProcessor        LatexilaPostProcessor;
 typedef struct _LatexilaPostProcessorClass   LatexilaPostProcessorClass;
 typedef struct _LatexilaPostProcessorPrivate LatexilaPostProcessorPrivate;
 
diff --git a/src/liblatexila/latexila-types.h b/src/liblatexila/latexila-types.h
new file mode 100644
index 0000000..64f5523
--- /dev/null
+++ b/src/liblatexila/latexila-types.h
@@ -0,0 +1,35 @@
+/*
+ * This file is part of LaTeXila.
+ *
+ * Copyright (C) 2014 - Sébastien Wilmet <swilmet gnome org>
+ *
+ * LaTeXila is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * LaTeXila is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with LaTeXila.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __LATEXILA_TYPES_H__
+#define __LATEXILA_TYPES_H__
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+typedef struct _LatexilaBuildTools              LatexilaBuildTools;
+typedef struct _LatexilaBuildToolsDefault       LatexilaBuildToolsDefault;
+typedef struct _LatexilaBuildToolsPersonal      LatexilaBuildToolsPersonal;
+typedef struct _LatexilaPostProcessor           LatexilaPostProcessor;
+typedef struct _LatexilaPostProcessorAllOutput  LatexilaPostProcessorAllOutput;
+
+G_END_DECLS
+
+#endif /* __LATEXILA_TYPES_H__ */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]