[gedit-cossa] Add standalone previewer



commit 702c1d53c1918bcb34af70aa50d312cc6f4a6406
Author: Carlos Garnacho <carlosg gnome org>
Date:   Thu Jun 2 12:06:08 2011 +0200

    Add standalone previewer
    
    This is a separate executable with no editor interaction, just
    monitors CSS files and displays the changes.

 src/Makefile.am         |   22 ++++-
 src/cossa-application.c |  251 +++++++++++++++++++++++++++++++++++++++++++++++
 src/cossa-application.h |   56 +++++++++++
 src/cossa-main.c        |   55 ++++++++++
 4 files changed, 380 insertions(+), 4 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index 3d05c4f..17669ef 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -9,9 +9,9 @@ INCLUDES = \
         $(COSSA_CFLAGS)                                           \
         $(DISABLE_DEPRECATED_CFLAGS)
 
-plugin_LTLIBRARIES = libcossa.la
+noinst_LTLIBRARIES = libcossa-common.la
 
-libcossa_la_SOURCES = \
+libcossa_common_la_SOURCES =     \
 	cossa-previewer.h        \
 	cossa-previewer.c        \
 	cossa-style-provider.h   \
@@ -19,12 +19,26 @@ libcossa_la_SOURCES = \
 	cossa-tool-menu-action.h \
 	cossa-tool-menu-action.c \
 	cossa-window.h           \
-	cossa-window.c           \
+	cossa-window.c
+
+plugin_LTLIBRARIES = libcossa.la
+
+libcossa_la_SOURCES = \
 	gedit-cossa-plugin.h     \
 	gedit-cossa-plugin.c
 
 libcossa_la_LDFLAGS = $(COSSA_FLAGS)
-libcossa_la_LIBADD  = $(COSSA_LIBS)
+libcossa_la_LIBADD  = $(COSSA_LIBS) libcossa-common.la
+
+bin_PROGRAMS = cossa-standalone-previewer
+
+cossa_standalone_previewer_SOURCES = \
+	cossa-application.c          \
+	cossa-application.h          \
+	cossa-main.c
+
+cossa_standalone_previewer_LDFLAGS = $(COSSA_FLAGS)
+cossa_standalone_previewer_LDADD = $(COSSA_LIBS) libcossa-common.la
 
 plugin_in_files = cossa.plugin.desktop.in
 
