gtranslator r3593 - in trunk: . plugins plugins/source-view src
- From: icq svn gnome org
- To: svn-commits-list gnome org
- Subject: gtranslator r3593 - in trunk: . plugins plugins/source-view src
- Date: Mon, 22 Sep 2008 09:38:11 +0000 (UTC)
Author: icq
Date: Mon Sep 22 09:38:11 2008
New Revision: 3593
URL: http://svn.gnome.org/viewvc/gtranslator?rev=3593&view=rev
Log:
Merge source-code-view into the master branch to implement feature Source view plugin
Added:
trunk/plugins/source-view/
trunk/plugins/source-view/Makefile.am
trunk/plugins/source-view/source-view-dialog.glade
trunk/plugins/source-view/source-view-plugin.c
trunk/plugins/source-view/source-view-plugin.h
trunk/plugins/source-view/source-view.gtranslator-plugin.desktop.in
trunk/plugins/source-view/viewer.c
trunk/plugins/source-view/viewer.glade
trunk/plugins/source-view/viewer.h
Modified:
trunk/ChangeLog
trunk/configure.ac
trunk/plugins/Makefile.am
trunk/src/comment.c
trunk/src/comment.h
Modified: trunk/configure.ac
==============================================================================
--- trunk/configure.ac (original)
+++ trunk/configure.ac Mon Sep 22 09:38:11 2008
@@ -303,6 +303,7 @@
plugins/fullscreen/Makefile
plugins/insert-tags/Makefile
plugins/open-tran/Makefile
+plugins/source-view/Makefile
src/Makefile
src/dialogs/Makefile
src/toolbareditor/Makefile
Modified: trunk/plugins/Makefile.am
==============================================================================
--- trunk/plugins/Makefile.am (original)
+++ trunk/plugins/Makefile.am Mon Sep 22 09:38:11 2008
@@ -1,7 +1,8 @@
SUBDIRS = \
alternate-language \
fullscreen \
- insert-tags
+ insert-tags \
+ source-view
if USE_CHARMAP
SUBDIRS += charmap
Added: trunk/plugins/source-view/Makefile.am
==============================================================================
--- (empty file)
+++ trunk/plugins/source-view/Makefile.am Mon Sep 22 09:38:11 2008
@@ -0,0 +1,45 @@
+# source-view plugin
+plugindir = $(libdir)/gtranslator/plugins
+
+INCLUDES = \
+ -I$(top_srcdir) \
+ -I$(top_srcdir)/src \
+ -I$(top_srcdir)/src/plugin-system \
+ $(GTRANSLATOR_CFLAGS) \
+ $(WARN_CFLAGS) \
+ $(DISABLE_DEPRECATED_CFLAGS) \
+ -DDATADIR=\""$(pkgdatadir)"\" \
+ -DGTR_LOCALEDIR=\""$(prefix)/$(DATADIRNAME)/locale"\"
+
+plugin_LTLIBRARIES = \
+ libsourceview.la
+
+libsourceview_la_SOURCES = \
+ source-view-plugin.c \
+ source-view-plugin.h \
+ viewer.c \
+ viewer.h
+
+libsourceview_la_LDFLAGS = \
+ $(PLUGIN_LIBTOOL_FLAGS) \
+ $(GTRANSLATOR_LIBS)
+
+gladedir = $(pkgdatadir)
+
+glade_DATA = \
+ viewer.glade \
+ source-view-dialog.glade
+
+# Plugin Info
+
+plugin_in_files = source-view.gtranslator-plugin.desktop.in
+
+%.gtranslator.plugin: %.gtranslator-plugin.desktop.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
+
+plugin_DATA = $(plugin_in_files:.gtranslator-plugin.desktop.in=.gtranslator.plugin)
+
+EXTRA_DIST = $(plugin_in_files)
+
+CLEANFILES = $(plugin_DATA)
+DISTCLEANFILES = $(plugin_DATA)
+
Added: trunk/plugins/source-view/source-view-dialog.glade
==============================================================================
--- (empty file)
+++ trunk/plugins/source-view/source-view-dialog.glade Mon Sep 22 09:38:11 2008
@@ -0,0 +1,174 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
+<!--Generated with glade3 3.4.5 on Mon Jun 30 12:37:34 2008 -->
+<glade-interface>
+ <widget class="GtkDialog" id="dialog">
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="border_width">5</property>
+ <property name="title" translatable="yes">Source View Settings</property>
+ <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+ <property name="has_separator">False</property>
+ <child internal-child="vbox">
+ <widget class="GtkVBox" id="dialog-vbox1">
+ <property name="visible">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="spacing">2</property>
+ <child>
+ <widget class="GtkVBox" id="main_box">
+ <property name="visible">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="border_width">12</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkCheckButton" id="use_editor">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">Use external editor</property>
+ <property name="response_id">0</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="program_box">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes"><b>Program command:</b></property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox1">
+ <property name="visible">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="label" translatable="yes"> </property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkEntry" id="program_cmd">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="tooltip_text">E.g.: gedit</property>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes"><b>Line command:</b></property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox2">
+ <property name="visible">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <child>
+ <widget class="GtkLabel" id="label4">
+ <property name="visible">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="label" translatable="yes"> </property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkEntry" id="line_cmd">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="tooltip_text">E.g.: +</property>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child internal-child="action_area">
+ <widget class="GtkHButtonBox" id="dialog-action_area1">
+ <property name="visible">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="layout_style">GTK_BUTTONBOX_END</property>
+ <child>
+ <widget class="GtkButton" id="cancel_button">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="label" translatable="yes">gtk-cancel</property>
+ <property name="use_stock">True</property>
+ <property name="response_id">-6</property>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkButton" id="ok_button">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="label" translatable="yes">gtk-ok</property>
+ <property name="use_stock">True</property>
+ <property name="response_id">-5</property>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="pack_type">GTK_PACK_END</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+</glade-interface>
Added: trunk/plugins/source-view/source-view-plugin.c
==============================================================================
--- (empty file)
+++ trunk/plugins/source-view/source-view-plugin.c Mon Sep 22 09:38:11 2008
@@ -0,0 +1,696 @@
+/*
+ * Copyright (C) 2008 Ignacio Casal Quinteiro <nacho resa gmail com>
+ *
+ * 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 3 of the License, 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
+ * MERCHANPOILITY 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, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "source-view-plugin.h"
+#include "comment.h"
+#include "utils.h"
+#include "viewer.h"
+#include "window.h"
+
+#include <glib/gi18n-lib.h>
+#include <gtk/gtk.h>
+#include <string.h>
+#include <gio/gio.h>
+#include <gconf/gconf-client.h>
+
+/* Gconf keys */
+#define SOURCE_VIEW_BASE_KEY "/apps/gtranslator/plugins/source-view"
+#define USE_EDITOR_KEY SOURCE_VIEW_BASE_KEY "/use_editor"
+#define PROGRAM_CMD_KEY SOURCE_VIEW_BASE_KEY "/program_cmd"
+#define LINE_CMD_KEY SOURCE_VIEW_BASE_KEY "/line_cmd"
+
+/* Glade */
+#define GLADE_FILE DATADIR"/source-view-dialog.glade"
+
+#define GTR_SOURCE_VIEW_PLUGIN_GET_PRIVATE(object) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((object), \
+ GTR_TYPE_SOURCE_VIEW_PLUGIN, \
+ GtranslatorSourceViewPluginPrivate))
+
+struct _GtranslatorSourceViewPluginPrivate
+{
+ GConfClient *gconf_client;
+
+ /* Dialog stuff */
+ GtkWidget *dialog;
+
+ GtkWidget *main_box;
+ GtkWidget *use_editor_checkbutton;
+ GtkWidget *program_box;
+ GtkWidget *program_cmd_entry;
+ GtkWidget *line_cmd_entry;
+
+ GtranslatorWindow *window;
+
+ gint inserted_lines;
+};
+
+GTR_PLUGIN_REGISTER_TYPE(GtranslatorSourceViewPlugin, gtranslator_source_view_plugin)
+
+static void
+insert_link (GtkTextBuffer *buffer,
+ GtkTextIter *iter,
+ const gchar *path,
+ gint *line)
+{
+ GtkTextTag *tag;
+ gchar *text;
+
+ tag = gtk_text_buffer_create_tag (buffer, NULL,
+ "foreground", "blue",
+ "underline", PANGO_UNDERLINE_SINGLE,
+ NULL);
+ g_object_set_data (G_OBJECT (tag), "path", g_strdup (path));
+ g_object_set_data (G_OBJECT (tag), "line", line);
+
+ text = g_strconcat (path, "\n", NULL);
+ gtk_text_buffer_insert_with_tags (buffer, iter, text, -1, tag, NULL);
+ g_free (text);
+}
+
+static void
+show_in_editor (const gchar *program_name,
+ const gchar *line_cmd,
+ const gchar *path,
+ gint line)
+{
+ gchar *open[4];
+
+ if (g_find_program_in_path (program_name))
+ {
+ open[0] = g_strdup (program_name);
+ }
+ else
+ {
+ GtkWidget *dialog;
+
+ dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL,
+ GTK_DIALOG_MODAL,
+ GTK_BUTTONS_CLOSE,
+ _("Please, install %s to be able to show the file"),
+ program_name);
+ gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+ }
+
+ open[1] = g_strdup (path);
+ open[2] = g_strdup_printf ("%s%d",line_cmd, line);
+ open[3] = NULL;
+
+ gdk_spawn_on_screen (gdk_screen_get_default (),
+ NULL,
+ open,
+ NULL,
+ G_SPAWN_SEARCH_PATH,
+ NULL,
+ NULL, NULL, NULL);
+ g_free (open[0]);
+ g_free (open[1]);
+ g_free (open[2]);
+}
+
+static void
+show_source (GtranslatorSourceViewPlugin *plugin,
+ const gchar *path,
+ gint line)
+{
+ gboolean use_editor;
+
+ use_editor = gconf_client_get_bool (plugin->priv->gconf_client,
+ USE_EDITOR_KEY,
+ NULL);
+
+ if (use_editor)
+ {
+ gchar *program_cmd;
+ gchar *line_cmd;
+
+ //Program cmd
+ program_cmd = gconf_client_get_string (plugin->priv->gconf_client,
+ PROGRAM_CMD_KEY,
+ NULL);
+
+ //Line cmd
+ line_cmd = gconf_client_get_string (plugin->priv->gconf_client,
+ LINE_CMD_KEY,
+ NULL);
+
+ show_in_editor (program_cmd,
+ line_cmd,
+ path, line);
+
+ g_free (program_cmd);
+ g_free (line_cmd);
+ }
+ else gtranslator_show_viewer (plugin->priv->window,
+ path, line);
+}
+
+static void
+follow_if_link (GtranslatorSourceViewPlugin *plugin,
+ GtkWidget *text_view,
+ GtkTextIter *iter)
+{
+ GSList *tags = NULL, *tagp = NULL;
+ GtranslatorTab *tab;
+ GtranslatorPo *po;
+ const gchar *po_path;
+ gchar *fullpath;
+ gchar *dirname;
+
+ tab = gtranslator_window_get_active_tab (plugin->priv->window);
+
+ if (!tab)
+ return;
+ po = gtranslator_tab_get_po (tab);
+
+ po_path = gtranslator_po_get_filename (po);
+ dirname = g_path_get_dirname (po_path);
+
+ tags = gtk_text_iter_get_tags (iter);
+ for (tagp = tags; tagp != NULL; tagp = tagp->next)
+ {
+ GtkTextTag *tag = tagp->data;
+ gchar *path = g_object_get_data (G_OBJECT (tag), "path");
+ gint line = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (tag), "line"));
+
+ fullpath = g_build_filename (dirname, path, NULL);
+ show_source (plugin, fullpath, line);
+
+ g_free (fullpath);
+ }
+
+ if (tags)
+ g_slist_free (tags);
+
+ g_free (dirname);
+}
+
+static gboolean
+event_after (GtkWidget *text_view,
+ GdkEvent *ev,
+ GtranslatorSourceViewPlugin *plugin)
+{
+ GtkTextIter start, end, iter;
+ GtkTextBuffer *buffer;
+ GdkEventButton *event;
+ gint x, y;
+
+ if (ev->type != GDK_BUTTON_RELEASE)
+ return FALSE;
+
+ event = (GdkEventButton *)ev;
+
+ if (event->button != 1)
+ return FALSE;
+
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_view));
+
+ /* we shouldn't follow a link if the user has selected something */
+ gtk_text_buffer_get_selection_bounds (buffer, &start, &end);
+ if (gtk_text_iter_get_offset (&start) != gtk_text_iter_get_offset (&end))
+ return FALSE;
+
+ gtk_text_view_window_to_buffer_coords (GTK_TEXT_VIEW (text_view),
+ GTK_TEXT_WINDOW_WIDGET,
+ event->x, event->y, &x, &y);
+
+ gtk_text_view_get_iter_at_location (GTK_TEXT_VIEW (text_view), &iter, x, y);
+
+ follow_if_link (plugin, text_view, &iter);
+
+ return FALSE;
+}
+
+static gboolean hovering_over_link = FALSE;
+static GdkCursor *hand_cursor = NULL;
+static GdkCursor *regular_cursor = NULL;
+
+/* Looks at all tags covering the position (x, y) in the text view,
+ * and if one of them is a link, change the cursor to the "hands" cursor
+ * typically used by web browsers.
+ */
+static void
+set_cursor_if_appropriate (GtkTextView *text_view,
+ gint x,
+ gint y)
+{
+ GSList *tags = NULL, *tagp = NULL;
+ GtkTextIter iter;
+ gboolean hovering = FALSE;
+
+ gtk_text_view_get_iter_at_location (text_view, &iter, x, y);
+
+ tags = gtk_text_iter_get_tags (&iter);
+ for (tagp = tags; tagp != NULL; tagp = tagp->next)
+ {
+ GtkTextTag *tag = tagp->data;
+ gchar *path = g_object_get_data (G_OBJECT (tag), "path");
+
+ if (path)
+ {
+ hovering = TRUE;
+ break;
+ }
+ }
+
+ if (hovering != hovering_over_link)
+ {
+ hovering_over_link = hovering;
+
+ if (hovering_over_link)
+ gdk_window_set_cursor (gtk_text_view_get_window (text_view,
+ GTK_TEXT_WINDOW_TEXT),
+ hand_cursor);
+ else
+ gdk_window_set_cursor (gtk_text_view_get_window (text_view,
+ GTK_TEXT_WINDOW_TEXT),
+ regular_cursor);
+ }
+
+ if (tags)
+ g_slist_free (tags);
+}
+
+/*
+ * Update the cursor image if the pointer moved.
+ */
+static gboolean
+motion_notify_event (GtkWidget *text_view,
+ GdkEventMotion *event)
+{
+ gint x, y;
+
+ gtk_text_view_window_to_buffer_coords (GTK_TEXT_VIEW (text_view),
+ GTK_TEXT_WINDOW_WIDGET,
+ event->x, event->y, &x, &y);
+
+ set_cursor_if_appropriate (GTK_TEXT_VIEW (text_view), x, y);
+
+ gdk_window_get_pointer (text_view->window, NULL, NULL, NULL);
+ return FALSE;
+}
+
+/* Also update the cursor image if the window becomes visible
+ * (e.g. when a window covering it got iconified).
+ */
+static gboolean
+visibility_notify_event (GtkWidget *text_view,
+ GdkEventVisibility *event)
+{
+ gint wx, wy, bx, by;
+
+ gdk_window_get_pointer (text_view->window, &wx, &wy, NULL);
+
+ gtk_text_view_window_to_buffer_coords (GTK_TEXT_VIEW (text_view),
+ GTK_TEXT_WINDOW_WIDGET,
+ wx, wy, &bx, &by);
+
+ set_cursor_if_appropriate (GTK_TEXT_VIEW (text_view), bx, by);
+
+ return FALSE;
+}
+
+static void
+gtranslator_source_view_plugin_init (GtranslatorSourceViewPlugin *plugin)
+{
+ plugin->priv = GTR_SOURCE_VIEW_PLUGIN_GET_PRIVATE (plugin);
+
+ plugin->priv->gconf_client = gconf_client_get_default ();
+
+ gconf_client_add_dir (plugin->priv->gconf_client,
+ SOURCE_VIEW_BASE_KEY,
+ GCONF_CLIENT_PRELOAD_ONELEVEL,
+ NULL);
+}
+
+static void
+gtranslator_source_view_plugin_finalize (GObject *object)
+{
+ GtranslatorSourceViewPlugin *plugin = GTR_SOURCE_VIEW_PLUGIN (object);
+
+ gconf_client_suggest_sync (plugin->priv->gconf_client, NULL);
+
+ g_object_unref (G_OBJECT (plugin->priv->gconf_client));
+
+ G_OBJECT_CLASS (gtranslator_source_view_plugin_parent_class)->finalize (object);
+}
+
+static void
+showed_message_cb (GtranslatorTab *tab,
+ GtranslatorMsg *msg,
+ GtranslatorSourceViewPlugin *plugin)
+{
+ const gchar *filename = NULL;
+ gint i = 0;
+ gint *line = NULL;
+ GtkTextIter iter;
+ GtkTextBuffer *buffer;
+ GtkTextView *view;
+ GtranslatorCommentPanel *panel;
+
+ panel = gtranslator_tab_get_comment_panel (tab);
+ view = gtranslator_comment_panel_get_extracted_text_view (panel);
+
+ buffer = gtk_text_view_get_buffer (view);
+
+ gtk_text_buffer_get_iter_at_offset (buffer, &iter, 0);
+
+ gtk_text_buffer_insert (buffer, &iter, _("Paths:\n"), -1);
+
+ filename = gtranslator_msg_get_filename (msg, i);
+ while (filename)
+ {
+ line = gtranslator_msg_get_file_line (msg, i);
+ insert_link (buffer, &iter, filename, line);
+ i++;
+ filename = gtranslator_msg_get_filename (msg, i);
+ }
+
+ plugin->priv->inserted_lines = i;
+}
+
+static void
+message_edition_finished_cb (GtranslatorTab *tab,
+ GtranslatorMsg *msg,
+ GtranslatorSourceViewPlugin *plugin)
+{
+ GSList *tags = NULL, *tagp = NULL;
+ GtkTextIter iter;
+ GtkTextBuffer *buffer;
+ gint i = 0;
+ GtranslatorCommentPanel *panel;
+ GtkTextView *view;
+
+ panel = gtranslator_tab_get_comment_panel (tab);
+ view = gtranslator_comment_panel_get_extracted_text_view (panel);
+
+ buffer = gtk_text_view_get_buffer (view);
+
+ gtk_text_buffer_get_iter_at_offset (buffer, &iter, 0);
+
+ while (i < plugin->priv->inserted_lines)
+ {
+ /*
+ * Let's free the path
+ */
+ tags = gtk_text_iter_get_tags (&iter);
+ for (tagp = tags; tagp != NULL; tagp = tagp->next)
+ {
+ GtkTextTag *tag = tagp->data;
+ gchar *path = g_object_get_data (G_OBJECT (tag), "path");
+
+ if (path)
+ {
+ g_free (path);
+ }
+ }
+ g_slist_free (tags);
+ gtk_text_iter_forward_line (&iter);
+ i++;
+ }
+}
+
+static void
+page_added_cb (GtkNotebook *notebook,
+ GtkWidget *child,
+ guint page_num,
+ GtranslatorSourceViewPlugin *plugin)
+{
+ GtranslatorCommentPanel *panel;
+ GtkTextView *view;
+
+ panel = gtranslator_tab_get_comment_panel (GTR_TAB (child));
+ view = gtranslator_comment_panel_get_extracted_text_view (panel);
+
+ g_signal_connect_after (child, "showed-message",
+ G_CALLBACK (showed_message_cb), plugin);
+ /*g_signal_connect (child, "message-edition-finished,
+ G_CALLBACK (message_edition_finished_cb), plugin);*/
+
+ g_signal_connect (view, "event-after",
+ G_CALLBACK (event_after), plugin);
+ g_signal_connect (view, "motion-notify-event",
+ G_CALLBACK (motion_notify_event), NULL);
+ g_signal_connect (view, "visibility-notify-event",
+ G_CALLBACK (visibility_notify_event), NULL);
+}
+
+static void
+use_editor_toggled (GtkToggleButton *button,
+ GtranslatorSourceViewPlugin *plugin)
+{
+ gtk_widget_set_sensitive (plugin->priv->program_box,
+ gtk_toggle_button_get_active (button));
+}
+
+static GtkWidget *
+get_configuration_dialog (GtranslatorSourceViewPlugin *plugin)
+{
+
+ gboolean ret;
+ GtkWidget *error_widget;
+ gchar *value;
+ gboolean use_editor;
+
+ ret = gtranslator_utils_get_glade_widgets (GLADE_FILE,
+ "dialog",
+ &error_widget,
+ "dialog", &plugin->priv->dialog,
+ "main_box", &plugin->priv->main_box,
+ "use_editor", &plugin->priv->use_editor_checkbutton,
+ "program_box", &plugin->priv->program_box,
+ "program_cmd", &plugin->priv->program_cmd_entry,
+ "line_cmd", &plugin->priv->line_cmd_entry,
+ NULL);
+
+ if(!ret)
+ {
+ //FIXME: We have to show a dialog
+ }
+
+ /* Set default values */
+
+ //Use editor
+ use_editor = gconf_client_get_bool (plugin->priv->gconf_client,
+ USE_EDITOR_KEY,
+ NULL);
+
+ g_signal_connect (plugin->priv->use_editor_checkbutton, "toggled",
+ G_CALLBACK (use_editor_toggled), plugin);
+
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (plugin->priv->use_editor_checkbutton),
+ use_editor);
+
+ use_editor_toggled (GTK_TOGGLE_BUTTON (plugin->priv->use_editor_checkbutton),
+ plugin);
+
+ //Program cmd
+ value = gconf_client_get_string (plugin->priv->gconf_client,
+ PROGRAM_CMD_KEY,
+ NULL);
+
+ gtk_entry_set_text (GTK_ENTRY (plugin->priv->program_cmd_entry),
+ value);
+
+ g_free (value);
+
+ //Line cmd
+ value = gconf_client_get_string (plugin->priv->gconf_client,
+ LINE_CMD_KEY,
+ NULL);
+
+ gtk_entry_set_text (GTK_ENTRY (plugin->priv->line_cmd_entry),
+ value);
+
+ g_free (value);
+
+ return plugin->priv->dialog;
+}
+
+static void
+impl_activate (GtranslatorPlugin *plugin,
+ GtranslatorWindow *window)
+{
+ GtkWidget *notebook;
+ GtranslatorSourceViewPlugin *source_view = GTR_SOURCE_VIEW_PLUGIN (plugin);
+ GList *tabs, *l;
+
+ /*
+ * Cursors
+ */
+ hand_cursor = gdk_cursor_new (GDK_HAND2);
+ regular_cursor = gdk_cursor_new (GDK_XTERM);
+
+ notebook = GTK_WIDGET (gtranslator_window_get_notebook (window));
+
+ source_view->priv->window = window;
+
+ g_signal_connect (notebook, "page-added",
+ G_CALLBACK (page_added_cb), plugin);
+
+ /*
+ * If we already have tabs opened we have to add them
+ */
+ tabs = gtranslator_window_get_all_tabs (window);
+ for (l = tabs; l != NULL; l = g_list_next (l))
+ {
+ page_added_cb (GTK_NOTEBOOK (notebook),
+ l->data, 0, GTR_SOURCE_VIEW_PLUGIN (plugin));
+ }
+}
+
+static void
+impl_deactivate(GtranslatorPlugin *plugin,
+ GtranslatorWindow *window)
+{
+ GList *tabs, *l;
+ GtkTextView *view;
+ GtranslatorCommentPanel *panel;
+ GtkWidget *notebook;
+
+ tabs = gtranslator_window_get_all_tabs (window);
+ notebook = GTK_WIDGET (gtranslator_window_get_notebook (window));
+
+ for (l = tabs; l != NULL; l = g_list_next (l))
+ {
+ panel = gtranslator_tab_get_comment_panel (GTR_TAB (l->data));
+ view = gtranslator_comment_panel_get_extracted_text_view (panel);
+
+ g_signal_handlers_disconnect_by_func (l->data,
+ showed_message_cb,
+ plugin);
+
+ g_signal_handlers_disconnect_by_func (view,
+ event_after,
+ window);
+ g_signal_handlers_disconnect_by_func (view,
+ motion_notify_event,
+ NULL);
+ g_signal_handlers_disconnect_by_func (view,
+ visibility_notify_event,
+ NULL);
+ }
+
+ g_signal_handlers_disconnect_by_func (notebook,
+ page_added_cb,
+ plugin);
+}
+
+static void
+ok_button_pressed (GtranslatorSourceViewPlugin *plugin)
+{
+ const gchar *program_cmd;
+ const gchar *line_cmd;
+ gboolean use_editor;
+
+ /* We have to get the text from the entries */
+ use_editor = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (plugin->priv->use_editor_checkbutton));
+ program_cmd = gtk_entry_get_text (GTK_ENTRY (plugin->priv->program_cmd_entry));
+ line_cmd = gtk_entry_get_text (GTK_ENTRY (plugin->priv->line_cmd_entry));
+
+ /* Now we store the data in gconf */
+ if (!gconf_client_key_is_writable (plugin->priv->gconf_client,
+ USE_EDITOR_KEY,
+ NULL))
+ return;
+
+ gconf_client_set_bool (plugin->priv->gconf_client,
+ USE_EDITOR_KEY,
+ use_editor,
+ NULL);
+
+ if (!gconf_client_key_is_writable (plugin->priv->gconf_client,
+ PROGRAM_CMD_KEY,
+ NULL))
+ return;
+
+ gconf_client_set_string (plugin->priv->gconf_client,
+ PROGRAM_CMD_KEY,
+ program_cmd,
+ NULL);
+
+ if (!gconf_client_key_is_writable (plugin->priv->gconf_client,
+ LINE_CMD_KEY,
+ NULL))
+ return;
+
+ gconf_client_set_string (plugin->priv->gconf_client,
+ LINE_CMD_KEY,
+ line_cmd,
+ NULL);
+}
+
+static void
+configure_dialog_response_cb (GtkWidget *widget,
+ gint response,
+ GtranslatorSourceViewPlugin *plugin)
+{
+ switch (response)
+ {
+ case GTK_RESPONSE_OK:
+ {
+ ok_button_pressed (plugin);
+
+ gtk_widget_destroy (plugin->priv->dialog);
+ break;
+ }
+ case GTK_RESPONSE_CANCEL:
+ {
+ gtk_widget_destroy (plugin->priv->dialog);
+ }
+ }
+}
+
+static GtkWidget *
+impl_create_configure_dialog (GtranslatorPlugin *plugin)
+{
+ GtkWidget *dialog;
+
+ dialog = get_configuration_dialog (GTR_SOURCE_VIEW_PLUGIN (plugin));
+
+ g_signal_connect (dialog,
+ "response",
+ G_CALLBACK (configure_dialog_response_cb),
+ GTR_SOURCE_VIEW_PLUGIN (plugin));
+ g_signal_connect (dialog,
+ "destroy",
+ G_CALLBACK (gtk_widget_destroy),
+ &dialog);
+
+ return dialog;
+}
+
+static void
+gtranslator_source_view_plugin_class_init (GtranslatorSourceViewPluginClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtranslatorPluginClass *plugin_class = GTR_PLUGIN_CLASS (klass);
+
+ object_class->finalize = gtranslator_source_view_plugin_finalize;
+
+ plugin_class->activate = impl_activate;
+ plugin_class->deactivate = impl_deactivate;
+ plugin_class->create_configure_dialog = impl_create_configure_dialog;
+
+ g_type_class_add_private (object_class, sizeof (GtranslatorSourceViewPluginPrivate));
+}
Added: trunk/plugins/source-view/source-view-plugin.h
==============================================================================
--- (empty file)
+++ trunk/plugins/source-view/source-view-plugin.h Mon Sep 22 09:38:11 2008
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2008 Ignacio Casal Quinteiro <nacho resa gmail com>
+ *
+ * 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 3 of the License, 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
+ * MERCHANPOILITY 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, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef __GTR_SOURCE_VIEW_PLUGIN_H__
+#define __GTR_SOURCE_VIEW_PLUGIN_H__
+
+#include <glib.h>
+#include <glib-object.h>
+
+#include "plugin.h"
+
+G_BEGIN_DECLS
+
+/*
+ * Type checking and casting macros
+ */
+#define GTR_TYPE_SOURCE_VIEW_PLUGIN (gtranslator_source_view_plugin_get_type ())
+#define GTR_SOURCE_VIEW_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GTR_TYPE_SOURCE_VIEW_PLUGIN, GtranslatorSourceViewPlugin))
+#define GTR_SOURCE_VIEW_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GTR_TYPE_SOURCE_VIEW_PLUGIN, GtranslatorSourceViewPluginClass))
+#define GTR_IS_SOURCE_VIEW_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GTR_TYPE_SOURCE_VIEW_PLUGIN))
+#define GTR_IS_SOURCE_VIEW_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GTR_TYPE_SOURCE_VIEW_PLUGIN))
+#define GTR_SOURCE_VIEW_PLUGIN_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GTR_TYPE_SOURCE_VIEW_PLUGIN_PLUGIN, GtranslatorSourceViewPluginClass))
+
+/* Private structure type */
+typedef struct _GtranslatorSourceViewPluginPrivate GtranslatorSourceViewPluginPrivate;
+
+/*
+ * Main object structure
+ */
+typedef struct _GtranslatorSourceViewPlugin GtranslatorSourceViewPlugin;
+
+struct _GtranslatorSourceViewPlugin
+{
+ GtranslatorPlugin parent_instance;
+
+ /* private */
+ GtranslatorSourceViewPluginPrivate *priv;
+};
+
+/*
+ * Class definition
+ */
+typedef struct _GtranslatorSourceViewPluginClass GtranslatorSourceViewPluginClass;
+
+struct _GtranslatorSourceViewPluginClass
+{
+ GtranslatorPluginClass parent_class;
+};
+
+/*
+ * Public methods
+ */
+GType gtranslator_source_view_plugin_get_type (void) G_GNUC_CONST;
+
+/* All the plugins must implement this function */
+G_MODULE_EXPORT GType register_gtranslator_plugin (GTypeModule *module);
+
+G_END_DECLS
+
+#endif /* __GTR_SOURCE_VIEW_PLUGIN_H__ */
Added: trunk/plugins/source-view/source-view.gtranslator-plugin.desktop.in
==============================================================================
--- (empty file)
+++ trunk/plugins/source-view/source-view.gtranslator-plugin.desktop.in Mon Sep 22 09:38:11 2008
@@ -0,0 +1,8 @@
+[Gtranslator Plugin]
+Module=sourceview
+IAge=2
+_Name=Source View
+_Description=Show the message in the source code.
+Authors=Ignacio Casal Quinteiro <nacho resa gmail com>
+Copyright=Copyright @ 2008 Ignacio Casal Quinteiro
+Website=http://gtranslator.sf.net
Added: trunk/plugins/source-view/viewer.c
==============================================================================
--- (empty file)
+++ trunk/plugins/source-view/viewer.c Mon Sep 22 09:38:11 2008
@@ -0,0 +1,454 @@
+/*
+ * Copyright (C) 2008 Ignacio Casal Quinteiro <nacho resa gmail com>
+ *
+ * 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "utils.h"
+#include "viewer.h"
+#include "window.h"
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <glib-object.h>
+#include <gtk/gtk.h>
+#include <gio/gio.h>
+#include <string.h>
+#include <gtksourceview/gtksourcelanguagemanager.h>
+
+#define GTR_VIEWER_GET_PRIVATE(object) (G_TYPE_INSTANCE_GET_PRIVATE ( \
+ (object), \
+ GTR_TYPE_VIEWER, \
+ GtranslatorViewerPrivate))
+
+
+G_DEFINE_TYPE(GtranslatorViewer, gtranslator_viewer, GTK_TYPE_DIALOG)
+
+struct _GtranslatorViewerPrivate
+{
+ GtkWidget *main_box;
+ GtkWidget *view;
+};
+
+static void
+dialog_response_handler (GtkDialog *dlg,
+ gint res_id)
+{
+ switch (res_id)
+ {
+ default:
+ gtk_widget_destroy (GTK_WIDGET(dlg));
+ }
+}
+
+static void
+gtranslator_viewer_init (GtranslatorViewer *dlg)
+{
+ gboolean ret;
+ GtkWidget *error_widget;
+ GtkWidget *sw;
+
+ dlg->priv = GTR_VIEWER_GET_PRIVATE (dlg);
+
+ gtk_dialog_add_buttons (GTK_DIALOG (dlg),
+ GTK_STOCK_CLOSE,
+ GTK_RESPONSE_CLOSE,
+ NULL);
+
+ gtk_window_set_title (GTK_WINDOW (dlg), _("Source Viewer"));
+ gtk_window_set_default_size(GTK_WINDOW(dlg), 800, 600);
+ gtk_window_set_resizable (GTK_WINDOW (dlg), TRUE);
+ gtk_dialog_set_has_separator (GTK_DIALOG (dlg), FALSE);
+ gtk_window_set_destroy_with_parent (GTK_WINDOW (dlg), TRUE);
+
+ /* HIG defaults */
+ gtk_container_set_border_width (GTK_CONTAINER (dlg), 5);
+ gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dlg)->vbox), 2); /* 2 * 5 + 2 = 12 */
+ gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dlg)->action_area), 5);
+ gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dlg)->action_area), 4);
+
+ g_signal_connect (dlg,
+ "response",
+ G_CALLBACK (dialog_response_handler),
+ NULL);
+
+ /*Glade*/
+ ret = gtranslator_utils_get_glade_widgets(DATADIR "/viewer.glade",
+ "main_box",
+ &error_widget,
+
+ "main_box", &dlg->priv->main_box,
+ "scrolledwindow", &sw,
+ NULL);
+
+ if(!ret)
+ {
+ gtk_widget_show(error_widget);
+ gtk_box_pack_start_defaults (GTK_BOX (GTK_DIALOG (dlg)->vbox),
+ error_widget);
+
+ return;
+ }
+
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox),
+ dlg->priv->main_box, TRUE, TRUE, 0);
+
+ gtk_container_set_border_width (GTK_CONTAINER (dlg->priv->main_box), 5);
+
+ /* Source view */
+ dlg->priv->view = gtk_source_view_new ();
+ gtk_text_view_set_editable (GTK_TEXT_VIEW (dlg->priv->view), FALSE);
+ gtk_widget_show (dlg->priv->view);
+ gtk_container_add (GTK_CONTAINER (sw), dlg->priv->view);
+
+ gtk_source_view_set_highlight_current_line (GTK_SOURCE_VIEW (dlg->priv->view),
+ TRUE);
+
+ gtk_source_view_set_show_line_numbers (GTK_SOURCE_VIEW (dlg->priv->view),
+ TRUE);
+
+ gtk_source_view_set_show_right_margin (GTK_SOURCE_VIEW (dlg->priv->view),
+ TRUE);
+}
+
+static void
+gtranslator_viewer_finalize (GObject *object)
+{
+ G_OBJECT_CLASS (gtranslator_viewer_parent_class)->finalize (object);
+}
+
+static void
+gtranslator_viewer_class_init (GtranslatorViewerClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ g_type_class_add_private (klass, sizeof (GtranslatorViewerPrivate));
+
+ object_class->finalize = gtranslator_viewer_finalize;
+}
+
+/***************** File loading *****************/
+
+static void
+error_dialog (GtkWindow *parent, const gchar *msg, ...)
+{
+ va_list ap;
+ gchar *tmp;
+ GtkWidget *dialog;
+
+ va_start (ap, msg);
+ tmp = g_strdup_vprintf (msg, ap);
+ va_end (ap);
+
+ dialog = gtk_message_dialog_new (parent,
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_OK,
+ tmp);
+ g_free (tmp);
+
+ gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+}
+
+static gboolean
+gtk_source_buffer_load_file (GtkSourceBuffer *source_buffer,
+ const gchar *filename,
+ GError **error)
+{
+ GtkTextIter iter;
+ gchar *buffer;
+ GError *error_here = NULL;
+
+ g_return_val_if_fail (GTK_IS_SOURCE_BUFFER (source_buffer), FALSE);
+ g_return_val_if_fail (filename != NULL, FALSE);
+
+ if (!g_file_get_contents (filename, &buffer, NULL, &error_here))
+ {
+ error_dialog (NULL, "%s\nFile %s", error_here->message, filename);
+ g_propagate_error (error, error_here);
+ return FALSE;
+ }
+
+ gtk_source_buffer_begin_not_undoable_action (source_buffer);
+ gtk_text_buffer_set_text (GTK_TEXT_BUFFER (source_buffer), buffer, -1);
+ gtk_source_buffer_end_not_undoable_action (source_buffer);
+ gtk_text_buffer_set_modified (GTK_TEXT_BUFFER (source_buffer), FALSE);
+
+ /* move cursor to the beginning */
+ gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (source_buffer), &iter);
+ gtk_text_buffer_place_cursor (GTK_TEXT_BUFFER (source_buffer), &iter);
+
+ {
+ GtkTextIter start, end;
+ char *text;
+ gtk_text_buffer_get_bounds (GTK_TEXT_BUFFER (source_buffer), &start, &end);
+ text = gtk_text_buffer_get_text (GTK_TEXT_BUFFER (source_buffer), &start, &end, TRUE);
+ g_assert (!strcmp (text, buffer));
+ g_free (text);
+ }
+
+ g_free (buffer);
+ return TRUE;
+}
+
+static void
+remove_all_marks (GtkSourceBuffer *buffer)
+{
+ GtkTextIter s, e;
+
+ gtk_text_buffer_get_bounds (GTK_TEXT_BUFFER (buffer), &s, &e);
+
+ gtk_source_buffer_remove_source_marks (buffer, &s, &e, NULL);
+}
+
+/* Note this is wrong for several reasons, e.g. g_pattern_match is broken
+ * for glob matching. */
+static GtkSourceLanguage *
+get_language_for_filename (const gchar *filename)
+{
+ const gchar * const *languages;
+ gchar *filename_utf8;
+ GtkSourceLanguageManager *manager;
+
+ filename_utf8 = g_filename_to_utf8 (filename, -1, NULL, NULL, NULL);
+ g_return_val_if_fail (filename_utf8 != NULL, NULL);
+
+ manager = gtk_source_language_manager_get_default ();
+ languages = gtk_source_language_manager_get_language_ids (manager);
+
+ while (*languages != NULL)
+ {
+ GtkSourceLanguage *lang;
+ gchar **globs, **p;
+
+ lang = gtk_source_language_manager_get_language (manager,
+ *languages);
+ g_return_val_if_fail (GTK_IS_SOURCE_LANGUAGE (lang), NULL);
+ ++languages;
+
+ globs = gtk_source_language_get_globs (lang);
+ if (globs == NULL)
+ continue;
+
+ for (p = globs; *p != NULL; p++)
+ {
+ if (g_pattern_match_simple (*p, filename_utf8))
+ {
+ g_strfreev (globs);
+ g_free (filename_utf8);
+
+ return lang;
+ }
+ }
+
+ g_strfreev (globs);
+ }
+
+ g_free (filename_utf8);
+ return NULL;
+}
+
+static GtkSourceLanguage *
+get_language_for_file (const gchar *filename)
+{
+ GtkSourceLanguage *language = NULL;
+
+ if (!language)
+ language = get_language_for_filename (filename);
+
+ return language;
+}
+
+static GtkSourceLanguage *
+get_language_by_id (const gchar *id)
+{
+ GtkSourceLanguageManager *manager;
+ manager = gtk_source_language_manager_get_default ();
+ return gtk_source_language_manager_get_language (manager, id);
+}
+
+static GtkSourceLanguage *
+get_language (GtkTextBuffer *buffer, const gchar *filename)
+{
+ GtkSourceLanguage *language = NULL;
+ GtkTextIter start, end;
+ gchar *text;
+ gchar *lang_string;
+
+ gtk_text_buffer_get_start_iter (buffer, &start);
+ end = start;
+ gtk_text_iter_forward_line (&end);
+
+#define LANG_STRING "gtk-source-lang:"
+ text = gtk_text_iter_get_slice (&start, &end);
+ lang_string = strstr (text, LANG_STRING);
+ if (lang_string != NULL)
+ {
+ gchar **tokens;
+
+ lang_string += strlen (LANG_STRING);
+ g_strchug (lang_string);
+
+ tokens = g_strsplit_set (lang_string, " \t\n", 2);
+
+ if (tokens != NULL && tokens[0] != NULL)
+ language = get_language_by_id (tokens[0]);
+
+ g_strfreev (tokens);
+ }
+
+ if (!language)
+ language = get_language_for_file (filename);
+
+ g_free (text);
+ return language;
+}
+
+static gboolean
+open_file (GtkSourceBuffer *buffer, const gchar *filename)
+{
+ GtkSourceLanguage *language = NULL;
+ gchar *freeme = NULL;
+ gboolean success = FALSE;
+ GFile *file;
+ gchar *path;
+
+ file = g_file_new_for_path (filename);
+ path = g_file_get_path (file);
+ g_object_unref (file);
+
+ remove_all_marks (buffer);
+
+ success = gtk_source_buffer_load_file (buffer, path, NULL);
+
+ if (!success)
+ goto out;
+
+ language = get_language (GTK_TEXT_BUFFER (buffer), filename);
+
+ if (language == NULL)
+ g_print ("No language found for file `%s'\n", filename);
+
+ gtk_source_buffer_set_language (buffer, language);
+ g_object_set_data_full (G_OBJECT (buffer),
+ "filename", g_strdup (filename),
+ (GDestroyNotify) g_free);
+
+ if (language != NULL)
+ {
+ gchar **styles;
+
+ styles = gtk_source_language_get_style_ids (language);
+
+ if (styles == NULL)
+ g_print ("No styles in language '%s'\n", gtk_source_language_get_name (language));
+ else
+ {
+ gchar **ids;
+ g_print ("Styles in in language '%s':\n", gtk_source_language_get_name (language));
+
+ ids = styles;
+
+ while (*ids != NULL)
+ {
+ const gchar *name;
+
+ name = gtk_source_language_get_style_name (language, *ids);
+
+ g_print ("- %s (name: '%s')\n", *ids, name);
+
+ ++ids;
+ }
+
+ g_strfreev (styles);
+ }
+
+ g_print("\n");
+ }
+out:
+ g_free (freeme);
+ return success;
+}
+
+static void
+jump_to_line (GtkTextView *view,
+ gint line)
+{
+ GtkTextBuffer *buffer;
+ GtkTextIter iter;
+ gint line_count;
+
+ buffer = gtk_text_view_get_buffer (view);
+
+ line_count = gtk_text_buffer_get_line_count (buffer);
+
+ if (line >= line_count)
+ gtk_text_buffer_get_end_iter (buffer,
+ &iter);
+ else
+ gtk_text_buffer_get_iter_at_line (buffer,
+ &iter,
+ line-1);
+
+ gtk_text_buffer_place_cursor (buffer, &iter);
+
+ gtk_text_view_scroll_to_mark (view,
+ gtk_text_buffer_get_insert (buffer),
+ 0.25,
+ FALSE,
+ 0.0,
+ 0.0);
+}
+
+void
+gtranslator_show_viewer (GtranslatorWindow *window,
+ const gchar *path,
+ gint line)
+{
+ static GtranslatorViewer *dlg = NULL;
+
+ g_return_if_fail (GTR_IS_WINDOW (window));
+
+ if (dlg == NULL)
+ {
+ GtkSourceBuffer *buffer;
+
+ dlg = g_object_new (GTR_TYPE_VIEWER, NULL);
+
+ buffer = GTK_SOURCE_BUFFER (gtk_text_view_get_buffer (GTK_TEXT_VIEW (dlg->priv->view)));
+
+ open_file (buffer, path);
+ jump_to_line (GTK_TEXT_VIEW (dlg->priv->view), line);
+
+ g_signal_connect (dlg,
+ "destroy",
+ G_CALLBACK (gtk_widget_destroyed),
+ &dlg);
+ gtk_widget_show (GTK_WIDGET (dlg));
+ }
+
+ if (GTK_WINDOW (window) != gtk_window_get_transient_for (GTK_WINDOW (dlg)))
+ {
+ gtk_window_set_transient_for (GTK_WINDOW (dlg),
+ GTK_WINDOW (window));
+ }
+
+ gtk_window_present (GTK_WINDOW (dlg));
+}
Added: trunk/plugins/source-view/viewer.glade
==============================================================================
--- (empty file)
+++ trunk/plugins/source-view/viewer.glade Mon Sep 22 09:38:11 2008
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
+<!--Generated with glade3 3.4.5 on Fri Jun 27 10:41:35 2008 -->
+<glade-interface>
+ <widget class="GtkDialog" id="dialog1">
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="border_width">5</property>
+ <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+ <property name="has_separator">False</property>
+ <child internal-child="vbox">
+ <widget class="GtkVBox" id="dialog-vbox1">
+ <property name="visible">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="spacing">2</property>
+ <child>
+ <widget class="GtkVBox" id="main_box">
+ <property name="visible">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes"><b>Source code</b></property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkScrolledWindow" id="scrolledwindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="shadow_type">GTK_SHADOW_IN</property>
+ <child>
+ <placeholder/>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child internal-child="action_area">
+ <widget class="GtkHButtonBox" id="dialog-action_area1">
+ <property name="visible">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="layout_style">GTK_BUTTONBOX_END</property>
+ <child>
+ <widget class="GtkButton" id="button1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="label" translatable="yes">gtk-close</property>
+ <property name="use_stock">True</property>
+ <property name="response_id">0</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="pack_type">GTK_PACK_END</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+</glade-interface>
Added: trunk/plugins/source-view/viewer.h
==============================================================================
--- (empty file)
+++ trunk/plugins/source-view/viewer.h Mon Sep 22 09:38:11 2008
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2008 Ignacio Casal Quinteiro <nacho resa gmail com>
+ *
+ * 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef __VIEWER_H__
+#define __VIEWER_H__
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gtk/gtk.h>
+#include "window.h"
+#include "msg.h"
+
+G_BEGIN_DECLS
+
+/*
+ * Type checking and casting macros
+ */
+#define GTR_TYPE_VIEWER (gtranslator_viewer_get_type ())
+#define GTR_VIEWER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GTR_TYPE_VIEWER, GtranslatorViewer))
+#define GTR_VIEWER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GTR_TYPE_VIEWER, GtranslatorViewerClass))
+#define GTR_IS_VIEWER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GTR_TYPE_VIEWER))
+#define GTR_IS_VIEWER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GTR_TYPE_VIEWER))
+#define GTR_VIEWER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GTR_TYPE_VIEWER, GtranslatorViewerClass))
+
+/* Private structure type */
+typedef struct _GtranslatorViewerPrivate GtranslatorViewerPrivate;
+
+/*
+ * Main object structure
+ */
+typedef struct _GtranslatorViewer GtranslatorViewer;
+
+struct _GtranslatorViewer
+{
+ GtkDialog parent_instance;
+
+ /*< private > */
+ GtranslatorViewerPrivate *priv;
+};
+
+/*
+ * Class definition
+ */
+typedef struct _GtranslatorViewerClass GtranslatorViewerClass;
+
+struct _GtranslatorViewerClass
+{
+ GtkDialogClass parent_class;
+};
+
+/*
+ * Public methods
+ */
+GType gtranslator_viewer_get_type (void) G_GNUC_CONST;
+
+GType gtranslator_viewer_register_type (GTypeModule * module);
+
+void gtranslator_show_viewer (GtranslatorWindow *window,
+ const gchar *path,
+ gint line);
+
+G_END_DECLS
+
+#endif /* __VIEWER_H__ */
Modified: trunk/src/comment.c
==============================================================================
--- trunk/src/comment.c (original)
+++ trunk/src/comment.c Mon Sep 22 09:38:11 2008
@@ -26,7 +26,6 @@
#include <glib/gi18n.h>
#include <glib-object.h>
#include <gtk/gtk.h>
-#include <gio/gio.h>
#define GTR_COMMENT_PANEL_GET_PRIVATE(object) (G_TYPE_INSTANCE_GET_PRIVATE ( \
(object), \
@@ -44,210 +43,6 @@
GtranslatorTab *tab;
};
-static void
-insert_link (GtkTextBuffer *buffer,
- GtkTextIter *iter,
- const gchar *path,
- gint *line)
-{
- GtkTextTag *tag;
- gchar *text;
- GFile *file;
- gchar *uri;
-
- file = g_file_new_for_commandline_arg (path);
- uri = g_file_get_uri (file);
- g_object_unref (file);
-
- tag = gtk_text_buffer_create_tag (buffer, NULL,
- "foreground", "blue",
- "underline", PANGO_UNDERLINE_SINGLE,
- NULL);
- g_object_set_data (G_OBJECT (tag), "path", uri);
- g_object_set_data (G_OBJECT (tag), "line", line);
-
- text = g_strconcat (path, "\n", NULL);
- gtk_text_buffer_insert_with_tags (buffer, iter, text, -1, tag, NULL);
- g_free (text);
-}
-
-static void
-show_in_editor (const gchar *path,
- gint line)
-{
- gchar *open[4];
-
- if (g_find_program_in_path ("gedit"))
- {
- open[0] = "gedit";
- }
- else
- {
- GtkWidget *dialog;
-
- dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL,
- GTK_DIALOG_MODAL,
- GTK_BUTTONS_CLOSE,
- _("Please, install gedit to be able to show the file"));
- gtk_dialog_run (GTK_DIALOG (dialog));
- gtk_widget_destroy (dialog);
- }
-
- open[1] = g_strdup (path);
- open[2] = g_strdup_printf ("+%d", line);
- open[3] = NULL;
-
- gdk_spawn_on_screen (gdk_screen_get_default (),
- NULL,
- open,
- NULL,
- G_SPAWN_SEARCH_PATH,
- NULL,
- NULL, NULL, NULL);
- g_free (open[1]);
- g_free (open[2]);
-}
-
-static void
-follow_if_link (GtkWidget *text_view,
- GtkTextIter *iter)
-{
- GSList *tags = NULL, *tagp = NULL;
-
- tags = gtk_text_iter_get_tags (iter);
- for (tagp = tags; tagp != NULL; tagp = tagp->next)
- {
- GtkTextTag *tag = tagp->data;
- gchar *path = g_object_get_data (G_OBJECT (tag), "path");
- gint line = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (tag), "line"));
-
- show_in_editor (path, line);
- }
-
- if (tags)
- g_slist_free (tags);
-}
-
-static gboolean
-event_after (GtkWidget *text_view,
- GdkEvent *ev)
-{
- GtkTextIter start, end, iter;
- GtkTextBuffer *buffer;
- GdkEventButton *event;
- gint x, y;
-
- if (ev->type != GDK_BUTTON_RELEASE)
- return FALSE;
-
- event = (GdkEventButton *)ev;
-
- if (event->button != 1)
- return FALSE;
-
- buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_view));
-
- /* we shouldn't follow a link if the user has selected something */
- gtk_text_buffer_get_selection_bounds (buffer, &start, &end);
- if (gtk_text_iter_get_offset (&start) != gtk_text_iter_get_offset (&end))
- return FALSE;
-
- gtk_text_view_window_to_buffer_coords (GTK_TEXT_VIEW (text_view),
- GTK_TEXT_WINDOW_WIDGET,
- event->x, event->y, &x, &y);
-
- gtk_text_view_get_iter_at_location (GTK_TEXT_VIEW (text_view), &iter, x, y);
-
- follow_if_link (text_view, &iter);
-
- return FALSE;
-}
-
-static gboolean hovering_over_link = FALSE;
-static GdkCursor *hand_cursor = NULL;
-static GdkCursor *regular_cursor = NULL;
-
-/* Looks at all tags covering the position (x, y) in the text view,
- * and if one of them is a link, change the cursor to the "hands" cursor
- * typically used by web browsers.
- */
-static void
-set_cursor_if_appropriate (GtkTextView *text_view,
- gint x,
- gint y)
-{
- GSList *tags = NULL, *tagp = NULL;
- GtkTextIter iter;
- gboolean hovering = FALSE;
-
- gtk_text_view_get_iter_at_location (text_view, &iter, x, y);
-
- tags = gtk_text_iter_get_tags (&iter);
- for (tagp = tags; tagp != NULL; tagp = tagp->next)
- {
- GtkTextTag *tag = tagp->data;
- gchar *path = g_object_get_data (G_OBJECT (tag), "path");
-
- if (path)
- {
- hovering = TRUE;
- break;
- }
- }
-
- if (hovering != hovering_over_link)
- {
- hovering_over_link = hovering;
-
- if (hovering_over_link)
- gdk_window_set_cursor (gtk_text_view_get_window (text_view, GTK_TEXT_WINDOW_TEXT), hand_cursor);
- else
- gdk_window_set_cursor (gtk_text_view_get_window (text_view, GTK_TEXT_WINDOW_TEXT), regular_cursor);
- }
-
- if (tags)
- g_slist_free (tags);
-}
-
-/*
- * Update the cursor image if the pointer moved.
- */
-static gboolean
-motion_notify_event (GtkWidget *text_view,
- GdkEventMotion *event)
-{
- gint x, y;
-
- gtk_text_view_window_to_buffer_coords (GTK_TEXT_VIEW (text_view),
- GTK_TEXT_WINDOW_WIDGET,
- event->x, event->y, &x, &y);
-
- set_cursor_if_appropriate (GTK_TEXT_VIEW (text_view), x, y);
-
- gdk_window_get_pointer (text_view->window, NULL, NULL, NULL);
- return FALSE;
-}
-
-/* Also update the cursor image if the window becomes visible
- * (e.g. when a window covering it got iconified).
- */
-static gboolean
-visibility_notify_event (GtkWidget *text_view,
- GdkEventVisibility *event)
-{
- gint wx, wy, bx, by;
-
- gdk_window_get_pointer (text_view->window, &wx, &wy, NULL);
-
- gtk_text_view_window_to_buffer_coords (GTK_TEXT_VIEW (text_view),
- GTK_TEXT_WINDOW_WIDGET,
- wx, wy, &bx, &by);
-
- set_cursor_if_appropriate (GTK_TEXT_VIEW (text_view), bx, by);
-
- return FALSE;
-}
-
static void
showed_message_cb (GtranslatorTab *tab,
GtranslatorMsg *msg,
@@ -259,46 +54,14 @@
gchar *context;
gchar *format;
gchar *toset;
- const gchar *filename = NULL;
- gint i = 0;
- gint *index = NULL;
- gchar *path = NULL;
- GSList *tags = NULL, *tagp = NULL;
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (panel->priv->extracted_comments));
gtk_text_buffer_set_text (buffer, "", 0);
gtk_text_buffer_get_iter_at_offset (buffer, &iter, 0);
-
- /*
- * Let's free the path
- */
- tags = gtk_text_iter_get_tags (&iter);
- for (tagp = tags; tagp != NULL; tagp = tagp->next)
- {
- GtkTextTag *tag = tagp->data;
- gchar *path = g_object_get_data (G_OBJECT (tag), "path");
-
- if (path)
- {
- g_free (path);
- }
- }
- g_slist_free (tags);
-
- gtk_text_buffer_insert (buffer, &iter, _("Paths:\n"), -1);
-
- filename = gtranslator_msg_get_filename (msg, i);
- while (filename)
- {
- index = gtranslator_msg_get_file_line (msg, i);
- insert_link (buffer, &iter, filename, index);
- i++;
- filename = gtranslator_msg_get_filename (msg, i);
- }
format = g_strconcat (_("Format: "), gtranslator_msg_get_format (msg), NULL);
- context = g_strconcat (_("Context:\n"), gtranslator_msg_get_msgctxt (msg), NULL);
- extracted = g_strconcat (_("Extracted comments:\n"),
+ context = g_strconcat (_("Context:"), gtranslator_msg_get_msgctxt (msg), NULL);
+ extracted = g_strconcat (_("Extracted comments:"),
gtranslator_msg_get_extracted_comments(msg), NULL);
toset = g_strdup_printf("%s\n%s\n%s", format, context, extracted);
@@ -322,12 +85,6 @@
GtkWidget *comments_scrolled_window;
/*
- * Cursors
- */
- hand_cursor = gdk_cursor_new (GDK_HAND2);
- regular_cursor = gdk_cursor_new (GDK_XTERM);
-
- /*
* Set up the scrolling window for the extracted comments display
*/
comments_scrolled_window = gtk_scrolled_window_new(NULL, NULL);
@@ -343,12 +100,6 @@
* Extracted comments
*/
priv->extracted_comments = gtk_text_view_new();
- g_signal_connect (priv->extracted_comments, "event-after",
- G_CALLBACK (event_after), NULL);
- g_signal_connect (priv->extracted_comments, "motion-notify-event",
- G_CALLBACK (motion_notify_event), NULL);
- g_signal_connect (priv->extracted_comments, "visibility-notify-event",
- G_CALLBACK (visibility_notify_event), NULL);
gtk_text_view_set_editable(GTK_TEXT_VIEW(priv->extracted_comments), FALSE);
gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (priv->extracted_comments),
@@ -430,3 +181,12 @@
gtk_text_buffer_set_text(buf, comments, -1);
}
+
+GtkTextView *
+gtranslator_comment_panel_get_extracted_text_view (GtranslatorCommentPanel *panel)
+{
+ g_return_if_fail (GTR_IS_COMMENT_PANEL (panel));
+
+ return GTK_TEXT_VIEW (panel->priv->extracted_comments);
+}
+
Modified: trunk/src/comment.h
==============================================================================
--- trunk/src/comment.h (original)
+++ trunk/src/comment.h Mon Sep 22 09:38:11 2008
@@ -71,6 +71,8 @@
void gtranslator_comment_panel_set_comments (GtranslatorCommentPanel *panel,
const gchar *comments);
+
+GtkTextView *gtranslator_comment_panel_get_extracted_text_view (GtranslatorCommentPanel *panel);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]