diff --git a/src/cossa-application.c b/src/cossa-application.c
new file mode 100644
index 0000000..345734b
--- /dev/null
+++ b/src/cossa-application.c
@@ -0,0 +1,251 @@
+/*
+ * Cossa standalone applicaton
+ *
+ * ©2011 Carlos Garnacho <carlosg gnome org>
+ *
+ * This program 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 2, or (at your option)
+ * any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+#include "cossa-application.h"
+#include "cossa-window.h"
+
+typedef struct CossaApplicationPrivate CossaApplicationPrivate;
+typedef struct WindowData WindowData;
+
+struct WindowData {
+  GtkWidget *window;
+  GFile *file;
+  GFileMonitor *monitor;
+};
+
+struct CossaApplicationPrivate
+{
+  GList *windows;
+};
+
+G_DEFINE_TYPE (CossaApplication, cossa_application, GTK_TYPE_APPLICATION)
+
+static WindowData *
+lookup_window_data_by_file (CossaApplication *application,
+                            GFile            *file)
+{
+  CossaApplicationPrivate *priv = application->priv;
+  GList *l;
+
+  for (l = priv->windows; l; l = l->next)
+    {
+      WindowData *data = l->data;
+
+      if (g_file_equal (file, data->file))
+        return data;
+    }
+
+  return NULL;
+}
+
+static WindowData *
+lookup_window_data (CossaApplication *application,
+                    GtkWidget        *window)
+{
+  CossaApplicationPrivate *priv = application->priv;
+  GList *l;
+
+  for (l = priv->windows; l; l = l->next)
+    {
+      WindowData *data = l->data;
+
+      if (window == data->window)
+        return data;
+    }
+
+  return NULL;
+}
+
+static WindowData *
+window_data_new (GFile *file)
+{
+  WindowData *data;
+  gchar *name, *title;
+
+  data = g_slice_new0 (WindowData);
+
+  data->file = g_object_ref (file);
+  data->window = cossa_window_new ();
+
+  gtk_window_set_default_size (GTK_WINDOW (data->window), 400, 400);
+
+  name = g_file_get_parse_name (file);
+  title = g_strdup_printf ("Cossa - %s", name);
+  g_free (name);
+
+  gtk_window_set_title (GTK_WINDOW (data->window), title);
+  g_free (title);
+
+  /* Set up file monitor */
+  data->monitor = g_file_monitor_file (file,
+                                       G_FILE_MONITOR_NONE,
+                                       NULL, NULL);
+  return data;
+}
+
+static void
+window_data_free (WindowData *data)
+{
+  gtk_widget_destroy (data->window);
+  g_object_unref (data->file);
+
+  g_file_monitor_cancel (data->monitor);
+  g_object_unref (data->monitor);
+
+  g_slice_free (WindowData, data);
+}
+
+static void
+_cossa_application_update_window (CossaApplication *application,
+                                  GFile            *file)
+{
+  CossaApplication *app;
+  CossaPreviewer *preview;
+  GtkCssProvider *style;
+  WindowData *data;
+
+  app = COSSA_APPLICATION (application);
+  data = lookup_window_data_by_file (app, file);
+
+  if (!data)
+    return;
+
+  preview = cossa_window_get_previewer (COSSA_WINDOW (data->window));
+  style = cossa_previewer_get_style (COSSA_PREVIEWER (preview));
+
+  if (gtk_css_provider_load_from_file (style, file, NULL))
+    cossa_previewer_update_samples (preview);
+}
+
+static void
+file_changed_cb (GFileMonitor      *monitor,
+                 GFile             *file,
+                 GFile             *other_file,
+                 GFileMonitorEvent  event_type,
+                 gpointer           user_data)
+{
+  if (event_type == G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT)
+    _cossa_application_update_window (COSSA_APPLICATION (user_data), file);
+}
+
+static void
+close_window_cb (GtkWidget *window,
+                 GdkEvent  *event,
+                 gpointer   user_data)
+{
+  CossaApplicationPrivate *priv;
+  CossaApplication *app;
+  WindowData *data;
+
+  app = COSSA_APPLICATION (user_data);
+  data = lookup_window_data (app, window);
+  priv = app->priv;
+
+  if (data)
+    {
+      priv->windows = g_list_remove (priv->windows, data);
+      gtk_application_remove_window (GTK_APPLICATION (app),
+                                     GTK_WINDOW (data->window));
+      window_data_free (data);
+    }
+}
+
+static void
+cossa_application_open (GApplication  *application,
+                        GFile        **files,
+                        gint           n_files,
+                        const gchar   *hint)
+{
+  CossaApplication *app;
+  CossaApplicationPrivate *priv;
+  gint i;
+
+  app = COSSA_APPLICATION (application);
+  priv = app->priv;
+
+  for (i = 0; i < n_files; i++)
+    {
+      WindowData *data;
+      GFile *file;
+
+      file = files[i];
+      data = lookup_window_data_by_file (app, file);
+
+      if (!data)
+        {
+          data = window_data_new (file);
+          priv->windows = g_list_prepend (priv->windows, data);
+
+          g_signal_connect (data->window, "delete-event",
+                            G_CALLBACK (close_window_cb), app);
+
+          gtk_application_add_window (GTK_APPLICATION (application),
+                                      GTK_WINDOW (data->window));
+
+          if (data->monitor)
+            {
+              g_signal_connect (data->monitor, "changed",
+                                G_CALLBACK (file_changed_cb),
+                                application);
+            }
+
+          _cossa_application_update_window (app, file);
+        }
+
+      if (!gtk_widget_is_drawable (data->window))
+        gtk_widget_show (data->window);
+      else
+        gtk_window_present (GTK_WINDOW (data->window));
+    }
+}
+
+static void
+cossa_application_activate (GApplication *application)
+{
+}
+
+static void
+cossa_application_class_init (CossaApplicationClass *klass)
+{
+  GApplicationClass *application_class = G_APPLICATION_CLASS (klass);
+
+  application_class->open = cossa_application_open;
+  application_class->activate = cossa_application_activate;
+
+  g_type_class_add_private (klass, sizeof (CossaApplicationPrivate));
+}
+
+static void
+cossa_application_init (CossaApplication *application)
+{
+  application->priv = G_TYPE_INSTANCE_GET_PRIVATE (application,
+                                                   COSSA_TYPE_APPLICATION,
+                                                   CossaApplicationPrivate);
+}
+
+GApplication *
+cossa_application_new (void)
+{
+  return g_object_new (COSSA_TYPE_APPLICATION,
+                       "application-id", "org.gnome.Cossa",
+                       "flags", G_APPLICATION_HANDLES_OPEN,
+                       NULL);
+}
diff --git a/src/cossa-application.h b/src/cossa-application.h
new file mode 100644
index 0000000..5f4b55d
--- /dev/null
+++ b/src/cossa-application.h
@@ -0,0 +1,56 @@
+/*
+ * Cossa standalone applicaton
+ *
+ * ©2011 Carlos Garnacho <carlosg gnome org>
+ *
+ * This program 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 2, or (at your option)
+ * any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __COSSA_APPLICATION_H__
+#define __COSSA_APPLICATION_H__
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define COSSA_TYPE_APPLICATION         (cossa_application_get_type ())
+#define COSSA_APPLICATION(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), COSSA_TYPE_APPLICATION, CossaApplication))
+#define COSSA_APPLICATION_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), COSSA_TYPE_APPLICATION, CossaApplicationClass))
+#define COSSA_IS_APPLICATION(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), COSSA_TYPE_APPLICATION))
+#define COSSA_IS_APPLICATION_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), COSSA_TYPE_APPLICATION))
+#define COSSA_APPLICATION_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), COSSA_TYPE_APPLICATION, CossaApplicationClass))
+
+typedef struct _CossaApplication CossaApplication;
+typedef struct _CossaApplicationClass CossaApplicationClass;
+
+struct _CossaApplication
+{
+  GtkApplication parent_instance;
+  gpointer priv;
+};
+
+struct _CossaApplicationClass
+{
+  GtkApplicationClass parent_class;
+};
+
+GType            cossa_application_get_type      (void) G_GNUC_CONST;
+
+GApplication *   cossa_application_new           (void);
+
+
+G_END_DECLS
+
+#endif /* __COSSA_APPLICATION_H__ */
diff --git a/src/cossa-main.c b/src/cossa-main.c
new file mode 100644
index 0000000..30ef4d3
--- /dev/null
+++ b/src/cossa-main.c
@@ -0,0 +1,55 @@
+/*
+ * Cossa standalone applicaton
+ *
+ * ©2011 Carlos Garnacho <carlosg gnome org>
+ *
+ * This program 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 2, or (at your option)
+ * any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+#include "cossa-application.h"
+#include <gtk/gtk.h>
+#include <stdlib.h>
+
+int
+main (int argc, char *argv[])
+{
+  GApplication *application;
+  GError *error = NULL;
+  int status;
+
+  g_type_init ();
+  application = cossa_application_new ();
+
+  g_application_register (application, NULL, &error);
+
+  if (error)
+    {
+      g_warning ("Could not initialize application: %s", error->message);
+      g_error_free (error);
+      return EXIT_FAILURE;
+    }
+
+  if (argc < 2)
+    {
+      g_printerr ("USAGE - %s <FILE>\n", argv[0]);
+      return EXIT_FAILURE;
+    }
+
+  status = g_application_run (G_APPLICATION (application), argc, argv);
+  g_object_unref (application);
+
+  return status;
+}



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