initial
This commit is contained in:
42
plugins/Makefile.am
Executable file
42
plugins/Makefile.am
Executable file
@@ -0,0 +1,42 @@
|
||||
DIST_SUBDIRS = \
|
||||
changecase \
|
||||
checkupdate \
|
||||
docinfo \
|
||||
externaltools \
|
||||
filebrowser \
|
||||
modelines \
|
||||
pythonconsole \
|
||||
quickopen \
|
||||
snippets \
|
||||
sort \
|
||||
spell \
|
||||
taglist \
|
||||
time
|
||||
|
||||
SUBDIRS = \
|
||||
changecase \
|
||||
docinfo \
|
||||
filebrowser \
|
||||
modelines \
|
||||
sort \
|
||||
taglist \
|
||||
time
|
||||
|
||||
if ENABLE_PYTHON
|
||||
SUBDIRS += pythonconsole snippets quickopen
|
||||
|
||||
if !OS_WIN32
|
||||
SUBDIRS += externaltools
|
||||
endif
|
||||
|
||||
endif
|
||||
|
||||
if ENABLE_ENCHANT
|
||||
SUBDIRS += spell
|
||||
endif
|
||||
|
||||
if ENABLE_UPDATER
|
||||
SUBDIRS += checkupdate
|
||||
endif
|
||||
|
||||
-include $(top_srcdir)/git.mk
|
34
plugins/changecase/Makefile.am
Executable file
34
plugins/changecase/Makefile.am
Executable file
@@ -0,0 +1,34 @@
|
||||
# changecase plugin
|
||||
plugindir = $(GEDIT_PLUGINS_LIBS_DIR)
|
||||
|
||||
INCLUDES = \
|
||||
-I$(top_srcdir) \
|
||||
$(GEDIT_CFLAGS) \
|
||||
$(WARN_CFLAGS) \
|
||||
$(DISABLE_DEPRECATED_CFLAGS)
|
||||
|
||||
plugin_LTLIBRARIES = libchangecase.la
|
||||
|
||||
libchangecase_la_SOURCES = \
|
||||
gedit-changecase-plugin.h \
|
||||
gedit-changecase-plugin.c
|
||||
|
||||
libchangecase_la_LDFLAGS = $(PLUGIN_LIBTOOL_FLAGS)
|
||||
libchangecase_la_LIBADD = $(GEDIT_LIBS)
|
||||
|
||||
uidir = $(GEDIT_PLUGINS_DATA_DIR)/changecase
|
||||
ui_DATA =
|
||||
|
||||
plugin_in_files = changecase.gedit-plugin.desktop.in
|
||||
|
||||
%.gedit-plugin: %.gedit-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:.gedit-plugin.desktop.in=.gedit-plugin)
|
||||
|
||||
EXTRA_DIST = $(ui_DATA) $(plugin_in_files)
|
||||
|
||||
CLEANFILES = $(plugin_DATA)
|
||||
DISTCLEANFILES = $(plugin_DATA)
|
||||
|
||||
|
||||
-include $(top_srcdir)/git.mk
|
8
plugins/changecase/changecase.gedit-plugin.desktop.in
Executable file
8
plugins/changecase/changecase.gedit-plugin.desktop.in
Executable file
@@ -0,0 +1,8 @@
|
||||
[Gedit Plugin]
|
||||
Module=changecase
|
||||
IAge=2
|
||||
_Name=Change Case
|
||||
_Description=Changes the case of selected text.
|
||||
Authors=Paolo Borelli <pborelli@katamail.com>
|
||||
Copyright=Copyright © 2004-2005 Paolo Borelli
|
||||
Website=http://www.gedit.org
|
395
plugins/changecase/gedit-changecase-plugin.c
Executable file
395
plugins/changecase/gedit-changecase-plugin.c
Executable file
@@ -0,0 +1,395 @@
|
||||
/*
|
||||
* gedit-changecase-plugin.c
|
||||
*
|
||||
* Copyright (C) 2004-2005 - Paolo Borelli
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include "gedit-changecase-plugin.h"
|
||||
|
||||
#include <glib/gi18n-lib.h>
|
||||
#include <gmodule.h>
|
||||
|
||||
#include <gedit/gedit-debug.h>
|
||||
|
||||
#define WINDOW_DATA_KEY "GeditChangecasePluginWindowData"
|
||||
|
||||
GEDIT_PLUGIN_REGISTER_TYPE(GeditChangecasePlugin, gedit_changecase_plugin)
|
||||
|
||||
typedef enum {
|
||||
TO_UPPER_CASE,
|
||||
TO_LOWER_CASE,
|
||||
INVERT_CASE,
|
||||
TO_TITLE_CASE,
|
||||
} ChangeCaseChoice;
|
||||
|
||||
static void
|
||||
do_upper_case (GtkTextBuffer *buffer,
|
||||
GtkTextIter *start,
|
||||
GtkTextIter *end)
|
||||
{
|
||||
GString *s = g_string_new (NULL);
|
||||
|
||||
while (!gtk_text_iter_is_end (start) &&
|
||||
!gtk_text_iter_equal (start, end))
|
||||
{
|
||||
gunichar c, nc;
|
||||
|
||||
c = gtk_text_iter_get_char (start);
|
||||
nc = g_unichar_toupper (c);
|
||||
g_string_append_unichar (s, nc);
|
||||
|
||||
gtk_text_iter_forward_char (start);
|
||||
}
|
||||
|
||||
gtk_text_buffer_delete_selection (buffer, TRUE, TRUE);
|
||||
gtk_text_buffer_insert_at_cursor (buffer, s->str, s->len);
|
||||
|
||||
g_string_free (s, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
do_lower_case (GtkTextBuffer *buffer,
|
||||
GtkTextIter *start,
|
||||
GtkTextIter *end)
|
||||
{
|
||||
GString *s = g_string_new (NULL);
|
||||
|
||||
while (!gtk_text_iter_is_end (start) &&
|
||||
!gtk_text_iter_equal (start, end))
|
||||
{
|
||||
gunichar c, nc;
|
||||
|
||||
c = gtk_text_iter_get_char (start);
|
||||
nc = g_unichar_tolower (c);
|
||||
g_string_append_unichar (s, nc);
|
||||
|
||||
gtk_text_iter_forward_char (start);
|
||||
}
|
||||
|
||||
gtk_text_buffer_delete_selection (buffer, TRUE, TRUE);
|
||||
gtk_text_buffer_insert_at_cursor (buffer, s->str, s->len);
|
||||
|
||||
g_string_free (s, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
do_invert_case (GtkTextBuffer *buffer,
|
||||
GtkTextIter *start,
|
||||
GtkTextIter *end)
|
||||
{
|
||||
GString *s = g_string_new (NULL);
|
||||
|
||||
while (!gtk_text_iter_is_end (start) &&
|
||||
!gtk_text_iter_equal (start, end))
|
||||
{
|
||||
gunichar c, nc;
|
||||
|
||||
c = gtk_text_iter_get_char (start);
|
||||
if (g_unichar_islower (c))
|
||||
nc = g_unichar_toupper (c);
|
||||
else
|
||||
nc = g_unichar_tolower (c);
|
||||
g_string_append_unichar (s, nc);
|
||||
|
||||
gtk_text_iter_forward_char (start);
|
||||
}
|
||||
|
||||
gtk_text_buffer_delete_selection (buffer, TRUE, TRUE);
|
||||
gtk_text_buffer_insert_at_cursor (buffer, s->str, s->len);
|
||||
|
||||
g_string_free (s, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
do_title_case (GtkTextBuffer *buffer,
|
||||
GtkTextIter *start,
|
||||
GtkTextIter *end)
|
||||
{
|
||||
GString *s = g_string_new (NULL);
|
||||
|
||||
while (!gtk_text_iter_is_end (start) &&
|
||||
!gtk_text_iter_equal (start, end))
|
||||
{
|
||||
gunichar c, nc;
|
||||
|
||||
c = gtk_text_iter_get_char (start);
|
||||
if (gtk_text_iter_starts_word (start))
|
||||
nc = g_unichar_totitle (c);
|
||||
else
|
||||
nc = g_unichar_tolower (c);
|
||||
g_string_append_unichar (s, nc);
|
||||
|
||||
gtk_text_iter_forward_char (start);
|
||||
}
|
||||
|
||||
gtk_text_buffer_delete_selection (buffer, TRUE, TRUE);
|
||||
gtk_text_buffer_insert_at_cursor (buffer, s->str, s->len);
|
||||
|
||||
g_string_free (s, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
change_case (GeditWindow *window,
|
||||
ChangeCaseChoice choice)
|
||||
{
|
||||
GeditDocument *doc;
|
||||
GtkTextIter start, end;
|
||||
|
||||
gedit_debug (DEBUG_PLUGINS);
|
||||
|
||||
doc = gedit_window_get_active_document (window);
|
||||
g_return_if_fail (doc != NULL);
|
||||
|
||||
if (!gtk_text_buffer_get_selection_bounds (GTK_TEXT_BUFFER (doc),
|
||||
&start, &end))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
gtk_text_buffer_begin_user_action (GTK_TEXT_BUFFER (doc));
|
||||
|
||||
switch (choice)
|
||||
{
|
||||
case TO_UPPER_CASE:
|
||||
do_upper_case (GTK_TEXT_BUFFER (doc), &start, &end);
|
||||
break;
|
||||
case TO_LOWER_CASE:
|
||||
do_lower_case (GTK_TEXT_BUFFER (doc), &start, &end);
|
||||
break;
|
||||
case INVERT_CASE:
|
||||
do_invert_case (GTK_TEXT_BUFFER (doc), &start, &end);
|
||||
break;
|
||||
case TO_TITLE_CASE:
|
||||
do_title_case (GTK_TEXT_BUFFER (doc), &start, &end);
|
||||
break;
|
||||
default:
|
||||
g_return_if_reached ();
|
||||
}
|
||||
|
||||
gtk_text_buffer_end_user_action (GTK_TEXT_BUFFER (doc));
|
||||
}
|
||||
|
||||
static void
|
||||
upper_case_cb (GtkAction *action,
|
||||
GeditWindow *window)
|
||||
{
|
||||
change_case (window, TO_UPPER_CASE);
|
||||
}
|
||||
|
||||
static void
|
||||
lower_case_cb (GtkAction *action,
|
||||
GeditWindow *window)
|
||||
{
|
||||
change_case (window, TO_LOWER_CASE);
|
||||
}
|
||||
|
||||
static void
|
||||
invert_case_cb (GtkAction *action,
|
||||
GeditWindow *window)
|
||||
{
|
||||
change_case (window, INVERT_CASE);
|
||||
}
|
||||
|
||||
static void
|
||||
title_case_cb (GtkAction *action,
|
||||
GeditWindow *window)
|
||||
{
|
||||
change_case (window, TO_TITLE_CASE);
|
||||
}
|
||||
|
||||
static const GtkActionEntry action_entries[] =
|
||||
{
|
||||
{ "ChangeCase", NULL, N_("C_hange Case") },
|
||||
{ "UpperCase", NULL, N_("All _Upper Case"), NULL,
|
||||
N_("Change selected text to upper case"),
|
||||
G_CALLBACK (upper_case_cb) },
|
||||
{ "LowerCase", NULL, N_("All _Lower Case"), NULL,
|
||||
N_("Change selected text to lower case"),
|
||||
G_CALLBACK (lower_case_cb) },
|
||||
{ "InvertCase", NULL, N_("_Invert Case"), NULL,
|
||||
N_("Invert the case of selected text"),
|
||||
G_CALLBACK (invert_case_cb) },
|
||||
{ "TitleCase", NULL, N_("_Title Case"), NULL,
|
||||
N_("Capitalize the first letter of each selected word"),
|
||||
G_CALLBACK (title_case_cb) }
|
||||
};
|
||||
|
||||
const gchar submenu[] =
|
||||
"<ui>"
|
||||
" <menubar name='MenuBar'>"
|
||||
" <menu name='EditMenu' action='Edit'>"
|
||||
" <placeholder name='EditOps_6'>"
|
||||
" <menu action='ChangeCase'>"
|
||||
" <menuitem action='UpperCase'/>"
|
||||
" <menuitem action='LowerCase'/>"
|
||||
" <menuitem action='InvertCase'/>"
|
||||
" <menuitem action='TitleCase'/>"
|
||||
" </menu>"
|
||||
" </placeholder>"
|
||||
" </menu>"
|
||||
" </menubar>"
|
||||
"</ui>";
|
||||
|
||||
static void
|
||||
gedit_changecase_plugin_init (GeditChangecasePlugin *plugin)
|
||||
{
|
||||
gedit_debug_message (DEBUG_PLUGINS, "GeditChangecasePlugin initializing");
|
||||
}
|
||||
|
||||
static void
|
||||
gedit_changecase_plugin_finalize (GObject *object)
|
||||
{
|
||||
G_OBJECT_CLASS (gedit_changecase_plugin_parent_class)->finalize (object);
|
||||
|
||||
gedit_debug_message (DEBUG_PLUGINS, "GeditChangecasePlugin finalizing");
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GtkActionGroup *action_group;
|
||||
guint ui_id;
|
||||
} WindowData;
|
||||
|
||||
static void
|
||||
free_window_data (WindowData *data)
|
||||
{
|
||||
g_return_if_fail (data != NULL);
|
||||
|
||||
g_slice_free (WindowData, data);
|
||||
}
|
||||
|
||||
static void
|
||||
update_ui_real (GeditWindow *window,
|
||||
WindowData *data)
|
||||
{
|
||||
GtkTextView *view;
|
||||
GtkAction *action;
|
||||
gboolean sensitive = FALSE;
|
||||
|
||||
gedit_debug (DEBUG_PLUGINS);
|
||||
|
||||
view = GTK_TEXT_VIEW (gedit_window_get_active_view (window));
|
||||
|
||||
if (view != NULL)
|
||||
{
|
||||
GtkTextBuffer *buffer;
|
||||
|
||||
buffer = gtk_text_view_get_buffer (view);
|
||||
sensitive = (gtk_text_view_get_editable (view) &&
|
||||
gtk_text_buffer_get_has_selection (buffer));
|
||||
}
|
||||
|
||||
action = gtk_action_group_get_action (data->action_group,
|
||||
"ChangeCase");
|
||||
gtk_action_set_sensitive (action, sensitive);
|
||||
}
|
||||
|
||||
static void
|
||||
impl_activate (GeditPlugin *plugin,
|
||||
GeditWindow *window)
|
||||
{
|
||||
GtkUIManager *manager;
|
||||
WindowData *data;
|
||||
GError *error = NULL;
|
||||
|
||||
gedit_debug (DEBUG_PLUGINS);
|
||||
|
||||
data = g_slice_new (WindowData);
|
||||
|
||||
manager = gedit_window_get_ui_manager (window);
|
||||
|
||||
data->action_group = gtk_action_group_new ("GeditChangecasePluginActions");
|
||||
gtk_action_group_set_translation_domain (data->action_group,
|
||||
GETTEXT_PACKAGE);
|
||||
gtk_action_group_add_actions (data->action_group,
|
||||
action_entries,
|
||||
G_N_ELEMENTS (action_entries),
|
||||
window);
|
||||
|
||||
gtk_ui_manager_insert_action_group (manager, data->action_group, -1);
|
||||
|
||||
data->ui_id = gtk_ui_manager_add_ui_from_string (manager,
|
||||
submenu,
|
||||
-1,
|
||||
&error);
|
||||
if (data->ui_id == 0)
|
||||
{
|
||||
g_warning ("%s", error->message);
|
||||
free_window_data (data);
|
||||
return;
|
||||
}
|
||||
|
||||
g_object_set_data_full (G_OBJECT (window),
|
||||
WINDOW_DATA_KEY,
|
||||
data,
|
||||
(GDestroyNotify) free_window_data);
|
||||
|
||||
update_ui_real (window, data);
|
||||
}
|
||||
|
||||
static void
|
||||
impl_deactivate (GeditPlugin *plugin,
|
||||
GeditWindow *window)
|
||||
{
|
||||
GtkUIManager *manager;
|
||||
WindowData *data;
|
||||
|
||||
gedit_debug (DEBUG_PLUGINS);
|
||||
|
||||
manager = gedit_window_get_ui_manager (window);
|
||||
|
||||
data = (WindowData *) g_object_get_data (G_OBJECT (window), WINDOW_DATA_KEY);
|
||||
g_return_if_fail (data != NULL);
|
||||
|
||||
gtk_ui_manager_remove_ui (manager, data->ui_id);
|
||||
gtk_ui_manager_remove_action_group (manager, data->action_group);
|
||||
|
||||
g_object_set_data (G_OBJECT (window), WINDOW_DATA_KEY, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
impl_update_ui (GeditPlugin *plugin,
|
||||
GeditWindow *window)
|
||||
{
|
||||
WindowData *data;
|
||||
|
||||
gedit_debug (DEBUG_PLUGINS);
|
||||
|
||||
data = (WindowData *) g_object_get_data (G_OBJECT (window), WINDOW_DATA_KEY);
|
||||
g_return_if_fail (data != NULL);
|
||||
|
||||
update_ui_real (window, data);
|
||||
}
|
||||
|
||||
static void
|
||||
gedit_changecase_plugin_class_init (GeditChangecasePluginClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GeditPluginClass *plugin_class = GEDIT_PLUGIN_CLASS (klass);
|
||||
|
||||
object_class->finalize = gedit_changecase_plugin_finalize;
|
||||
|
||||
plugin_class->activate = impl_activate;
|
||||
plugin_class->deactivate = impl_deactivate;
|
||||
plugin_class->update_ui = impl_update_ui;
|
||||
}
|
72
plugins/changecase/gedit-changecase-plugin.h
Executable file
72
plugins/changecase/gedit-changecase-plugin.h
Executable file
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* gedit-changecase-plugin.h
|
||||
*
|
||||
* Copyright (C) 2004-2005 - Paolo Borelli
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef __GEDIT_CHANGECASE_PLUGIN_H__
|
||||
#define __GEDIT_CHANGECASE_PLUGIN_H__
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
#include <gedit/gedit-plugin.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/*
|
||||
* Type checking and casting macros
|
||||
*/
|
||||
#define GEDIT_TYPE_CHANGECASE_PLUGIN (gedit_changecase_plugin_get_type ())
|
||||
#define GEDIT_CHANGECASE_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GEDIT_TYPE_CHANGECASE_PLUGIN, GeditChangecasePlugin))
|
||||
#define GEDIT_CHANGECASE_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GEDIT_TYPE_CHANGECASE_PLUGIN, GeditChangecasePluginClass))
|
||||
#define GEDIT_IS_CHANGECASE_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GEDIT_TYPE_CHANGECASE_PLUGIN))
|
||||
#define GEDIT_IS_CHANGECASE_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GEDIT_TYPE_CHANGECASE_PLUGIN))
|
||||
#define GEDIT_CHANGECASE_PLUGIN_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GEDIT_TYPE_CHANGECASE_PLUGIN, GeditChangecasePluginClass))
|
||||
|
||||
/*
|
||||
* Main object structure
|
||||
*/
|
||||
typedef struct _GeditChangecasePlugin GeditChangecasePlugin;
|
||||
|
||||
struct _GeditChangecasePlugin
|
||||
{
|
||||
GeditPlugin parent_instance;
|
||||
};
|
||||
|
||||
/*
|
||||
* Class definition
|
||||
*/
|
||||
typedef struct _GeditChangecasePluginClass GeditChangecasePluginClass;
|
||||
|
||||
struct _GeditChangecasePluginClass
|
||||
{
|
||||
GeditPluginClass parent_class;
|
||||
};
|
||||
|
||||
/*
|
||||
* Public methods
|
||||
*/
|
||||
GType gedit_changecase_plugin_get_type (void) G_GNUC_CONST;
|
||||
|
||||
/* All the plugins must implement this function */
|
||||
G_MODULE_EXPORT GType register_gedit_plugin (GTypeModule *module);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GEDIT_CHANGECASE_PLUGIN_H__ */
|
49
plugins/checkupdate/Makefile.am
Executable file
49
plugins/checkupdate/Makefile.am
Executable file
@@ -0,0 +1,49 @@
|
||||
# gedit win32 updater
|
||||
|
||||
plugindir = $(GEDIT_PLUGINS_LIBS_DIR)
|
||||
|
||||
INCLUDES = \
|
||||
-I$(top_srcdir) \
|
||||
$(GEDIT_CFLAGS) \
|
||||
$(LIBSOUP_CFLAGS) \
|
||||
$(WARN_CFLAGS) \
|
||||
$(DISABLE_DEPRECATED_CFLAGS)
|
||||
|
||||
plugin_LTLIBRARIES = libcheckupdate.la
|
||||
|
||||
libcheckupdate_la_SOURCES = \
|
||||
gedit-check-update-plugin.h \
|
||||
gedit-check-update-plugin.c
|
||||
|
||||
libcheckupdate_la_LDFLAGS = $(PLUGIN_LIBTOOL_FLAGS)
|
||||
libcheckupdate_la_LIBADD = $(GEDIT_LIBS) $(LIBSOUP_LIBS)
|
||||
|
||||
plugin_in_files = checkupdate.gedit-plugin.desktop.in
|
||||
|
||||
%.gedit-plugin: %.gedit-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:.gedit-plugin.desktop.in=.gedit-plugin)
|
||||
|
||||
schemasdir = $(MATECONF_SCHEMA_FILE_DIR)
|
||||
schemas_in_files = gedit-check-update.schemas.in
|
||||
schemas_DATA = $(schemas_in_files:.schemas.in=.schemas)
|
||||
@INTLTOOL_SCHEMAS_RULE@
|
||||
|
||||
if MATECONF_SCHEMAS_INSTALL
|
||||
install-data-local:
|
||||
if test -z "$(DESTDIR)" ; then \
|
||||
for p in $(schemas_DATA) ; do \
|
||||
MATECONF_CONFIG_SOURCE=$(MATECONF_SCHEMA_CONFIG_SOURCE) $(MATECONFTOOL) --makefile-install-rule $(top_builddir)/plugins/checkupdate/$$p ; \
|
||||
done \
|
||||
fi
|
||||
else
|
||||
install-data-local:
|
||||
endif
|
||||
|
||||
EXTRA_DIST = $(plugin_in_files) $(schemas_in_files)
|
||||
|
||||
CLEANFILES = $(plugin_DATA) $(schemas_DATA)
|
||||
|
||||
DISTCLEANFILES = $(plugin_DATA) $(schemas_DATA)
|
||||
|
||||
-include $(top_srcdir)/git.mk
|
9
plugins/checkupdate/checkupdate.gedit-plugin.desktop.in
Executable file
9
plugins/checkupdate/checkupdate.gedit-plugin.desktop.in
Executable file
@@ -0,0 +1,9 @@
|
||||
[Gedit Plugin]
|
||||
Module=checkupdate
|
||||
IAge=2
|
||||
_Name=Check update
|
||||
_Description=Check for latest version of gedit
|
||||
Icon=gedit-plugin
|
||||
Authors=Ignacio Casal Quinteiro <icq@gnome.org>
|
||||
Copyright=Copyright © 2009 Ignacio Casal Quinteiro
|
||||
Website=http://www.gedit.org
|
697
plugins/checkupdate/gedit-check-update-plugin.c
Executable file
697
plugins/checkupdate/gedit-check-update-plugin.c
Executable file
@@ -0,0 +1,697 @@
|
||||
/*
|
||||
* Copyright (C) 2009 - Ignacio Casal Quinteiro <icq@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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include "gedit-check-update-plugin.h"
|
||||
|
||||
#include <glib/gi18n-lib.h>
|
||||
#include <gedit/gedit-debug.h>
|
||||
#include <gedit/gedit-utils.h>
|
||||
#include <libsoup/soup.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <mateconf/mateconf-client.h>
|
||||
|
||||
#if !GTK_CHECK_VERSION(2, 17, 1)
|
||||
#include <gedit/gedit-message-area.h>
|
||||
#endif
|
||||
|
||||
#define MATECONF_KEY_BASE "/apps/gedit-2/plugins/checkupdate"
|
||||
#define MATECONF_KEY_IGNORE_VERSION MATECONF_KEY_BASE "/ignore_version"
|
||||
|
||||
#define WINDOW_DATA_KEY "GeditCheckUpdatePluginWindowData"
|
||||
|
||||
#define VERSION_PLACE "<a href=\"[0-9]\\.[0-9]+/\">"
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
#define GEDIT_URL "http://ftp.acc.umu.se/pub/mate/binaries/win32/gedit/"
|
||||
#define FILE_REGEX "gedit\\-setup\\-[0-9]+\\.[0-9]+\\.[0-9]+(\\-[0-9]+)?\\.exe"
|
||||
#else
|
||||
#define GEDIT_URL "http://ftp.acc.umu.se/pub/mate/binaries/mac/gedit/"
|
||||
#define FILE_REGEX "gedit\\-[0-9]+\\.[0-9]+\\.[0-9]+(\\-[0-9]+)?\\.dmg"
|
||||
#endif
|
||||
|
||||
#ifdef OS_OSX
|
||||
#include "gedit/osx/gedit-osx.h"
|
||||
#endif
|
||||
|
||||
#define GEDIT_CHECK_UPDATE_PLUGIN_GET_PRIVATE(object) \
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE ((object), \
|
||||
GEDIT_TYPE_CHECK_UPDATE_PLUGIN, \
|
||||
GeditCheckUpdatePluginPrivate))
|
||||
|
||||
GEDIT_PLUGIN_REGISTER_TYPE (GeditCheckUpdatePlugin, gedit_check_update_plugin)
|
||||
|
||||
struct _GeditCheckUpdatePluginPrivate
|
||||
{
|
||||
SoupSession *session;
|
||||
|
||||
MateConfClient *mateconf_client;
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GeditCheckUpdatePlugin *plugin;
|
||||
|
||||
gchar *url;
|
||||
gchar *version;
|
||||
} WindowData;
|
||||
|
||||
static void
|
||||
free_window_data (gpointer data)
|
||||
{
|
||||
WindowData *window_data;
|
||||
|
||||
if (data == NULL)
|
||||
return;
|
||||
|
||||
window_data = (WindowData *)data;
|
||||
|
||||
g_free (window_data->url);
|
||||
g_free (window_data->version);
|
||||
g_slice_free (WindowData, data);
|
||||
}
|
||||
|
||||
static void
|
||||
gedit_check_update_plugin_init (GeditCheckUpdatePlugin *plugin)
|
||||
{
|
||||
plugin->priv = GEDIT_CHECK_UPDATE_PLUGIN_GET_PRIVATE (plugin);
|
||||
|
||||
gedit_debug_message (DEBUG_PLUGINS,
|
||||
"GeditCheckUpdatePlugin initializing");
|
||||
|
||||
plugin->priv->session = soup_session_async_new ();
|
||||
|
||||
plugin->priv->mateconf_client = mateconf_client_get_default ();
|
||||
|
||||
mateconf_client_add_dir (plugin->priv->mateconf_client,
|
||||
MATECONF_KEY_BASE,
|
||||
MATECONF_CLIENT_PRELOAD_ONELEVEL,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gedit_check_update_plugin_dispose (GObject *object)
|
||||
{
|
||||
GeditCheckUpdatePlugin *plugin = GEDIT_CHECK_UPDATE_PLUGIN (object);
|
||||
|
||||
if (plugin->priv->session != NULL)
|
||||
{
|
||||
g_object_unref (plugin->priv->session);
|
||||
plugin->priv->session = NULL;
|
||||
}
|
||||
|
||||
if (plugin->priv->mateconf_client != NULL)
|
||||
{
|
||||
mateconf_client_suggest_sync (plugin->priv->mateconf_client, NULL);
|
||||
|
||||
g_object_unref (G_OBJECT (plugin->priv->mateconf_client));
|
||||
|
||||
plugin->priv->mateconf_client = NULL;
|
||||
}
|
||||
|
||||
gedit_debug_message (DEBUG_PLUGINS,
|
||||
"GeditCheckUpdatePlugin disposing");
|
||||
|
||||
G_OBJECT_CLASS (gedit_check_update_plugin_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gedit_check_update_plugin_finalize (GObject *object)
|
||||
{
|
||||
gedit_debug_message (DEBUG_PLUGINS,
|
||||
"GeditCheckUpdatePlugin finalizing");
|
||||
|
||||
G_OBJECT_CLASS (gedit_check_update_plugin_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
set_contents (GtkWidget *infobar,
|
||||
GtkWidget *contents)
|
||||
{
|
||||
#if !GTK_CHECK_VERSION (2, 17, 1)
|
||||
gedit_message_area_set_contents (GEDIT_MESSAGE_AREA (infobar),
|
||||
contents);
|
||||
#else
|
||||
GtkWidget *content_area;
|
||||
|
||||
content_area = gtk_info_bar_get_content_area (GTK_INFO_BAR (infobar));
|
||||
gtk_container_add (GTK_CONTAINER (content_area), contents);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
set_message_area_text_and_icon (GtkWidget *message_area,
|
||||
const gchar *icon_stock_id,
|
||||
const gchar *primary_text,
|
||||
const gchar *secondary_text)
|
||||
{
|
||||
GtkWidget *hbox_content;
|
||||
GtkWidget *image;
|
||||
GtkWidget *vbox;
|
||||
gchar *primary_markup;
|
||||
gchar *secondary_markup;
|
||||
GtkWidget *primary_label;
|
||||
GtkWidget *secondary_label;
|
||||
|
||||
hbox_content = gtk_hbox_new (FALSE, 8);
|
||||
gtk_widget_show (hbox_content);
|
||||
|
||||
image = gtk_image_new_from_stock (icon_stock_id, GTK_ICON_SIZE_DIALOG);
|
||||
gtk_widget_show (image);
|
||||
gtk_box_pack_start (GTK_BOX (hbox_content), image, FALSE, FALSE, 0);
|
||||
gtk_misc_set_alignment (GTK_MISC (image), 0.5, 0);
|
||||
|
||||
vbox = gtk_vbox_new (FALSE, 6);
|
||||
gtk_widget_show (vbox);
|
||||
gtk_box_pack_start (GTK_BOX (hbox_content), vbox, TRUE, TRUE, 0);
|
||||
|
||||
primary_markup = g_strdup_printf ("<b>%s</b>", primary_text);
|
||||
primary_label = gtk_label_new (primary_markup);
|
||||
g_free (primary_markup);
|
||||
gtk_widget_show (primary_label);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), primary_label, TRUE, TRUE, 0);
|
||||
gtk_label_set_use_markup (GTK_LABEL (primary_label), TRUE);
|
||||
gtk_label_set_line_wrap (GTK_LABEL (primary_label), TRUE);
|
||||
gtk_misc_set_alignment (GTK_MISC (primary_label), 0, 0.5);
|
||||
GTK_WIDGET_SET_FLAGS (primary_label, GTK_CAN_FOCUS);
|
||||
gtk_label_set_selectable (GTK_LABEL (primary_label), TRUE);
|
||||
|
||||
if (secondary_text != NULL)
|
||||
{
|
||||
secondary_markup = g_strdup_printf ("<small>%s</small>",
|
||||
secondary_text);
|
||||
secondary_label = gtk_label_new (secondary_markup);
|
||||
g_free (secondary_markup);
|
||||
gtk_widget_show (secondary_label);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), secondary_label, TRUE, TRUE, 0);
|
||||
GTK_WIDGET_SET_FLAGS (secondary_label, GTK_CAN_FOCUS);
|
||||
gtk_label_set_use_markup (GTK_LABEL (secondary_label), TRUE);
|
||||
gtk_label_set_line_wrap (GTK_LABEL (secondary_label), TRUE);
|
||||
gtk_label_set_selectable (GTK_LABEL (secondary_label), TRUE);
|
||||
gtk_misc_set_alignment (GTK_MISC (secondary_label), 0, 0.5);
|
||||
}
|
||||
|
||||
set_contents (message_area, hbox_content);
|
||||
}
|
||||
|
||||
static void
|
||||
on_response_cb (GtkWidget *infobar,
|
||||
gint response_id,
|
||||
GeditWindow *window)
|
||||
{
|
||||
if (response_id == GTK_RESPONSE_YES)
|
||||
{
|
||||
GError *error = NULL;
|
||||
WindowData *data;
|
||||
|
||||
data = g_object_get_data (G_OBJECT (window),
|
||||
WINDOW_DATA_KEY);
|
||||
|
||||
#ifdef OS_OSX
|
||||
gedit_osx_show_url (data->url);
|
||||
#else
|
||||
gtk_show_uri (gtk_widget_get_screen (GTK_WIDGET (window)),
|
||||
data->url,
|
||||
GDK_CURRENT_TIME,
|
||||
&error);
|
||||
#endif
|
||||
if (error != NULL)
|
||||
{
|
||||
GtkWidget *dialog;
|
||||
|
||||
dialog = gtk_message_dialog_new (GTK_WINDOW (window),
|
||||
GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||
GTK_MESSAGE_ERROR,
|
||||
GTK_BUTTONS_CLOSE,
|
||||
_("There was an error displaying the URI."));
|
||||
|
||||
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
|
||||
"%s", error->message);
|
||||
|
||||
g_signal_connect (G_OBJECT (dialog),
|
||||
"response",
|
||||
G_CALLBACK (gtk_widget_destroy),
|
||||
NULL);
|
||||
|
||||
gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
|
||||
|
||||
gtk_widget_show (dialog);
|
||||
|
||||
g_error_free (error);
|
||||
}
|
||||
}
|
||||
else if (response_id == GTK_RESPONSE_NO)
|
||||
{
|
||||
WindowData *data;
|
||||
|
||||
data = g_object_get_data (G_OBJECT (window), WINDOW_DATA_KEY);
|
||||
|
||||
mateconf_client_set_string (data->plugin->priv->mateconf_client,
|
||||
MATECONF_KEY_IGNORE_VERSION,
|
||||
data->version,
|
||||
NULL);
|
||||
}
|
||||
|
||||
g_object_set_data (G_OBJECT (window),
|
||||
WINDOW_DATA_KEY,
|
||||
NULL);
|
||||
|
||||
gtk_widget_destroy (infobar);
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
create_infobar (GeditWindow *window,
|
||||
const gchar *version)
|
||||
{
|
||||
GtkWidget *infobar;
|
||||
gchar *message;
|
||||
|
||||
#if !GTK_CHECK_VERSION (2, 17, 1)
|
||||
infobar = gedit_message_area_new ();
|
||||
|
||||
gedit_message_area_add_stock_button_with_text (GEDIT_MESSAGE_AREA (infobar),
|
||||
_("_Download"),
|
||||
GTK_STOCK_SAVE,
|
||||
GTK_RESPONSE_YES);
|
||||
gedit_message_area_add_stock_button_with_text (GEDIT_MESSAGE_AREA (infobar),
|
||||
_("_Ignore Version"),
|
||||
GTK_STOCK_DISCARD,
|
||||
GTK_RESPONSE_NO);
|
||||
gedit_message_area_add_button (GEDIT_MESSAGE_AREA (infobar),
|
||||
GTK_STOCK_CANCEL,
|
||||
GTK_RESPONSE_CANCEL);
|
||||
#else
|
||||
GtkWidget *button;
|
||||
|
||||
infobar = gtk_info_bar_new ();
|
||||
|
||||
button = gedit_gtk_button_new_with_stock_icon (_("_Download"),
|
||||
GTK_STOCK_SAVE);
|
||||
gtk_widget_show (button);
|
||||
|
||||
gtk_info_bar_add_action_widget (GTK_INFO_BAR (infobar),
|
||||
button,
|
||||
GTK_RESPONSE_YES);
|
||||
|
||||
button = gedit_gtk_button_new_with_stock_icon (_("_Ignore Version"),
|
||||
GTK_STOCK_DISCARD);
|
||||
gtk_widget_show (button);
|
||||
|
||||
gtk_info_bar_add_action_widget (GTK_INFO_BAR (infobar),
|
||||
button,
|
||||
GTK_RESPONSE_NO);
|
||||
|
||||
gtk_info_bar_add_button (GTK_INFO_BAR (infobar),
|
||||
GTK_STOCK_CANCEL,
|
||||
GTK_RESPONSE_CANCEL);
|
||||
|
||||
gtk_info_bar_set_message_type (GTK_INFO_BAR (infobar),
|
||||
GTK_MESSAGE_INFO);
|
||||
#endif
|
||||
|
||||
message = g_strdup_printf ("%s (%s)", _("There is a new version of gedit"), version);
|
||||
set_message_area_text_and_icon (infobar,
|
||||
"gtk-dialog-info",
|
||||
message,
|
||||
_("You can download the new version of gedit"
|
||||
" by clicking on the download button or"
|
||||
" ignore that version and wait for a new one"));
|
||||
|
||||
g_free (message);
|
||||
|
||||
g_signal_connect (infobar, "response",
|
||||
G_CALLBACK (on_response_cb),
|
||||
window);
|
||||
|
||||
return infobar;
|
||||
}
|
||||
|
||||
static void
|
||||
pack_infobar (GtkWidget *window,
|
||||
GtkWidget *infobar)
|
||||
{
|
||||
GtkWidget *vbox;
|
||||
|
||||
vbox = gtk_bin_get_child (GTK_BIN (window));
|
||||
|
||||
gtk_box_pack_start (GTK_BOX (vbox), infobar, FALSE, FALSE, 0);
|
||||
gtk_box_reorder_child (GTK_BOX (vbox), infobar, 2);
|
||||
}
|
||||
|
||||
static gchar *
|
||||
get_file (const gchar *text,
|
||||
const gchar *regex_place)
|
||||
{
|
||||
GRegex *regex;
|
||||
GMatchInfo *match_info;
|
||||
gchar *word = NULL;
|
||||
|
||||
regex = g_regex_new (regex_place, 0, 0, NULL);
|
||||
g_regex_match (regex, text, 0, &match_info);
|
||||
while (g_match_info_matches (match_info))
|
||||
{
|
||||
g_free (word);
|
||||
|
||||
word = g_match_info_fetch (match_info, 0);
|
||||
|
||||
g_match_info_next (match_info, NULL);
|
||||
}
|
||||
g_match_info_free (match_info);
|
||||
g_regex_unref (regex);
|
||||
|
||||
return word;
|
||||
}
|
||||
|
||||
static void
|
||||
get_numbers (const gchar *version,
|
||||
gint *major,
|
||||
gint *minor,
|
||||
gint *micro)
|
||||
{
|
||||
gchar **split;
|
||||
gint num = 2;
|
||||
|
||||
if (micro != NULL)
|
||||
num = 3;
|
||||
|
||||
split = g_strsplit (version, ".", num);
|
||||
*major = atoi (split[0]);
|
||||
*minor = atoi (split[1]);
|
||||
if (micro != NULL)
|
||||
*micro = atoi (split[2]);
|
||||
|
||||
g_strfreev (split);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
newer_version (const gchar *v1,
|
||||
const gchar *v2,
|
||||
gboolean with_micro)
|
||||
{
|
||||
gboolean newer = FALSE;
|
||||
gint major1, minor1, micro1;
|
||||
gint major2, minor2, micro2;
|
||||
|
||||
if (v1 == NULL || v2 == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (with_micro)
|
||||
{
|
||||
get_numbers (v1, &major1, &minor1, µ1);
|
||||
get_numbers (v2, &major2, &minor2, µ2);
|
||||
}
|
||||
else
|
||||
{
|
||||
get_numbers (v1, &major1, &minor1, NULL);
|
||||
get_numbers (v2, &major2, &minor2, NULL);
|
||||
}
|
||||
|
||||
if (major1 > major2)
|
||||
{
|
||||
newer = TRUE;
|
||||
}
|
||||
else if (minor1 > minor2 && major1 == major2)
|
||||
{
|
||||
newer = TRUE;
|
||||
}
|
||||
else if (with_micro && micro1 > micro2 && minor1 == minor2)
|
||||
{
|
||||
newer = TRUE;
|
||||
}
|
||||
|
||||
return newer;
|
||||
}
|
||||
|
||||
static gchar *
|
||||
parse_file_version (const gchar *file)
|
||||
{
|
||||
gchar *p, *aux;
|
||||
|
||||
p = (gchar *)file;
|
||||
|
||||
while (*p != '\0' && !g_ascii_isdigit (*p))
|
||||
{
|
||||
p++;
|
||||
}
|
||||
|
||||
if (*p == '\0')
|
||||
return NULL;
|
||||
|
||||
aux = g_strrstr (p, "-");
|
||||
if (aux == NULL)
|
||||
aux = g_strrstr (p, ".");
|
||||
|
||||
return g_strndup (p, aux - p);
|
||||
}
|
||||
|
||||
static gchar *
|
||||
get_ignore_version (GeditCheckUpdatePlugin *plugin)
|
||||
{
|
||||
return mateconf_client_get_string (plugin->priv->mateconf_client,
|
||||
MATECONF_KEY_IGNORE_VERSION,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
parse_page_file (SoupSession *session,
|
||||
SoupMessage *msg,
|
||||
GeditWindow *window)
|
||||
{
|
||||
if (msg->status_code == SOUP_STATUS_OK)
|
||||
{
|
||||
gchar *file;
|
||||
gchar *file_version;
|
||||
gchar *ignore_version;
|
||||
WindowData *data;
|
||||
|
||||
data = g_object_get_data (G_OBJECT (window), WINDOW_DATA_KEY);
|
||||
|
||||
file = get_file (msg->response_body->data, FILE_REGEX);
|
||||
file_version = parse_file_version (file);
|
||||
ignore_version = get_ignore_version (data->plugin);
|
||||
|
||||
if (newer_version (file_version, VERSION, TRUE) &&
|
||||
(ignore_version == NULL || *ignore_version == '\0' ||
|
||||
newer_version (file_version, ignore_version, TRUE)))
|
||||
{
|
||||
GtkWidget *infobar;
|
||||
WindowData *data;
|
||||
gchar *file_url;
|
||||
|
||||
data = g_object_get_data (G_OBJECT (window),
|
||||
WINDOW_DATA_KEY);
|
||||
|
||||
file_url = g_strconcat (data->url, file, NULL);
|
||||
|
||||
g_free (data->url);
|
||||
data->url = file_url;
|
||||
data->version = g_strdup (file_version);
|
||||
|
||||
infobar = create_infobar (window, file_version);
|
||||
pack_infobar (GTK_WIDGET (window), infobar);
|
||||
gtk_widget_show (infobar);
|
||||
}
|
||||
|
||||
g_free (ignore_version);
|
||||
g_free (file_version);
|
||||
g_free (file);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_object_set_data (G_OBJECT (window),
|
||||
WINDOW_DATA_KEY,
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_unstable (const gchar *version)
|
||||
{
|
||||
gchar **split;
|
||||
gint minor;
|
||||
gboolean unstable = TRUE;;
|
||||
|
||||
split = g_strsplit (version, ".", 2);
|
||||
minor = atoi (split[1]);
|
||||
g_strfreev (split);
|
||||
|
||||
if ((minor % 2) == 0)
|
||||
unstable = FALSE;
|
||||
|
||||
return unstable;
|
||||
}
|
||||
|
||||
static gchar *
|
||||
get_file_page_version (const gchar *text,
|
||||
const gchar *regex_place)
|
||||
{
|
||||
GRegex *regex;
|
||||
GMatchInfo *match_info;
|
||||
GString *string = NULL;
|
||||
gchar *unstable = NULL;
|
||||
gchar *stable = NULL;
|
||||
|
||||
regex = g_regex_new (regex_place, 0, 0, NULL);
|
||||
g_regex_match (regex, text, 0, &match_info);
|
||||
while (g_match_info_matches (match_info))
|
||||
{
|
||||
gint end;
|
||||
gint i;
|
||||
|
||||
g_match_info_fetch_pos (match_info, 0, NULL, &end);
|
||||
|
||||
string = g_string_new ("");
|
||||
|
||||
i = end;
|
||||
while (text[i] != '/')
|
||||
{
|
||||
string = g_string_append_c (string, text[i]);
|
||||
i++;
|
||||
}
|
||||
|
||||
if (is_unstable (string->str))
|
||||
{
|
||||
g_free (unstable);
|
||||
unstable = g_string_free (string, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_free (stable);
|
||||
stable = g_string_free (string, FALSE);
|
||||
}
|
||||
|
||||
g_match_info_next (match_info, NULL);
|
||||
}
|
||||
g_match_info_free (match_info);
|
||||
g_regex_unref (regex);
|
||||
|
||||
if ((GEDIT_MINOR_VERSION % 2) == 0)
|
||||
{
|
||||
g_free (unstable);
|
||||
|
||||
return stable;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We need to check that stable isn't newer than unstable */
|
||||
if (newer_version (stable, unstable, FALSE))
|
||||
{
|
||||
g_free (unstable);
|
||||
|
||||
return stable;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_free (stable);
|
||||
|
||||
return unstable;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
parse_page_version (SoupSession *session,
|
||||
SoupMessage *msg,
|
||||
GeditWindow *window)
|
||||
{
|
||||
if (msg->status_code == SOUP_STATUS_OK)
|
||||
{
|
||||
gchar *version;
|
||||
SoupMessage *msg2;
|
||||
WindowData *data;
|
||||
|
||||
data = g_object_get_data (G_OBJECT (window), WINDOW_DATA_KEY);
|
||||
|
||||
version = get_file_page_version (msg->response_body->data,
|
||||
VERSION_PLACE);
|
||||
|
||||
data->url = g_strconcat (GEDIT_URL, version, "/", NULL);
|
||||
g_free (version);
|
||||
msg2 = soup_message_new ("GET", data->url);
|
||||
|
||||
soup_session_queue_message (session, msg2,
|
||||
(SoupSessionCallback)parse_page_file,
|
||||
window);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_object_set_data (G_OBJECT (window),
|
||||
WINDOW_DATA_KEY,
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
impl_activate (GeditPlugin *plugin,
|
||||
GeditWindow *window)
|
||||
{
|
||||
SoupMessage *msg;
|
||||
WindowData *data;
|
||||
|
||||
gedit_debug (DEBUG_PLUGINS);
|
||||
|
||||
data = g_slice_new (WindowData);
|
||||
data->plugin = GEDIT_CHECK_UPDATE_PLUGIN (plugin);
|
||||
data->url = NULL;
|
||||
data->version = NULL;
|
||||
|
||||
g_object_set_data_full (G_OBJECT (window),
|
||||
WINDOW_DATA_KEY,
|
||||
data,
|
||||
free_window_data);
|
||||
|
||||
msg = soup_message_new ("GET", GEDIT_URL);
|
||||
|
||||
soup_session_queue_message (GEDIT_CHECK_UPDATE_PLUGIN (plugin)->priv->session, msg,
|
||||
(SoupSessionCallback)parse_page_version,
|
||||
window);
|
||||
}
|
||||
|
||||
static void
|
||||
impl_deactivate (GeditPlugin *plugin,
|
||||
GeditWindow *window)
|
||||
{
|
||||
|
||||
gedit_debug (DEBUG_PLUGINS);
|
||||
|
||||
soup_session_abort (GEDIT_CHECK_UPDATE_PLUGIN (plugin)->priv->session);
|
||||
|
||||
g_object_set_data (G_OBJECT (window),
|
||||
WINDOW_DATA_KEY,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gedit_check_update_plugin_class_init (GeditCheckUpdatePluginClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GeditPluginClass *plugin_class = GEDIT_PLUGIN_CLASS (klass);
|
||||
|
||||
g_type_class_add_private (object_class, sizeof (GeditCheckUpdatePluginPrivate));
|
||||
|
||||
object_class->finalize = gedit_check_update_plugin_finalize;
|
||||
object_class->dispose = gedit_check_update_plugin_dispose;
|
||||
|
||||
plugin_class->activate = impl_activate;
|
||||
plugin_class->deactivate = impl_deactivate;
|
||||
}
|
74
plugins/checkupdate/gedit-check-update-plugin.h
Executable file
74
plugins/checkupdate/gedit-check-update-plugin.h
Executable file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (C) 2009 - Ignacio Casal Quinteiro <icq@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 __GEDIT_CHECK_UPDATE_PLUGIN_H__
|
||||
#define __GEDIT_CHECK_UPDATE_PLUGIN_H__
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
#include <gedit/gedit-plugin.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/*
|
||||
* Type checking and casting macros
|
||||
*/
|
||||
#define GEDIT_TYPE_CHECK_UPDATE_PLUGIN (gedit_check_update_plugin_get_type ())
|
||||
#define GEDIT_CHECK_UPDATE_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GEDIT_TYPE_CHECK_UPDATE_PLUGIN, GeditCheckUpdatePlugin))
|
||||
#define GEDIT_CHECK_UPDATE_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GEDIT_TYPE_CHECK_UPDATE_PLUGIN, GeditCheckUpdatePluginClass))
|
||||
#define IS_GEDIT_CHECK_UPDATE_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GEDIT_TYPE_CHECK_UPDATE_PLUGIN))
|
||||
#define IS_GEDIT_CHECK_UPDATE_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GEDIT_TYPE_CHECK_UPDATE_PLUGIN))
|
||||
#define GEDIT_CHECK_UPDATE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GEDIT_TYPE_CHECK_UPDATE_PLUGIN, GeditCheckUpdatePluginClass))
|
||||
|
||||
/* Private structure type */
|
||||
typedef struct _GeditCheckUpdatePluginPrivate GeditCheckUpdatePluginPrivate;
|
||||
|
||||
/*
|
||||
* Main object structure
|
||||
*/
|
||||
typedef struct _GeditCheckUpdatePlugin GeditCheckUpdatePlugin;
|
||||
|
||||
struct _GeditCheckUpdatePlugin
|
||||
{
|
||||
GeditPlugin parent_instance;
|
||||
|
||||
/*< private >*/
|
||||
GeditCheckUpdatePluginPrivate *priv;
|
||||
};
|
||||
|
||||
/*
|
||||
* Class definition
|
||||
*/
|
||||
typedef struct _GeditCheckUpdatePluginClass GeditCheckUpdatePluginClass;
|
||||
|
||||
struct _GeditCheckUpdatePluginClass
|
||||
{
|
||||
GeditPluginClass parent_class;
|
||||
};
|
||||
|
||||
/*
|
||||
* Public methods
|
||||
*/
|
||||
GType gedit_check_update_plugin_get_type (void) G_GNUC_CONST;
|
||||
|
||||
/* All the plugins must implement this function */
|
||||
G_MODULE_EXPORT GType register_gedit_plugin (GTypeModule *module);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GEDIT_CHECK_UPDATE_PLUGIN_H__ */
|
13
plugins/checkupdate/gedit-check-update.schemas.in
Executable file
13
plugins/checkupdate/gedit-check-update.schemas.in
Executable file
@@ -0,0 +1,13 @@
|
||||
<mateconfschemafile>
|
||||
<schemalist>
|
||||
<schema>
|
||||
<key>/schemas/apps/gedit-2/plugins/checkupdate/ignore_version</key>
|
||||
<applyto>/apps/gedit-2/plugins/checkupdate/ignore_version</applyto>
|
||||
<owner>gedit</owner>
|
||||
<type>string</type>
|
||||
<locale name="C">
|
||||
<short>Version to ignore until the next version is released</short>
|
||||
</locale>
|
||||
</schema>
|
||||
</schemalist>
|
||||
</mateconfschemafile>
|
34
plugins/docinfo/Makefile.am
Executable file
34
plugins/docinfo/Makefile.am
Executable file
@@ -0,0 +1,34 @@
|
||||
# docinfo plugin
|
||||
plugindir = $(GEDIT_PLUGINS_LIBS_DIR)
|
||||
|
||||
INCLUDES = \
|
||||
-I$(top_srcdir) \
|
||||
$(GEDIT_CFLAGS) \
|
||||
$(WARN_CFLAGS) \
|
||||
$(DISABLE_DEPRECATED_CFLAGS)
|
||||
|
||||
plugin_LTLIBRARIES = libdocinfo.la
|
||||
|
||||
libdocinfo_la_SOURCES = \
|
||||
gedit-docinfo-plugin.h \
|
||||
gedit-docinfo-plugin.c
|
||||
|
||||
libdocinfo_la_LDFLAGS = $(PLUGIN_LIBTOOL_FLAGS)
|
||||
libdocinfo_la_LIBADD = $(GEDIT_LIBS)
|
||||
|
||||
uidir = $(GEDIT_PLUGINS_DATA_DIR)/docinfo
|
||||
ui_DATA = docinfo.ui
|
||||
|
||||
plugin_in_files = docinfo.gedit-plugin.desktop.in
|
||||
|
||||
%.gedit-plugin: %.gedit-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:.gedit-plugin.desktop.in=.gedit-plugin)
|
||||
|
||||
EXTRA_DIST = $(ui_DATA) $(plugin_in_files)
|
||||
|
||||
CLEANFILES = $(plugin_DATA)
|
||||
DISTCLEANFILES = $(plugin_DATA)
|
||||
|
||||
|
||||
-include $(top_srcdir)/git.mk
|
7
plugins/docinfo/docinfo.gedit-plugin.desktop.in
Executable file
7
plugins/docinfo/docinfo.gedit-plugin.desktop.in
Executable file
@@ -0,0 +1,7 @@
|
||||
[Gedit Plugin]
|
||||
Module=docinfo
|
||||
IAge=2
|
||||
_Name=Document Statistics
|
||||
_Description=Analyzes the current document and reports the number of words, lines, characters and non-space characters in it.
|
||||
Authors=Paolo Maggi <paolo.maggi@polito.it>;Jorge Alberto Torres <jorge@deadoak.com>
|
||||
Copyright=Copyright © 2002-2005 Paolo Maggi
|
621
plugins/docinfo/docinfo.ui
Executable file
621
plugins/docinfo/docinfo.ui
Executable file
@@ -0,0 +1,621 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--*- mode: xml -*-->
|
||||
<interface>
|
||||
<object class="GtkDialog" id="dialog">
|
||||
<property name="border_width">5</property>
|
||||
<property name="title" translatable="yes">Document Statistics</property>
|
||||
<property name="type">GTK_WINDOW_TOPLEVEL</property>
|
||||
<property name="window_position">GTK_WIN_POS_NONE</property>
|
||||
<property name="modal">False</property>
|
||||
<property name="resizable">False</property>
|
||||
<property name="destroy_with_parent">True</property>
|
||||
<property name="decorated">True</property>
|
||||
<property name="skip_taskbar_hint">False</property>
|
||||
<property name="skip_pager_hint">False</property>
|
||||
<property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
|
||||
<property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
|
||||
<property name="focus_on_map">True</property>
|
||||
<property name="urgency_hint">False</property>
|
||||
<property name="has_separator">False</property>
|
||||
<child internal-child="vbox">
|
||||
<object class="GtkVBox" id="dialog-vbox1">
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">8</property>
|
||||
<child internal-child="action_area">
|
||||
<object class="GtkHButtonBox" id="dialog-action_area1">
|
||||
<property name="visible">True</property>
|
||||
<property name="layout_style">GTK_BUTTONBOX_END</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="close_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label">gtk-close</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<property name="focus_on_click">True</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="update_button">
|
||||
<property name="label" translatable="yes">_Update</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="image">update_image</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="pack_type">GTK_PACK_END</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkVBox" id="docinfo_dialog_content">
|
||||
<property name="border_width">5</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="file_name_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">File Name</property>
|
||||
<property name="use_underline">False</property>
|
||||
<property name="use_markup">True</property>
|
||||
<property name="justify">GTK_JUSTIFY_LEFT</property>
|
||||
<property name="wrap">False</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xpad">0</property>
|
||||
<property name="ypad">0</property>
|
||||
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
|
||||
<property name="width_chars">-1</property>
|
||||
<property name="single_line_mode">False</property>
|
||||
<property name="angle">0</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="PANGO_WEIGHT_BOLD"/>
|
||||
</attributes>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkHBox" id="hbox1">
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">0</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label28">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes"> </property>
|
||||
<property name="use_underline">False</property>
|
||||
<property name="use_markup">False</property>
|
||||
<property name="justify">GTK_JUSTIFY_LEFT</property>
|
||||
<property name="wrap">False</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="xalign">0.5</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xpad">0</property>
|
||||
<property name="ypad">0</property>
|
||||
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
|
||||
<property name="width_chars">-1</property>
|
||||
<property name="single_line_mode">False</property>
|
||||
<property name="angle">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTable" id="table1">
|
||||
<property name="border_width">6</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="n_rows">6</property>
|
||||
<property name="n_columns">2</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="row_spacing">6</property>
|
||||
<property name="column_spacing">18</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label26">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Bytes</property>
|
||||
<property name="use_underline">False</property>
|
||||
<property name="use_markup">False</property>
|
||||
<property name="justify">GTK_JUSTIFY_LEFT</property>
|
||||
<property name="wrap">False</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xpad">0</property>
|
||||
<property name="ypad">0</property>
|
||||
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
|
||||
<property name="width_chars">-1</property>
|
||||
<property name="single_line_mode">False</property>
|
||||
<property name="angle">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="right_attach">1</property>
|
||||
<property name="top_attach">5</property>
|
||||
<property name="bottom_attach">6</property>
|
||||
<property name="x_options">fill</property>
|
||||
<property name="y_options"/>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="bytes_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="label">0</property>
|
||||
<property name="use_underline">False</property>
|
||||
<property name="use_markup">False</property>
|
||||
<property name="justify">GTK_JUSTIFY_LEFT</property>
|
||||
<property name="wrap">False</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="xalign">1</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xpad">0</property>
|
||||
<property name="ypad">0</property>
|
||||
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
|
||||
<property name="width_chars">-1</property>
|
||||
<property name="single_line_mode">False</property>
|
||||
<property name="angle">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">5</property>
|
||||
<property name="bottom_attach">6</property>
|
||||
<property name="x_options">fill</property>
|
||||
<property name="y_options"/>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label5">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Characters (no spaces)</property>
|
||||
<property name="use_underline">False</property>
|
||||
<property name="use_markup">False</property>
|
||||
<property name="justify">GTK_JUSTIFY_LEFT</property>
|
||||
<property name="wrap">False</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xpad">0</property>
|
||||
<property name="ypad">0</property>
|
||||
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
|
||||
<property name="width_chars">-1</property>
|
||||
<property name="single_line_mode">False</property>
|
||||
<property name="angle">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="right_attach">1</property>
|
||||
<property name="top_attach">4</property>
|
||||
<property name="bottom_attach">5</property>
|
||||
<property name="x_options">fill</property>
|
||||
<property name="y_options"/>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="chars_ns_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="label">0</property>
|
||||
<property name="use_underline">False</property>
|
||||
<property name="use_markup">False</property>
|
||||
<property name="justify">GTK_JUSTIFY_LEFT</property>
|
||||
<property name="wrap">False</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="xalign">1</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xpad">0</property>
|
||||
<property name="ypad">0</property>
|
||||
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
|
||||
<property name="width_chars">-1</property>
|
||||
<property name="single_line_mode">False</property>
|
||||
<property name="angle">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">4</property>
|
||||
<property name="bottom_attach">5</property>
|
||||
<property name="x_options">fill</property>
|
||||
<property name="y_options"/>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label4">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Characters (with spaces)</property>
|
||||
<property name="use_underline">False</property>
|
||||
<property name="use_markup">False</property>
|
||||
<property name="justify">GTK_JUSTIFY_LEFT</property>
|
||||
<property name="wrap">False</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xpad">0</property>
|
||||
<property name="ypad">0</property>
|
||||
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
|
||||
<property name="width_chars">-1</property>
|
||||
<property name="single_line_mode">False</property>
|
||||
<property name="angle">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="right_attach">1</property>
|
||||
<property name="top_attach">3</property>
|
||||
<property name="bottom_attach">4</property>
|
||||
<property name="x_options">fill</property>
|
||||
<property name="y_options"/>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="chars_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="label">0</property>
|
||||
<property name="use_underline">False</property>
|
||||
<property name="use_markup">False</property>
|
||||
<property name="justify">GTK_JUSTIFY_LEFT</property>
|
||||
<property name="wrap">False</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="xalign">1</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xpad">0</property>
|
||||
<property name="ypad">0</property>
|
||||
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
|
||||
<property name="width_chars">-1</property>
|
||||
<property name="single_line_mode">False</property>
|
||||
<property name="angle">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">3</property>
|
||||
<property name="bottom_attach">4</property>
|
||||
<property name="x_options">fill</property>
|
||||
<property name="y_options"/>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="words_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="label">0</property>
|
||||
<property name="use_underline">False</property>
|
||||
<property name="use_markup">False</property>
|
||||
<property name="justify">GTK_JUSTIFY_LEFT</property>
|
||||
<property name="wrap">False</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="xalign">1</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xpad">0</property>
|
||||
<property name="ypad">0</property>
|
||||
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
|
||||
<property name="width_chars">-1</property>
|
||||
<property name="single_line_mode">False</property>
|
||||
<property name="angle">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">2</property>
|
||||
<property name="bottom_attach">3</property>
|
||||
<property name="x_options">fill</property>
|
||||
<property name="y_options"/>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label2">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Words</property>
|
||||
<property name="use_underline">False</property>
|
||||
<property name="use_markup">False</property>
|
||||
<property name="justify">GTK_JUSTIFY_LEFT</property>
|
||||
<property name="wrap">False</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xpad">0</property>
|
||||
<property name="ypad">0</property>
|
||||
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
|
||||
<property name="width_chars">-1</property>
|
||||
<property name="single_line_mode">False</property>
|
||||
<property name="angle">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="right_attach">1</property>
|
||||
<property name="top_attach">2</property>
|
||||
<property name="bottom_attach">3</property>
|
||||
<property name="x_options">fill</property>
|
||||
<property name="y_options"/>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label6">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Lines</property>
|
||||
<property name="use_underline">False</property>
|
||||
<property name="use_markup">False</property>
|
||||
<property name="justify">GTK_JUSTIFY_LEFT</property>
|
||||
<property name="wrap">False</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xpad">0</property>
|
||||
<property name="ypad">0</property>
|
||||
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
|
||||
<property name="width_chars">-1</property>
|
||||
<property name="single_line_mode">False</property>
|
||||
<property name="angle">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="right_attach">1</property>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="bottom_attach">2</property>
|
||||
<property name="x_options">fill</property>
|
||||
<property name="y_options"/>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="lines_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="label">0</property>
|
||||
<property name="use_underline">False</property>
|
||||
<property name="use_markup">False</property>
|
||||
<property name="justify">GTK_JUSTIFY_LEFT</property>
|
||||
<property name="wrap">False</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="xalign">1</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xpad">0</property>
|
||||
<property name="ypad">0</property>
|
||||
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
|
||||
<property name="width_chars">-1</property>
|
||||
<property name="single_line_mode">False</property>
|
||||
<property name="angle">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="bottom_attach">2</property>
|
||||
<property name="x_options">fill</property>
|
||||
<property name="y_options"/>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label30">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Document</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="use_markup">True</property>
|
||||
<property name="justify">GTK_JUSTIFY_CENTER</property>
|
||||
<property name="wrap">False</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xpad">0</property>
|
||||
<property name="ypad">0</property>
|
||||
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
|
||||
<property name="width_chars">-1</property>
|
||||
<property name="single_line_mode">False</property>
|
||||
<property name="angle">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">0</property>
|
||||
<property name="bottom_attach">1</property>
|
||||
<property name="x_options">fill</property>
|
||||
<property name="y_options"/>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkVBox" id="selection_vbox">
|
||||
<property name="border_width">6</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="selection_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Selection</property>
|
||||
<property name="use_underline">False</property>
|
||||
<property name="use_markup">False</property>
|
||||
<property name="justify">GTK_JUSTIFY_LEFT</property>
|
||||
<property name="wrap">False</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xpad">0</property>
|
||||
<property name="ypad">0</property>
|
||||
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
|
||||
<property name="width_chars">-1</property>
|
||||
<property name="single_line_mode">False</property>
|
||||
<property name="angle">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="selected_lines_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="label">0</property>
|
||||
<property name="use_underline">False</property>
|
||||
<property name="use_markup">False</property>
|
||||
<property name="justify">GTK_JUSTIFY_LEFT</property>
|
||||
<property name="wrap">False</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="xalign">1</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xpad">0</property>
|
||||
<property name="ypad">0</property>
|
||||
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
|
||||
<property name="width_chars">-1</property>
|
||||
<property name="single_line_mode">False</property>
|
||||
<property name="angle">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="selected_words_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="label">0</property>
|
||||
<property name="use_underline">False</property>
|
||||
<property name="use_markup">False</property>
|
||||
<property name="justify">GTK_JUSTIFY_LEFT</property>
|
||||
<property name="wrap">False</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="xalign">1</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xpad">0</property>
|
||||
<property name="ypad">0</property>
|
||||
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
|
||||
<property name="width_chars">-1</property>
|
||||
<property name="single_line_mode">False</property>
|
||||
<property name="angle">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="selected_chars_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="label">0</property>
|
||||
<property name="use_underline">False</property>
|
||||
<property name="use_markup">False</property>
|
||||
<property name="justify">GTK_JUSTIFY_LEFT</property>
|
||||
<property name="wrap">False</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="xalign">1</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xpad">0</property>
|
||||
<property name="ypad">0</property>
|
||||
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
|
||||
<property name="width_chars">-1</property>
|
||||
<property name="single_line_mode">False</property>
|
||||
<property name="angle">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="selected_chars_ns_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="label">0</property>
|
||||
<property name="use_underline">False</property>
|
||||
<property name="use_markup">False</property>
|
||||
<property name="justify">GTK_JUSTIFY_LEFT</property>
|
||||
<property name="wrap">False</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="xalign">1</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xpad">0</property>
|
||||
<property name="ypad">0</property>
|
||||
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
|
||||
<property name="width_chars">-1</property>
|
||||
<property name="single_line_mode">False</property>
|
||||
<property name="angle">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="selected_bytes_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="label">0</property>
|
||||
<property name="use_underline">False</property>
|
||||
<property name="use_markup">False</property>
|
||||
<property name="justify">GTK_JUSTIFY_LEFT</property>
|
||||
<property name="wrap">False</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="xalign">1</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xpad">0</property>
|
||||
<property name="ypad">0</property>
|
||||
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
|
||||
<property name="width_chars">-1</property>
|
||||
<property name="single_line_mode">False</property>
|
||||
<property name="angle">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<action-widgets>
|
||||
<action-widget response="-7">close_button</action-widget>
|
||||
<action-widget response="-5">update_button</action-widget>
|
||||
</action-widgets>
|
||||
</object>
|
||||
<object class="GtkImage" id="update_image">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-refresh</property>
|
||||
</object>
|
||||
</interface>
|
580
plugins/docinfo/gedit-docinfo-plugin.c
Executable file
580
plugins/docinfo/gedit-docinfo-plugin.c
Executable file
@@ -0,0 +1,580 @@
|
||||
/*
|
||||
* gedit-docinfo-plugin.c
|
||||
*
|
||||
* Copyright (C) 2002-2005 Paolo Maggi
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include "gedit-docinfo-plugin.h"
|
||||
|
||||
#include <string.h> /* For strlen (...) */
|
||||
|
||||
#include <glib/gi18n-lib.h>
|
||||
#include <pango/pango-break.h>
|
||||
#include <gmodule.h>
|
||||
|
||||
#include <gedit/gedit-debug.h>
|
||||
#include <gedit/gedit-utils.h>
|
||||
|
||||
#define WINDOW_DATA_KEY "GeditDocInfoWindowData"
|
||||
#define MENU_PATH "/MenuBar/ToolsMenu/ToolsOps_2"
|
||||
|
||||
GEDIT_PLUGIN_REGISTER_TYPE(GeditDocInfoPlugin, gedit_docinfo_plugin)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GtkWidget *dialog;
|
||||
GtkWidget *file_name_label;
|
||||
GtkWidget *lines_label;
|
||||
GtkWidget *words_label;
|
||||
GtkWidget *chars_label;
|
||||
GtkWidget *chars_ns_label;
|
||||
GtkWidget *bytes_label;
|
||||
GtkWidget *selection_vbox;
|
||||
GtkWidget *selected_lines_label;
|
||||
GtkWidget *selected_words_label;
|
||||
GtkWidget *selected_chars_label;
|
||||
GtkWidget *selected_chars_ns_label;
|
||||
GtkWidget *selected_bytes_label;
|
||||
} DocInfoDialog;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GeditPlugin *plugin;
|
||||
|
||||
GtkActionGroup *ui_action_group;
|
||||
guint ui_id;
|
||||
|
||||
DocInfoDialog *dialog;
|
||||
} WindowData;
|
||||
|
||||
static void docinfo_dialog_response_cb (GtkDialog *widget,
|
||||
gint res_id,
|
||||
GeditWindow *window);
|
||||
|
||||
static void
|
||||
docinfo_dialog_destroy_cb (GtkObject *obj,
|
||||
WindowData *data)
|
||||
{
|
||||
gedit_debug (DEBUG_PLUGINS);
|
||||
|
||||
if (data != NULL)
|
||||
{
|
||||
g_free (data->dialog);
|
||||
data->dialog = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static DocInfoDialog *
|
||||
get_docinfo_dialog (GeditWindow *window,
|
||||
WindowData *data)
|
||||
{
|
||||
DocInfoDialog *dialog;
|
||||
gchar *data_dir;
|
||||
gchar *ui_file;
|
||||
GtkWidget *content;
|
||||
GtkWidget *error_widget;
|
||||
gboolean ret;
|
||||
|
||||
gedit_debug (DEBUG_PLUGINS);
|
||||
|
||||
dialog = g_new (DocInfoDialog, 1);
|
||||
|
||||
data_dir = gedit_plugin_get_data_dir (data->plugin);
|
||||
ui_file = g_build_filename (data_dir, "docinfo.ui", NULL);
|
||||
ret = gedit_utils_get_ui_objects (ui_file,
|
||||
NULL,
|
||||
&error_widget,
|
||||
"dialog", &dialog->dialog,
|
||||
"docinfo_dialog_content", &content,
|
||||
"file_name_label", &dialog->file_name_label,
|
||||
"words_label", &dialog->words_label,
|
||||
"bytes_label", &dialog->bytes_label,
|
||||
"lines_label", &dialog->lines_label,
|
||||
"chars_label", &dialog->chars_label,
|
||||
"chars_ns_label", &dialog->chars_ns_label,
|
||||
"selection_vbox", &dialog->selection_vbox,
|
||||
"selected_words_label", &dialog->selected_words_label,
|
||||
"selected_bytes_label", &dialog->selected_bytes_label,
|
||||
"selected_lines_label", &dialog->selected_lines_label,
|
||||
"selected_chars_label", &dialog->selected_chars_label,
|
||||
"selected_chars_ns_label", &dialog->selected_chars_ns_label,
|
||||
NULL);
|
||||
|
||||
g_free (data_dir);
|
||||
g_free (ui_file);
|
||||
|
||||
if (!ret)
|
||||
{
|
||||
const gchar *err_message;
|
||||
|
||||
err_message = gtk_label_get_label (GTK_LABEL (error_widget));
|
||||
gedit_warning (GTK_WINDOW (window), "%s", err_message);
|
||||
|
||||
g_free (dialog);
|
||||
gtk_widget_destroy (error_widget);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gtk_dialog_set_default_response (GTK_DIALOG (dialog->dialog),
|
||||
GTK_RESPONSE_OK);
|
||||
gtk_window_set_transient_for (GTK_WINDOW (dialog->dialog),
|
||||
GTK_WINDOW (window));
|
||||
|
||||
g_signal_connect (dialog->dialog,
|
||||
"destroy",
|
||||
G_CALLBACK (docinfo_dialog_destroy_cb),
|
||||
data);
|
||||
g_signal_connect (dialog->dialog,
|
||||
"response",
|
||||
G_CALLBACK (docinfo_dialog_response_cb),
|
||||
window);
|
||||
|
||||
return dialog;
|
||||
}
|
||||
|
||||
static void
|
||||
calculate_info (GeditDocument *doc,
|
||||
GtkTextIter *start,
|
||||
GtkTextIter *end,
|
||||
gint *chars,
|
||||
gint *words,
|
||||
gint *white_chars,
|
||||
gint *bytes)
|
||||
{
|
||||
gchar *text;
|
||||
|
||||
gedit_debug (DEBUG_PLUGINS);
|
||||
|
||||
text = gtk_text_buffer_get_slice (GTK_TEXT_BUFFER (doc),
|
||||
start,
|
||||
end,
|
||||
TRUE);
|
||||
|
||||
*chars = g_utf8_strlen (text, -1);
|
||||
*bytes = strlen (text);
|
||||
|
||||
if (*chars > 0)
|
||||
{
|
||||
PangoLogAttr *attrs;
|
||||
gint i;
|
||||
|
||||
attrs = g_new0 (PangoLogAttr, *chars + 1);
|
||||
|
||||
pango_get_log_attrs (text,
|
||||
-1,
|
||||
0,
|
||||
pango_language_from_string ("C"),
|
||||
attrs,
|
||||
*chars + 1);
|
||||
|
||||
for (i = 0; i < (*chars); i++)
|
||||
{
|
||||
if (attrs[i].is_white)
|
||||
++(*white_chars);
|
||||
|
||||
if (attrs[i].is_word_start)
|
||||
++(*words);
|
||||
}
|
||||
|
||||
g_free (attrs);
|
||||
}
|
||||
else
|
||||
{
|
||||
*white_chars = 0;
|
||||
*words = 0;
|
||||
}
|
||||
|
||||
g_free (text);
|
||||
}
|
||||
|
||||
static void
|
||||
docinfo_real (GeditDocument *doc,
|
||||
DocInfoDialog *dialog)
|
||||
{
|
||||
GtkTextIter start, end;
|
||||
gint words = 0;
|
||||
gint chars = 0;
|
||||
gint white_chars = 0;
|
||||
gint lines = 0;
|
||||
gint bytes = 0;
|
||||
gchar *tmp_str;
|
||||
gchar *doc_name;
|
||||
|
||||
gedit_debug (DEBUG_PLUGINS);
|
||||
|
||||
gtk_text_buffer_get_bounds (GTK_TEXT_BUFFER (doc),
|
||||
&start,
|
||||
&end);
|
||||
|
||||
lines = gtk_text_buffer_get_line_count (GTK_TEXT_BUFFER (doc));
|
||||
|
||||
calculate_info (doc,
|
||||
&start, &end,
|
||||
&chars, &words, &white_chars, &bytes);
|
||||
|
||||
if (chars == 0)
|
||||
lines = 0;
|
||||
|
||||
gedit_debug_message (DEBUG_PLUGINS, "Chars: %d", chars);
|
||||
gedit_debug_message (DEBUG_PLUGINS, "Lines: %d", lines);
|
||||
gedit_debug_message (DEBUG_PLUGINS, "Words: %d", words);
|
||||
gedit_debug_message (DEBUG_PLUGINS, "Chars non-space: %d", chars - white_chars);
|
||||
gedit_debug_message (DEBUG_PLUGINS, "Bytes: %d", bytes);
|
||||
|
||||
doc_name = gedit_document_get_short_name_for_display (doc);
|
||||
tmp_str = g_strdup_printf ("<span weight=\"bold\">%s</span>", doc_name);
|
||||
gtk_label_set_markup (GTK_LABEL (dialog->file_name_label), tmp_str);
|
||||
g_free (doc_name);
|
||||
g_free (tmp_str);
|
||||
|
||||
tmp_str = g_strdup_printf("%d", lines);
|
||||
gtk_label_set_text (GTK_LABEL (dialog->lines_label), tmp_str);
|
||||
g_free (tmp_str);
|
||||
|
||||
tmp_str = g_strdup_printf("%d", words);
|
||||
gtk_label_set_text (GTK_LABEL (dialog->words_label), tmp_str);
|
||||
g_free (tmp_str);
|
||||
|
||||
tmp_str = g_strdup_printf("%d", chars);
|
||||
gtk_label_set_text (GTK_LABEL (dialog->chars_label), tmp_str);
|
||||
g_free (tmp_str);
|
||||
|
||||
tmp_str = g_strdup_printf("%d", chars - white_chars);
|
||||
gtk_label_set_text (GTK_LABEL (dialog->chars_ns_label), tmp_str);
|
||||
g_free (tmp_str);
|
||||
|
||||
tmp_str = g_strdup_printf("%d", bytes);
|
||||
gtk_label_set_text (GTK_LABEL (dialog->bytes_label), tmp_str);
|
||||
g_free (tmp_str);
|
||||
}
|
||||
|
||||
static void
|
||||
selectioninfo_real (GeditDocument *doc,
|
||||
DocInfoDialog *dialog)
|
||||
{
|
||||
gboolean sel;
|
||||
GtkTextIter start, end;
|
||||
gint words = 0;
|
||||
gint chars = 0;
|
||||
gint white_chars = 0;
|
||||
gint lines = 0;
|
||||
gint bytes = 0;
|
||||
gchar *tmp_str;
|
||||
|
||||
gedit_debug (DEBUG_PLUGINS);
|
||||
|
||||
sel = gtk_text_buffer_get_selection_bounds (GTK_TEXT_BUFFER (doc),
|
||||
&start,
|
||||
&end);
|
||||
|
||||
if (sel)
|
||||
{
|
||||
lines = gtk_text_iter_get_line (&end) - gtk_text_iter_get_line (&start) + 1;
|
||||
|
||||
calculate_info (doc,
|
||||
&start, &end,
|
||||
&chars, &words, &white_chars, &bytes);
|
||||
|
||||
gedit_debug_message (DEBUG_PLUGINS, "Selected chars: %d", chars);
|
||||
gedit_debug_message (DEBUG_PLUGINS, "Selected lines: %d", lines);
|
||||
gedit_debug_message (DEBUG_PLUGINS, "Selected words: %d", words);
|
||||
gedit_debug_message (DEBUG_PLUGINS, "Selected chars non-space: %d", chars - white_chars);
|
||||
gedit_debug_message (DEBUG_PLUGINS, "Selected bytes: %d", bytes);
|
||||
|
||||
gtk_widget_set_sensitive (dialog->selection_vbox, TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_widget_set_sensitive (dialog->selection_vbox, FALSE);
|
||||
|
||||
gedit_debug_message (DEBUG_PLUGINS, "Selection empty");
|
||||
}
|
||||
|
||||
if (chars == 0)
|
||||
lines = 0;
|
||||
|
||||
tmp_str = g_strdup_printf("%d", lines);
|
||||
gtk_label_set_text (GTK_LABEL (dialog->selected_lines_label), tmp_str);
|
||||
g_free (tmp_str);
|
||||
|
||||
tmp_str = g_strdup_printf("%d", words);
|
||||
gtk_label_set_text (GTK_LABEL (dialog->selected_words_label), tmp_str);
|
||||
g_free (tmp_str);
|
||||
|
||||
tmp_str = g_strdup_printf("%d", chars);
|
||||
gtk_label_set_text (GTK_LABEL (dialog->selected_chars_label), tmp_str);
|
||||
g_free (tmp_str);
|
||||
|
||||
tmp_str = g_strdup_printf("%d", chars - white_chars);
|
||||
gtk_label_set_text (GTK_LABEL (dialog->selected_chars_ns_label), tmp_str);
|
||||
g_free (tmp_str);
|
||||
|
||||
tmp_str = g_strdup_printf("%d", bytes);
|
||||
gtk_label_set_text (GTK_LABEL (dialog->selected_bytes_label), tmp_str);
|
||||
g_free (tmp_str);
|
||||
}
|
||||
|
||||
static void
|
||||
docinfo_cb (GtkAction *action,
|
||||
GeditWindow *window)
|
||||
{
|
||||
GeditDocument *doc;
|
||||
WindowData *data;
|
||||
|
||||
gedit_debug (DEBUG_PLUGINS);
|
||||
|
||||
data = (WindowData *) g_object_get_data (G_OBJECT (window),
|
||||
WINDOW_DATA_KEY);
|
||||
|
||||
doc = gedit_window_get_active_document (window);
|
||||
g_return_if_fail (doc != NULL);
|
||||
|
||||
if (data->dialog != NULL)
|
||||
{
|
||||
gtk_window_present (GTK_WINDOW (data->dialog->dialog));
|
||||
gtk_widget_grab_focus (GTK_WIDGET (data->dialog->dialog));
|
||||
}
|
||||
else
|
||||
{
|
||||
DocInfoDialog *dialog;
|
||||
|
||||
dialog = get_docinfo_dialog (window, data);
|
||||
g_return_if_fail (dialog != NULL);
|
||||
|
||||
data->dialog = dialog;
|
||||
|
||||
gtk_widget_show (GTK_WIDGET (dialog->dialog));
|
||||
}
|
||||
|
||||
docinfo_real (doc,
|
||||
data->dialog);
|
||||
selectioninfo_real (doc,
|
||||
data->dialog);
|
||||
}
|
||||
|
||||
static void
|
||||
docinfo_dialog_response_cb (GtkDialog *widget,
|
||||
gint res_id,
|
||||
GeditWindow *window)
|
||||
{
|
||||
WindowData *data;
|
||||
|
||||
gedit_debug (DEBUG_PLUGINS);
|
||||
|
||||
data = (WindowData *) g_object_get_data (G_OBJECT (window),
|
||||
WINDOW_DATA_KEY);
|
||||
|
||||
switch (res_id)
|
||||
{
|
||||
case GTK_RESPONSE_CLOSE:
|
||||
{
|
||||
gedit_debug_message (DEBUG_PLUGINS, "GTK_RESPONSE_CLOSE");
|
||||
gtk_widget_destroy (data->dialog->dialog);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case GTK_RESPONSE_OK:
|
||||
{
|
||||
GeditDocument *doc;
|
||||
|
||||
gedit_debug_message (DEBUG_PLUGINS, "GTK_RESPONSE_OK");
|
||||
|
||||
doc = gedit_window_get_active_document (window);
|
||||
g_return_if_fail (doc != NULL);
|
||||
|
||||
docinfo_real (doc,
|
||||
data->dialog);
|
||||
|
||||
selectioninfo_real (doc,
|
||||
data->dialog);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const GtkActionEntry action_entries[] =
|
||||
{
|
||||
{ "DocumentStatistics",
|
||||
NULL,
|
||||
N_("_Document Statistics"),
|
||||
NULL,
|
||||
N_("Get statistical information on the current document"),
|
||||
G_CALLBACK (docinfo_cb) }
|
||||
};
|
||||
|
||||
static void
|
||||
free_window_data (WindowData *data)
|
||||
{
|
||||
g_return_if_fail (data != NULL);
|
||||
|
||||
gedit_debug (DEBUG_PLUGINS);
|
||||
|
||||
g_object_unref (data->plugin);
|
||||
|
||||
g_object_unref (data->ui_action_group);
|
||||
|
||||
if (data->dialog != NULL)
|
||||
{
|
||||
gtk_widget_destroy (data->dialog->dialog);
|
||||
}
|
||||
|
||||
g_free (data);
|
||||
}
|
||||
|
||||
static void
|
||||
update_ui_real (GeditWindow *window,
|
||||
WindowData *data)
|
||||
{
|
||||
GeditView *view;
|
||||
|
||||
gedit_debug (DEBUG_PLUGINS);
|
||||
|
||||
view = gedit_window_get_active_view (window);
|
||||
|
||||
gtk_action_group_set_sensitive (data->ui_action_group,
|
||||
(view != NULL));
|
||||
|
||||
if (data->dialog != NULL)
|
||||
{
|
||||
gtk_dialog_set_response_sensitive (GTK_DIALOG (data->dialog->dialog),
|
||||
GTK_RESPONSE_OK,
|
||||
(view != NULL));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gedit_docinfo_plugin_init (GeditDocInfoPlugin *plugin)
|
||||
{
|
||||
gedit_debug_message (DEBUG_PLUGINS, "GeditDocInfoPlugin initializing");
|
||||
}
|
||||
|
||||
static void
|
||||
gedit_docinfo_plugin_finalize (GObject *object)
|
||||
{
|
||||
gedit_debug_message (DEBUG_PLUGINS, "GeditDocInfoPlugin finalizing");
|
||||
|
||||
G_OBJECT_CLASS (gedit_docinfo_plugin_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
impl_activate (GeditPlugin *plugin,
|
||||
GeditWindow *window)
|
||||
{
|
||||
GtkUIManager *manager;
|
||||
WindowData *data;
|
||||
|
||||
gedit_debug (DEBUG_PLUGINS);
|
||||
|
||||
data = g_new (WindowData, 1);
|
||||
|
||||
data->plugin = g_object_ref (plugin);
|
||||
data->dialog = NULL;
|
||||
data->ui_action_group = gtk_action_group_new ("GeditDocInfoPluginActions");
|
||||
|
||||
gtk_action_group_set_translation_domain (data->ui_action_group,
|
||||
GETTEXT_PACKAGE);
|
||||
gtk_action_group_add_actions (data->ui_action_group,
|
||||
action_entries,
|
||||
G_N_ELEMENTS (action_entries),
|
||||
window);
|
||||
|
||||
manager = gedit_window_get_ui_manager (window);
|
||||
gtk_ui_manager_insert_action_group (manager,
|
||||
data->ui_action_group,
|
||||
-1);
|
||||
|
||||
data->ui_id = gtk_ui_manager_new_merge_id (manager);
|
||||
|
||||
g_object_set_data_full (G_OBJECT (window),
|
||||
WINDOW_DATA_KEY,
|
||||
data,
|
||||
(GDestroyNotify) free_window_data);
|
||||
|
||||
gtk_ui_manager_add_ui (manager,
|
||||
data->ui_id,
|
||||
MENU_PATH,
|
||||
"DocumentStatistics",
|
||||
"DocumentStatistics",
|
||||
GTK_UI_MANAGER_MENUITEM,
|
||||
FALSE);
|
||||
|
||||
update_ui_real (window,
|
||||
data);
|
||||
}
|
||||
|
||||
static void
|
||||
impl_deactivate (GeditPlugin *plugin,
|
||||
GeditWindow *window)
|
||||
{
|
||||
GtkUIManager *manager;
|
||||
WindowData *data;
|
||||
|
||||
gedit_debug (DEBUG_PLUGINS);
|
||||
|
||||
manager = gedit_window_get_ui_manager (window);
|
||||
|
||||
data = (WindowData *) g_object_get_data (G_OBJECT (window),
|
||||
WINDOW_DATA_KEY);
|
||||
g_return_if_fail (data != NULL);
|
||||
|
||||
gtk_ui_manager_remove_ui (manager,
|
||||
data->ui_id);
|
||||
gtk_ui_manager_remove_action_group (manager,
|
||||
data->ui_action_group);
|
||||
|
||||
g_object_set_data (G_OBJECT (window),
|
||||
WINDOW_DATA_KEY,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
impl_update_ui (GeditPlugin *plugin,
|
||||
GeditWindow *window)
|
||||
{
|
||||
WindowData *data;
|
||||
|
||||
gedit_debug (DEBUG_PLUGINS);
|
||||
|
||||
data = (WindowData *) g_object_get_data (G_OBJECT (window),
|
||||
WINDOW_DATA_KEY);
|
||||
g_return_if_fail (data != NULL);
|
||||
|
||||
update_ui_real (window,
|
||||
data);
|
||||
}
|
||||
|
||||
static void
|
||||
gedit_docinfo_plugin_class_init (GeditDocInfoPluginClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GeditPluginClass *plugin_class = GEDIT_PLUGIN_CLASS (klass);
|
||||
|
||||
object_class->finalize = gedit_docinfo_plugin_finalize;
|
||||
|
||||
plugin_class->activate = impl_activate;
|
||||
plugin_class->deactivate = impl_deactivate;
|
||||
plugin_class->update_ui = impl_update_ui;
|
||||
}
|
75
plugins/docinfo/gedit-docinfo-plugin.h
Executable file
75
plugins/docinfo/gedit-docinfo-plugin.h
Executable file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* gedit-docinfo-plugin.h
|
||||
*
|
||||
* Copyright (C) 2002-2005 Paolo Maggi
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef __GEDIT_DOCINFO_PLUGIN_H__
|
||||
#define __GEDIT_DOCINFO_PLUGIN_H__
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
#include <gedit/gedit-plugin.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/*
|
||||
* Type checking and casting macros
|
||||
*/
|
||||
#define GEDIT_TYPE_DOCINFO_PLUGIN (gedit_docinfo_plugin_get_type ())
|
||||
#define GEDIT_DOCINFO_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GEDIT_TYPE_DOCINFO_PLUGIN, GeditDocInfoPlugin))
|
||||
#define GEDIT_DOCINFO_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GEDIT_TYPE_DOCINFO_PLUGIN, GeditDocInfoPluginClass))
|
||||
#define GEDIT_IS_DOCINFO_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GEDIT_TYPE_DOCINFO_PLUGIN))
|
||||
#define GEDIT_IS_DOCINFO_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GEDIT_TYPE_DOCINFO_PLUGIN))
|
||||
#define GEDIT_DOCINFO_PLUGIN_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GEDIT_TYPE_DOCINFO_PLUGIN, GeditDocInfoPluginClass))
|
||||
|
||||
/* Private structure type */
|
||||
typedef struct _GeditDocInfoPluginPrivate GeditDocInfoPluginPrivate;
|
||||
|
||||
/*
|
||||
* Main object structure
|
||||
*/
|
||||
typedef struct _GeditDocInfoPlugin GeditDocInfoPlugin;
|
||||
|
||||
struct _GeditDocInfoPlugin
|
||||
{
|
||||
GeditPlugin parent_instance;
|
||||
};
|
||||
|
||||
/*
|
||||
* Class definition
|
||||
*/
|
||||
typedef struct _GeditDocInfoPluginClass GeditDocInfoPluginClass;
|
||||
|
||||
struct _GeditDocInfoPluginClass
|
||||
{
|
||||
GeditPluginClass parent_class;
|
||||
};
|
||||
|
||||
/*
|
||||
* Public methods
|
||||
*/
|
||||
GType gedit_docinfo_plugin_get_type (void) G_GNUC_CONST;
|
||||
|
||||
/* All the plugins must implement this function */
|
||||
G_MODULE_EXPORT GType register_gedit_plugin (GTypeModule *module);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GEDIT_DOCINFO_PLUGIN_H__ */
|
15
plugins/externaltools/Makefile.am
Executable file
15
plugins/externaltools/Makefile.am
Executable file
@@ -0,0 +1,15 @@
|
||||
# External Tools plugin
|
||||
SUBDIRS = tools data scripts
|
||||
plugindir = $(GEDIT_PLUGINS_LIBS_DIR)
|
||||
|
||||
plugin_in_files = externaltools.gedit-plugin.desktop.in
|
||||
%.gedit-plugin: %.gedit-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:.gedit-plugin.desktop.in=.gedit-plugin)
|
||||
|
||||
EXTRA_DIST = $(plugin_in_files)
|
||||
|
||||
CLEANFILES = $(plugin_DATA)
|
||||
DISTCLEANFILES = $(plugin_DATA)
|
||||
|
||||
-include $(top_srcdir)/git.mk
|
65
plugins/externaltools/data/Makefile.am
Executable file
65
plugins/externaltools/data/Makefile.am
Executable file
@@ -0,0 +1,65 @@
|
||||
TOOL_MERGE=$(top_srcdir)/plugins/externaltools/scripts/gedit-tool-merge.pl
|
||||
|
||||
tools_in_files = \
|
||||
build.tool.in \
|
||||
remove-trailing-spaces.tool.in
|
||||
|
||||
tools_in_linux = \
|
||||
open-terminal-here.tool.in \
|
||||
run-command.tool.in
|
||||
|
||||
tools_in_osx = \
|
||||
open-terminal-here-osx.tool.in
|
||||
|
||||
tools_in_win32 =
|
||||
|
||||
install_tools_in_files = $(tools_in_files)
|
||||
|
||||
if PLATFORM_OSX
|
||||
install_tools_in_files += $(tools_in_osx)
|
||||
else
|
||||
if PLATFORM_WIN32
|
||||
install_tools_in_files += $(tools_in_win32)
|
||||
else
|
||||
install_tools_in_files += $(tools_in_linux)
|
||||
endif
|
||||
endif
|
||||
|
||||
desktop_in_files = $(install_tools_in_files:.tool.in=.desktop.in)
|
||||
desktop_files = $(install_tools_in_files:.tool.in=.desktop)
|
||||
|
||||
tools_SCRIPTS = $(install_tools_in_files:.tool.in=)
|
||||
toolsdir = $(GEDIT_PLUGINS_DATA_DIR)/externaltools/tools
|
||||
|
||||
all_tools_in_files = \
|
||||
$(tools_in_files) \
|
||||
$(tools_in_linux) \
|
||||
$(tools_in_osx) \
|
||||
$(tools_in_win32)
|
||||
|
||||
all_desktop_in_files = $(all_tools_in_files:.tool.in=.desktop.in)
|
||||
all_desktop_files = $(all_tools_in_files:.tool.in=.desktop)
|
||||
all_tools_files = $(all_tools_in_files:.tool.in=)
|
||||
|
||||
@INTLTOOL_DESKTOP_RULE@
|
||||
|
||||
# Tools are generated by merging a script file (.tool.in) with a data file
|
||||
# (.desktop), which happens to be translated using intltool.
|
||||
$(tools_SCRIPTS): %: %.tool.in %.desktop $(TOOL_MERGE)
|
||||
perl $(TOOL_MERGE) -o $@ $< $(word 2,$^)
|
||||
chmod 755 $@
|
||||
|
||||
EXTRA_DIST = \
|
||||
$(all_desktop_in_files) \
|
||||
$(all_tools_in_files)
|
||||
|
||||
CLEANFILES = \
|
||||
$(all_desktop_files) \
|
||||
$(all_tools_files)
|
||||
|
||||
DISTCLEANFILES = \
|
||||
$(all_desktop_files) \
|
||||
$(all_tools_files)
|
||||
|
||||
|
||||
-include $(top_srcdir)/git.mk
|
9
plugins/externaltools/data/build.desktop.in
Executable file
9
plugins/externaltools/data/build.desktop.in
Executable file
@@ -0,0 +1,9 @@
|
||||
[Gedit Tool]
|
||||
_Name=Build
|
||||
_Comment=Run "make" in the document directory
|
||||
Input=nothing
|
||||
Output=output-panel
|
||||
Shortcut=<Control>F8
|
||||
Applicability=local
|
||||
Save-files=nothing
|
||||
Languages=
|
15
plugins/externaltools/data/build.tool.in
Executable file
15
plugins/externaltools/data/build.tool.in
Executable file
@@ -0,0 +1,15 @@
|
||||
#!/bin/sh
|
||||
|
||||
EHOME=`echo $HOME | sed "s/#/\#/"`
|
||||
DIR=$GEDIT_CURRENT_DOCUMENT_DIR
|
||||
while test "$DIR" != "/"; do
|
||||
for m in GNUmakefile makefile Makefile; do
|
||||
if [ -f "${DIR}/${m}" ]; then
|
||||
echo "Using ${m} from ${DIR}" | sed "s#$EHOME#~#" > /dev/stderr
|
||||
make -C "${DIR}"
|
||||
exit
|
||||
fi
|
||||
done
|
||||
DIR=`dirname "${DIR}"`
|
||||
done
|
||||
echo "No Makefile found!" > /dev/stderr
|
8
plugins/externaltools/data/open-terminal-here-osx.desktop.in
Executable file
8
plugins/externaltools/data/open-terminal-here-osx.desktop.in
Executable file
@@ -0,0 +1,8 @@
|
||||
[Gedit Tool]
|
||||
_Name=Open terminal here
|
||||
_Comment=Open a terminal in the document location
|
||||
Input=nothing
|
||||
Output=output-panel
|
||||
Applicability=local
|
||||
Save-files=nothing
|
||||
Languages=
|
16
plugins/externaltools/data/open-terminal-here-osx.tool.in
Executable file
16
plugins/externaltools/data/open-terminal-here-osx.tool.in
Executable file
@@ -0,0 +1,16 @@
|
||||
#!/usr/bin/osascript
|
||||
|
||||
set the_path to system attribute "GEDIT_CURRENT_DOCUMENT_DIR"
|
||||
set cmd to "cd " & quoted form of the_path
|
||||
|
||||
tell application "System Events" to set terminalIsRunning to exists application process "Terminal"
|
||||
|
||||
tell application "Terminal"
|
||||
activate
|
||||
|
||||
if terminalIsRunning is true then
|
||||
do script with command cmd
|
||||
else
|
||||
do script with command cmd in window 1
|
||||
end if
|
||||
end tell
|
8
plugins/externaltools/data/open-terminal-here.desktop.in
Executable file
8
plugins/externaltools/data/open-terminal-here.desktop.in
Executable file
@@ -0,0 +1,8 @@
|
||||
[Gedit Tool]
|
||||
_Name=Open terminal here
|
||||
_Comment=Open a terminal in the document location
|
||||
Input=nothing
|
||||
Output=output-panel
|
||||
Applicability=local
|
||||
Save-files=nothing
|
||||
Languages=
|
4
plugins/externaltools/data/open-terminal-here.tool.in
Executable file
4
plugins/externaltools/data/open-terminal-here.tool.in
Executable file
@@ -0,0 +1,4 @@
|
||||
#!/bin/sh
|
||||
|
||||
#TODO: use "mateconftool-2 -g /desktop/mate/applications/terminal/exec"
|
||||
mate-terminal --working-directory=$GEDIT_CURRENT_DOCUMENT_DIR &
|
9
plugins/externaltools/data/remove-trailing-spaces.desktop.in
Executable file
9
plugins/externaltools/data/remove-trailing-spaces.desktop.in
Executable file
@@ -0,0 +1,9 @@
|
||||
[Gedit Tool]
|
||||
_Name=Remove trailing spaces
|
||||
_Comment=Remove useless trailing spaces in your file
|
||||
Input=document
|
||||
Output=replace-document
|
||||
Shortcut=<Alt>F12
|
||||
Applicability=all
|
||||
Save-files=nothing
|
||||
Languages=
|
3
plugins/externaltools/data/remove-trailing-spaces.tool.in
Executable file
3
plugins/externaltools/data/remove-trailing-spaces.tool.in
Executable file
@@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
sed 's/[[:blank:]]*$//'
|
8
plugins/externaltools/data/run-command.desktop.in
Executable file
8
plugins/externaltools/data/run-command.desktop.in
Executable file
@@ -0,0 +1,8 @@
|
||||
[Gedit Tool]
|
||||
_Name=Run command
|
||||
_Comment=Execute a custom command and put its output in a new document
|
||||
Input=nothing
|
||||
Output=new-document
|
||||
Applicability=all
|
||||
Save-files=nothing
|
||||
Languages=
|
4
plugins/externaltools/data/run-command.tool.in
Executable file
4
plugins/externaltools/data/run-command.tool.in
Executable file
@@ -0,0 +1,4 @@
|
||||
#!/bin/sh
|
||||
|
||||
#TODO: use "mateconftool-2 -g /desktop/mate/applications/terminal/exec"
|
||||
exec `matedialog --entry --title="Run command - gedit" --text="Command to run"`
|
9
plugins/externaltools/externaltools.gedit-plugin.desktop.in
Executable file
9
plugins/externaltools/externaltools.gedit-plugin.desktop.in
Executable file
@@ -0,0 +1,9 @@
|
||||
[Gedit Plugin]
|
||||
Loader=python
|
||||
Module=externaltools
|
||||
IAge=2
|
||||
_Name=External Tools
|
||||
_Description=Execute external commands and shell scripts.
|
||||
Authors=Steve Frécinaux <steve@istique.net>
|
||||
Copyright=Copyright © 2005 Steve Frécinaux
|
||||
Website=http://www.gedit.org
|
4
plugins/externaltools/scripts/Makefile.am
Executable file
4
plugins/externaltools/scripts/Makefile.am
Executable file
@@ -0,0 +1,4 @@
|
||||
EXTRA_DIST = gedit-tool-merge.pl
|
||||
|
||||
|
||||
-include $(top_srcdir)/git.mk
|
78
plugins/externaltools/scripts/gedit-tool-merge.pl
Executable file
78
plugins/externaltools/scripts/gedit-tool-merge.pl
Executable file
@@ -0,0 +1,78 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
# gedit-tool-merge.pl
|
||||
# This file is part of gedit
|
||||
#
|
||||
# Copyright (C) 2006 - Steve Frécinaux <code@istique.net>
|
||||
#
|
||||
# gedit 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 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# gedit 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 gedit; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
# Boston, MA 02110-1301 USA
|
||||
|
||||
# This script merges a script file with a desktop file containing
|
||||
# metadata about the external tool. This is required in order to
|
||||
# have translatable tools (bug #342042) since intltool can't extract
|
||||
# string directly from tool files (a tool file being the combination
|
||||
# of a script file and a metadata section).
|
||||
#
|
||||
# The desktop file is embedded in a comment of the script file, under
|
||||
# the assumption that any scripting language supports # as a comment
|
||||
# mark (this is likely to be true since the shebang uses #!). The
|
||||
# section is placed at the top of the tool file, after the shebang and
|
||||
# modelines if present.
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Getopt::Long;
|
||||
|
||||
sub usage {
|
||||
print <<EOF;
|
||||
Usage: ${0} [OPTION]... [SCRIPT] [DESKTOP]
|
||||
Merges a script file with a desktop file, embedding it in a comment.
|
||||
|
||||
-o, --output=FILE Specify the output file name. [default: stdout]
|
||||
EOF
|
||||
exit;
|
||||
}
|
||||
|
||||
my $output = "";
|
||||
my $help;
|
||||
|
||||
GetOptions ("help|h" => \$help, "output|o=s" => \$output) or &usage;
|
||||
usage if $help or @ARGV lt 2;
|
||||
|
||||
open INFILE, "<", $ARGV[0];
|
||||
open DFILE, "<", $ARGV[1];
|
||||
open STDOUT, ">", $output if $output;
|
||||
|
||||
# Put shebang and various modelines at the top of the generated file.
|
||||
$_ = <INFILE>;
|
||||
print and $_ = <INFILE> if /^#!/;
|
||||
print and $_ = <INFILE> if /-\*-/;
|
||||
print and $_ = <INFILE> if /(ex|vi|vim):/;
|
||||
|
||||
# Put a blank line before the info block if there is one in INFILE.
|
||||
print and $_ = <INFILE> if /^\s*$/;
|
||||
seek INFILE, -length, 1;
|
||||
|
||||
# Embed the desktop file...
|
||||
print "# $_" while <DFILE>;
|
||||
print "\n";
|
||||
|
||||
# ...and write the remaining part of the script.
|
||||
print while <INFILE>;
|
||||
|
||||
close INFILE;
|
||||
close DFILE;
|
||||
close STDOUT;
|
23
plugins/externaltools/tools/Makefile.am
Executable file
23
plugins/externaltools/tools/Makefile.am
Executable file
@@ -0,0 +1,23 @@
|
||||
# Python snippets plugin
|
||||
|
||||
plugindir = $(GEDIT_PLUGINS_LIBS_DIR)/externaltools
|
||||
plugin_PYTHON = \
|
||||
__init__.py \
|
||||
capture.py \
|
||||
library.py \
|
||||
functions.py \
|
||||
manager.py \
|
||||
outputpanel.py \
|
||||
filelookup.py \
|
||||
linkparsing.py
|
||||
|
||||
uidir = $(GEDIT_PLUGINS_DATA_DIR)/externaltools/ui
|
||||
ui_DATA = tools.ui \
|
||||
outputpanel.ui
|
||||
|
||||
EXTRA_DIST = $(ui_DATA)
|
||||
|
||||
CLEANFILES = *.bak *.gladep
|
||||
DISTCLEANFILES = *.bak *.gladep
|
||||
|
||||
-include $(top_srcdir)/git.mk
|
281
plugins/externaltools/tools/__init__.py
Executable file
281
plugins/externaltools/tools/__init__.py
Executable file
@@ -0,0 +1,281 @@
|
||||
# -*- coding: UTF-8 -*-
|
||||
# Gedit External Tools plugin
|
||||
# Copyright (C) 2005-2006 Steve Frécinaux <steve@istique.net>
|
||||
#
|
||||
# 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 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, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
__all__ = ('ExternalToolsPlugin', 'ExternalToolsWindowHelper',
|
||||
'Manager', 'OutputPanel', 'Capture', 'UniqueById')
|
||||
|
||||
import gedit
|
||||
import gtk
|
||||
from manager import Manager
|
||||
from library import ToolLibrary
|
||||
from outputpanel import OutputPanel
|
||||
from capture import Capture
|
||||
from functions import *
|
||||
|
||||
class ToolMenu(object):
|
||||
ACTION_HANDLER_DATA_KEY = "ExternalToolActionHandlerData"
|
||||
ACTION_ITEM_DATA_KEY = "ExternalToolActionItemData"
|
||||
|
||||
def __init__(self, library, window, menupath):
|
||||
super(ToolMenu, self).__init__()
|
||||
self._library = library
|
||||
self._window = window
|
||||
self._menupath = menupath
|
||||
|
||||
self._merge_id = 0
|
||||
self._action_group = gtk.ActionGroup("ExternalToolsPluginToolActions")
|
||||
self._signals = []
|
||||
|
||||
self.update()
|
||||
|
||||
def deactivate(self):
|
||||
self.remove()
|
||||
|
||||
def remove(self):
|
||||
if self._merge_id != 0:
|
||||
self._window.get_ui_manager().remove_ui(self._merge_id)
|
||||
self._window.get_ui_manager().remove_action_group(self._action_group)
|
||||
self._merge_id = 0
|
||||
|
||||
for action in self._action_group.list_actions():
|
||||
handler = action.get_data(self.ACTION_HANDLER_DATA_KEY)
|
||||
|
||||
if handler is not None:
|
||||
action.disconnect(handler)
|
||||
|
||||
action.set_data(self.ACTION_ITEM_DATA_KEY, None)
|
||||
action.set_data(self.ACTION_HANDLER_DATA_KEY, None)
|
||||
|
||||
self._action_group.remove_action(action)
|
||||
|
||||
accelmap = gtk.accel_map_get()
|
||||
|
||||
for s in self._signals:
|
||||
accelmap.disconnect(s)
|
||||
|
||||
self._signals = []
|
||||
|
||||
def _insert_directory(self, directory, path):
|
||||
manager = self._window.get_ui_manager()
|
||||
|
||||
for item in directory.subdirs:
|
||||
action_name = 'ExternalToolDirectory%X' % id(item)
|
||||
action = gtk.Action(action_name, item.name.replace('_', '__'), None, None)
|
||||
self._action_group.add_action(action)
|
||||
|
||||
manager.add_ui(self._merge_id, path,
|
||||
action_name, action_name,
|
||||
gtk.UI_MANAGER_MENU, False)
|
||||
|
||||
self._insert_directory(item, path + '/' + action_name)
|
||||
|
||||
for item in directory.tools:
|
||||
action_name = 'ExternalToolTool%X' % id(item)
|
||||
action = gtk.Action(action_name, item.name.replace('_', '__'), item.comment, None)
|
||||
handler = action.connect("activate", capture_menu_action, self._window, item)
|
||||
|
||||
action.set_data(self.ACTION_ITEM_DATA_KEY, item)
|
||||
action.set_data(self.ACTION_HANDLER_DATA_KEY, handler)
|
||||
|
||||
# Make sure to replace accel
|
||||
accelpath = '<Actions>/ExternalToolsPluginToolActions/%s' % (action_name, )
|
||||
|
||||
if item.shortcut:
|
||||
key, mod = gtk.accelerator_parse(item.shortcut)
|
||||
gtk.accel_map_change_entry(accelpath, key, mod, True)
|
||||
|
||||
self._signals.append(gtk.accel_map_get().connect('changed::%s' % (accelpath,), self.on_accelmap_changed, item))
|
||||
|
||||
self._action_group.add_action_with_accel(action, item.shortcut)
|
||||
|
||||
manager.add_ui(self._merge_id, path,
|
||||
action_name, action_name,
|
||||
gtk.UI_MANAGER_MENUITEM, False)
|
||||
|
||||
def on_accelmap_changed(self, accelmap, path, key, mod, tool):
|
||||
tool.shortcut = gtk.accelerator_name(key, mod)
|
||||
tool.save()
|
||||
|
||||
self._window.get_data("ExternalToolsPluginWindowData").update_manager(tool)
|
||||
|
||||
def update(self):
|
||||
self.remove()
|
||||
self._merge_id = self._window.get_ui_manager().new_merge_id()
|
||||
self._insert_directory(self._library.tree, self._menupath)
|
||||
self._window.get_ui_manager().insert_action_group(self._action_group, -1)
|
||||
self.filter(self._window.get_active_document())
|
||||
|
||||
def filter_language(self, language, item):
|
||||
if not item.languages:
|
||||
return True
|
||||
|
||||
if not language and 'plain' in item.languages:
|
||||
return True
|
||||
|
||||
if language and (language.get_id() in item.languages):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def filter(self, document):
|
||||
if document is None:
|
||||
return
|
||||
|
||||
titled = document.get_uri() is not None
|
||||
remote = not document.is_local()
|
||||
|
||||
states = {
|
||||
'all' : True,
|
||||
'local': titled and not remote,
|
||||
'remote': titled and remote,
|
||||
'titled': titled,
|
||||
'untitled': not titled,
|
||||
}
|
||||
|
||||
language = document.get_language()
|
||||
|
||||
for action in self._action_group.list_actions():
|
||||
item = action.get_data(self.ACTION_ITEM_DATA_KEY)
|
||||
|
||||
if item is not None:
|
||||
action.set_visible(states[item.applicability] and self.filter_language(language, item))
|
||||
|
||||
class ExternalToolsWindowHelper(object):
|
||||
def __init__(self, plugin, window):
|
||||
super(ExternalToolsWindowHelper, self).__init__()
|
||||
|
||||
self._window = window
|
||||
self._plugin = plugin
|
||||
self._library = ToolLibrary()
|
||||
|
||||
manager = window.get_ui_manager()
|
||||
|
||||
self._action_group = gtk.ActionGroup('ExternalToolsPluginActions')
|
||||
self._action_group.set_translation_domain('gedit')
|
||||
self._action_group.add_actions([('ExternalToolManager',
|
||||
None,
|
||||
_('Manage _External Tools...'),
|
||||
None,
|
||||
_("Opens the External Tools Manager"),
|
||||
lambda action: plugin.open_dialog()),
|
||||
('ExternalTools',
|
||||
None,
|
||||
_('External _Tools'),
|
||||
None,
|
||||
_("External tools"),
|
||||
None)])
|
||||
manager.insert_action_group(self._action_group, -1)
|
||||
|
||||
ui_string = """
|
||||
<ui>
|
||||
<menubar name="MenuBar">
|
||||
<menu name="ToolsMenu" action="Tools">
|
||||
<placeholder name="ToolsOps_4">
|
||||
<separator/>
|
||||
<menu name="ExternalToolsMenu" action="ExternalTools">
|
||||
<placeholder name="ExternalToolPlaceholder"/>
|
||||
</menu>
|
||||
<separator/>
|
||||
</placeholder>
|
||||
<placeholder name="ToolsOps_5">
|
||||
<menuitem name="ExternalToolManager" action="ExternalToolManager"/>
|
||||
</placeholder>
|
||||
</menu>
|
||||
</menubar>
|
||||
</ui>"""
|
||||
|
||||
self._merge_id = manager.add_ui_from_string(ui_string)
|
||||
|
||||
self.menu = ToolMenu(self._library, self._window,
|
||||
"/MenuBar/ToolsMenu/ToolsOps_4/ExternalToolsMenu/ExternalToolPlaceholder")
|
||||
manager.ensure_update()
|
||||
|
||||
# Create output console
|
||||
self._output_buffer = OutputPanel(self._plugin.get_data_dir(), window)
|
||||
bottom = window.get_bottom_panel()
|
||||
bottom.add_item(self._output_buffer.panel,
|
||||
_("Shell Output"),
|
||||
gtk.STOCK_EXECUTE)
|
||||
|
||||
def update_ui(self):
|
||||
self.menu.filter(self._window.get_active_document())
|
||||
self._window.get_ui_manager().ensure_update()
|
||||
|
||||
def deactivate(self):
|
||||
manager = self._window.get_ui_manager()
|
||||
self.menu.deactivate()
|
||||
manager.remove_ui(self._merge_id)
|
||||
manager.remove_action_group(self._action_group)
|
||||
manager.ensure_update()
|
||||
|
||||
bottom = self._window.get_bottom_panel()
|
||||
bottom.remove_item(self._output_buffer.panel)
|
||||
|
||||
def update_manager(self, tool):
|
||||
self._plugin.update_manager(tool)
|
||||
|
||||
class ExternalToolsPlugin(gedit.Plugin):
|
||||
WINDOW_DATA_KEY = "ExternalToolsPluginWindowData"
|
||||
|
||||
def __init__(self):
|
||||
super(ExternalToolsPlugin, self).__init__()
|
||||
|
||||
self._manager = None
|
||||
self._manager_default_size = None
|
||||
|
||||
ToolLibrary().set_locations(os.path.join(self.get_data_dir(), 'tools'))
|
||||
|
||||
def activate(self, window):
|
||||
helper = ExternalToolsWindowHelper(self, window)
|
||||
window.set_data(self.WINDOW_DATA_KEY, helper)
|
||||
|
||||
def deactivate(self, window):
|
||||
window.get_data(self.WINDOW_DATA_KEY).deactivate()
|
||||
window.set_data(self.WINDOW_DATA_KEY, None)
|
||||
|
||||
def update_ui(self, window):
|
||||
window.get_data(self.WINDOW_DATA_KEY).update_ui()
|
||||
|
||||
def create_configure_dialog(self):
|
||||
return self.open_dialog()
|
||||
|
||||
def open_dialog(self):
|
||||
if not self._manager:
|
||||
self._manager = Manager(self.get_data_dir())
|
||||
|
||||
if self._manager_default_size:
|
||||
self._manager.dialog.set_default_size(*self._manager_default_size)
|
||||
|
||||
self._manager.dialog.connect('destroy', self.on_manager_destroy)
|
||||
|
||||
window = gedit.app_get_default().get_active_window()
|
||||
self._manager.run(window)
|
||||
|
||||
return self._manager.dialog
|
||||
|
||||
def update_manager(self, tool):
|
||||
if not self._manager:
|
||||
return
|
||||
|
||||
self._manager.tool_changed(tool, True)
|
||||
|
||||
def on_manager_destroy(self, dialog):
|
||||
self._manager_default_size = [dialog.allocation.width, dialog.allocation.height]
|
||||
self._manager = None
|
||||
|
||||
# ex:ts=4:et:
|
214
plugins/externaltools/tools/capture.py
Executable file
214
plugins/externaltools/tools/capture.py
Executable file
@@ -0,0 +1,214 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Gedit External Tools plugin
|
||||
# Copyright (C) 2005-2006 Steve Frécinaux <steve@istique.net>
|
||||
#
|
||||
# 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 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, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
__all__ = ('Capture', )
|
||||
|
||||
import os, sys, signal
|
||||
import locale
|
||||
import subprocess
|
||||
import gobject
|
||||
import fcntl
|
||||
import glib
|
||||
|
||||
class Capture(gobject.GObject):
|
||||
CAPTURE_STDOUT = 0x01
|
||||
CAPTURE_STDERR = 0x02
|
||||
CAPTURE_BOTH = 0x03
|
||||
CAPTURE_NEEDS_SHELL = 0x04
|
||||
|
||||
WRITE_BUFFER_SIZE = 0x4000
|
||||
|
||||
__gsignals__ = {
|
||||
'stdout-line' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_STRING,)),
|
||||
'stderr-line' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_STRING,)),
|
||||
'begin-execute': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, tuple()),
|
||||
'end-execute' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_INT,))
|
||||
}
|
||||
|
||||
def __init__(self, command, cwd = None, env = {}):
|
||||
gobject.GObject.__init__(self)
|
||||
self.pipe = None
|
||||
self.env = env
|
||||
self.cwd = cwd
|
||||
self.flags = self.CAPTURE_BOTH | self.CAPTURE_NEEDS_SHELL
|
||||
self.command = command
|
||||
self.input_text = None
|
||||
|
||||
def set_env(self, **values):
|
||||
self.env.update(**values)
|
||||
|
||||
def set_command(self, command):
|
||||
self.command = command
|
||||
|
||||
def set_flags(self, flags):
|
||||
self.flags = flags
|
||||
|
||||
def set_input(self, text):
|
||||
self.input_text = text
|
||||
|
||||
def set_cwd(self, cwd):
|
||||
self.cwd = cwd
|
||||
|
||||
def execute(self):
|
||||
if self.command is None:
|
||||
return
|
||||
|
||||
# Initialize pipe
|
||||
popen_args = {
|
||||
'cwd' : self.cwd,
|
||||
'shell': self.flags & self.CAPTURE_NEEDS_SHELL,
|
||||
'env' : self.env
|
||||
}
|
||||
|
||||
if self.input_text is not None:
|
||||
popen_args['stdin'] = subprocess.PIPE
|
||||
if self.flags & self.CAPTURE_STDOUT:
|
||||
popen_args['stdout'] = subprocess.PIPE
|
||||
if self.flags & self.CAPTURE_STDERR:
|
||||
popen_args['stderr'] = subprocess.PIPE
|
||||
|
||||
self.tried_killing = False
|
||||
self.idle_write_id = 0
|
||||
self.read_buffer = ''
|
||||
|
||||
try:
|
||||
self.pipe = subprocess.Popen(self.command, **popen_args)
|
||||
except OSError, e:
|
||||
self.pipe = None
|
||||
self.emit('stderr-line', _('Could not execute command: %s') % (e, ))
|
||||
return
|
||||
|
||||
# Signal
|
||||
self.emit('begin-execute')
|
||||
|
||||
if self.flags & self.CAPTURE_STDOUT:
|
||||
# Set non blocking
|
||||
flags = fcntl.fcntl(self.pipe.stdout.fileno(), fcntl.F_GETFL) | os.O_NONBLOCK
|
||||
fcntl.fcntl(self.pipe.stdout.fileno(), fcntl.F_SETFL, flags)
|
||||
|
||||
gobject.io_add_watch(self.pipe.stdout,
|
||||
gobject.IO_IN | gobject.IO_HUP,
|
||||
self.on_output)
|
||||
|
||||
if self.flags & self.CAPTURE_STDERR:
|
||||
# Set non blocking
|
||||
flags = fcntl.fcntl(self.pipe.stderr.fileno(), fcntl.F_GETFL) | os.O_NONBLOCK
|
||||
fcntl.fcntl(self.pipe.stderr.fileno(), fcntl.F_SETFL, flags)
|
||||
|
||||
gobject.io_add_watch(self.pipe.stderr,
|
||||
gobject.IO_IN | gobject.IO_HUP,
|
||||
self.on_output)
|
||||
|
||||
# IO
|
||||
if self.input_text is not None:
|
||||
# Write async, in chunks of something
|
||||
self.write_buffer = str(self.input_text)
|
||||
|
||||
if self.idle_write_chunk():
|
||||
self.idle_write_id = gobject.idle_add(self.idle_write_chunk)
|
||||
|
||||
# Wait for the process to complete
|
||||
gobject.child_watch_add(self.pipe.pid, self.on_child_end)
|
||||
|
||||
def idle_write_chunk(self):
|
||||
if not self.pipe:
|
||||
self.idle_write_id = 0
|
||||
return False
|
||||
|
||||
try:
|
||||
l = len(self.write_buffer)
|
||||
m = min(l, self.WRITE_BUFFER_SIZE)
|
||||
|
||||
self.pipe.stdin.write(self.write_buffer[:m])
|
||||
|
||||
if m == l:
|
||||
self.write_buffer = ''
|
||||
self.pipe.stdin.close()
|
||||
|
||||
self.idle_write_id = 0
|
||||
|
||||
return False
|
||||
else:
|
||||
self.write_buffer = self.write_buffer[m:]
|
||||
return True
|
||||
except IOError:
|
||||
self.pipe.stdin.close()
|
||||
self.idle_write_id = 0
|
||||
|
||||
return False
|
||||
|
||||
def on_output(self, source, condition):
|
||||
if condition & (glib.IO_IN | glib.IO_PRI):
|
||||
line = source.read()
|
||||
|
||||
if len(line) > 0:
|
||||
try:
|
||||
line = unicode(line, 'utf-8')
|
||||
except:
|
||||
line = unicode(line,
|
||||
locale.getdefaultlocale()[1],
|
||||
'replace')
|
||||
|
||||
self.read_buffer += line
|
||||
lines = self.read_buffer.splitlines(True)
|
||||
|
||||
if not lines[-1].endswith("\n"):
|
||||
self.read_buffer = lines[-1]
|
||||
lines = lines[0:-1]
|
||||
else:
|
||||
self.read_buffer = ''
|
||||
|
||||
for line in lines:
|
||||
if not self.pipe or source == self.pipe.stdout:
|
||||
self.emit('stdout-line', line)
|
||||
else:
|
||||
self.emit('stderr-line', line)
|
||||
|
||||
if condition & ~(glib.IO_IN | glib.IO_PRI):
|
||||
if self.read_buffer:
|
||||
if source == self.pipe.stdout:
|
||||
self.emit('stdout-line', self.read_buffer)
|
||||
else:
|
||||
self.emit('stderr-line', self.read_buffer)
|
||||
|
||||
self.read_buffer = ''
|
||||
|
||||
self.pipe = None
|
||||
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
def stop(self, error_code = -1):
|
||||
if self.pipe is not None:
|
||||
if self.idle_write_id:
|
||||
gobject.source_remove(self.idle_write_id)
|
||||
self.idle_write_id = 0
|
||||
|
||||
if not self.tried_killing:
|
||||
os.kill(self.pipe.pid, signal.SIGTERM)
|
||||
self.tried_killing = True
|
||||
else:
|
||||
os.kill(self.pipe.pid, signal.SIGKILL)
|
||||
|
||||
def on_child_end(self, pid, error_code):
|
||||
# In an idle, so it is emitted after all the std*-line signals
|
||||
# have been intercepted
|
||||
gobject.idle_add(self.emit, 'end-execute', error_code)
|
||||
|
||||
# ex:ts=4:et:
|
145
plugins/externaltools/tools/filelookup.py
Executable file
145
plugins/externaltools/tools/filelookup.py
Executable file
@@ -0,0 +1,145 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (C) 2009-2010 Per Arneng <per.arneng@anyplanet.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 2 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, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
import os
|
||||
import gio
|
||||
import gedit
|
||||
|
||||
class FileLookup:
|
||||
"""
|
||||
This class is responsible for looking up files given a part or the whole
|
||||
path of a real file. The lookup is delegated to providers wich use different
|
||||
methods of trying to find the real file.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.providers = []
|
||||
self.providers.append(AbsoluteFileLookupProvider())
|
||||
self.providers.append(CwdFileLookupProvider())
|
||||
self.providers.append(OpenDocumentRelPathFileLookupProvider())
|
||||
self.providers.append(OpenDocumentFileLookupProvider())
|
||||
|
||||
def lookup(self, path):
|
||||
"""
|
||||
Tries to find a file specified by the path parameter. It delegates to
|
||||
different lookup providers and the first match is returned. If no file
|
||||
was found then None is returned.
|
||||
|
||||
path -- the path to find
|
||||
"""
|
||||
found_file = None
|
||||
for provider in self.providers:
|
||||
found_file = provider.lookup(path)
|
||||
if found_file is not None:
|
||||
break
|
||||
|
||||
return found_file
|
||||
|
||||
|
||||
class FileLookupProvider:
|
||||
"""
|
||||
The base class of all file lookup providers.
|
||||
"""
|
||||
|
||||
def lookup(self, path):
|
||||
"""
|
||||
This method must be implemented by subclasses. Implementors will be
|
||||
given a path and will try to find a matching file. If no file is found
|
||||
then None is returned.
|
||||
"""
|
||||
raise NotImplementedError("need to implement a lookup method")
|
||||
|
||||
|
||||
class AbsoluteFileLookupProvider(FileLookupProvider):
|
||||
"""
|
||||
This file tries to see if the path given is an absolute path and that the
|
||||
path references a file.
|
||||
"""
|
||||
|
||||
def lookup(self, path):
|
||||
if os.path.isabs(path) and os.path.isfile(path):
|
||||
return gio.File(path)
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
class CwdFileLookupProvider(FileLookupProvider):
|
||||
"""
|
||||
This lookup provider tries to find a file specified by the path relative to
|
||||
the current working directory.
|
||||
"""
|
||||
|
||||
def lookup(self, path):
|
||||
try:
|
||||
cwd = os.getcwd()
|
||||
except OSError:
|
||||
cwd = os.getenv('HOME')
|
||||
|
||||
real_path = os.path.join(cwd, path)
|
||||
|
||||
if os.path.isfile(real_path):
|
||||
return gio.File(real_path)
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
class OpenDocumentRelPathFileLookupProvider(FileLookupProvider):
|
||||
"""
|
||||
Tries to see if the path is relative to any directories where the
|
||||
currently open documents reside in. Example: If you have a document opened
|
||||
'/tmp/Makefile' and a lookup is made for 'src/test2.c' then this class
|
||||
will try to find '/tmp/src/test2.c'.
|
||||
"""
|
||||
|
||||
def lookup(self, path):
|
||||
if path.startswith('/'):
|
||||
return None
|
||||
|
||||
for doc in gedit.app_get_default().get_documents():
|
||||
if doc.is_local():
|
||||
location = doc.get_location()
|
||||
if location:
|
||||
rel_path = location.get_parent().get_path()
|
||||
joined_path = os.path.join(rel_path, path)
|
||||
if os.path.isfile(joined_path):
|
||||
return gio.File(joined_path)
|
||||
|
||||
return None
|
||||
|
||||
|
||||
class OpenDocumentFileLookupProvider(FileLookupProvider):
|
||||
"""
|
||||
Makes a guess that the if the path that was looked for matches the end
|
||||
of the path of a currently open document then that document is the one
|
||||
that is looked for. Example: If a document is opened called '/tmp/t.c'
|
||||
and a lookup is made for 't.c' or 'tmp/t.c' then both will match since
|
||||
the open document ends with the path that is searched for.
|
||||
"""
|
||||
|
||||
def lookup(self, path):
|
||||
if path.startswith('/'):
|
||||
return None
|
||||
|
||||
for doc in gedit.app_get_default().get_documents():
|
||||
if doc.is_local():
|
||||
location = doc.get_location()
|
||||
if location and location.get_uri().endswith(path):
|
||||
return location
|
||||
return None
|
||||
|
||||
# ex:ts=4:et:
|
303
plugins/externaltools/tools/functions.py
Executable file
303
plugins/externaltools/tools/functions.py
Executable file
@@ -0,0 +1,303 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Gedit External Tools plugin
|
||||
# Copyright (C) 2005-2006 Steve Frécinaux <steve@istique.net>
|
||||
#
|
||||
# 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 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, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
import os
|
||||
import gtk
|
||||
from gtk import gdk
|
||||
import gio
|
||||
import gedit
|
||||
#import gtksourceview
|
||||
from outputpanel import OutputPanel
|
||||
from capture import *
|
||||
|
||||
def default(val, d):
|
||||
if val is not None:
|
||||
return val
|
||||
else:
|
||||
return d
|
||||
|
||||
def current_word(document):
|
||||
piter = document.get_iter_at_mark(document.get_insert())
|
||||
start = piter.copy()
|
||||
|
||||
if not piter.starts_word() and (piter.inside_word() or piter.ends_word()):
|
||||
start.backward_word_start()
|
||||
|
||||
if not piter.ends_word() and piter.inside_word():
|
||||
piter.forward_word_end()
|
||||
|
||||
return (start, piter)
|
||||
|
||||
# ==== Capture related functions ====
|
||||
def run_external_tool(window, node):
|
||||
# Configure capture environment
|
||||
try:
|
||||
cwd = os.getcwd()
|
||||
except OSError:
|
||||
cwd = os.getenv('HOME');
|
||||
|
||||
capture = Capture(node.command, cwd)
|
||||
capture.env = os.environ.copy()
|
||||
capture.set_env(GEDIT_CWD = cwd)
|
||||
|
||||
view = window.get_active_view()
|
||||
if view is not None:
|
||||
# Environment vars relative to current document
|
||||
document = view.get_buffer()
|
||||
uri = document.get_uri()
|
||||
|
||||
# Current line number
|
||||
piter = document.get_iter_at_mark(document.get_insert())
|
||||
capture.set_env(GEDIT_CURRENT_LINE_NUMBER=str(piter.get_line() + 1))
|
||||
|
||||
# Current line text
|
||||
piter.set_line_offset(0)
|
||||
end = piter.copy()
|
||||
|
||||
if not end.ends_line():
|
||||
end.forward_to_line_end()
|
||||
|
||||
capture.set_env(GEDIT_CURRENT_LINE=piter.get_text(end))
|
||||
|
||||
# Selected text (only if input is not selection)
|
||||
if node.input != 'selection' and node.input != 'selection-document':
|
||||
bounds = document.get_selection_bounds()
|
||||
|
||||
if bounds:
|
||||
capture.set_env(GEDIT_SELECTED_TEXT=bounds[0].get_text(bounds[1]))
|
||||
|
||||
bounds = current_word(document)
|
||||
capture.set_env(GEDIT_CURRENT_WORD=bounds[0].get_text(bounds[1]))
|
||||
|
||||
capture.set_env(GEDIT_CURRENT_DOCUMENT_TYPE=document.get_mime_type())
|
||||
|
||||
if uri is not None:
|
||||
gfile = gio.File(uri)
|
||||
scheme = gfile.get_uri_scheme()
|
||||
name = os.path.basename(uri)
|
||||
capture.set_env(GEDIT_CURRENT_DOCUMENT_URI = uri,
|
||||
GEDIT_CURRENT_DOCUMENT_NAME = name,
|
||||
GEDIT_CURRENT_DOCUMENT_SCHEME = scheme)
|
||||
if gedit.utils.uri_has_file_scheme(uri):
|
||||
path = gfile.get_path()
|
||||
cwd = os.path.dirname(path)
|
||||
capture.set_cwd(cwd)
|
||||
capture.set_env(GEDIT_CURRENT_DOCUMENT_PATH = path,
|
||||
GEDIT_CURRENT_DOCUMENT_DIR = cwd)
|
||||
|
||||
documents_uri = [doc.get_uri()
|
||||
for doc in window.get_documents()
|
||||
if doc.get_uri() is not None]
|
||||
documents_path = [gio.File(uri).get_path()
|
||||
for uri in documents_uri
|
||||
if gedit.utils.uri_has_file_scheme(uri)]
|
||||
capture.set_env(GEDIT_DOCUMENTS_URI = ' '.join(documents_uri),
|
||||
GEDIT_DOCUMENTS_PATH = ' '.join(documents_path))
|
||||
|
||||
flags = capture.CAPTURE_BOTH
|
||||
|
||||
if not node.has_hash_bang():
|
||||
flags |= capture.CAPTURE_NEEDS_SHELL
|
||||
|
||||
capture.set_flags(flags)
|
||||
|
||||
# Get input text
|
||||
input_type = node.input
|
||||
output_type = node.output
|
||||
|
||||
# Get the panel
|
||||
panel = window.get_data("ExternalToolsPluginWindowData")._output_buffer
|
||||
panel.clear()
|
||||
|
||||
if output_type == 'output-panel':
|
||||
panel.show()
|
||||
|
||||
# Assign the error output to the output panel
|
||||
panel.set_process(capture)
|
||||
|
||||
if input_type != 'nothing' and view is not None:
|
||||
if input_type == 'document':
|
||||
start, end = document.get_bounds()
|
||||
elif input_type == 'selection' or input_type == 'selection-document':
|
||||
try:
|
||||
start, end = document.get_selection_bounds()
|
||||
|
||||
print start, end
|
||||
except ValueError:
|
||||
if input_type == 'selection-document':
|
||||
start, end = document.get_bounds()
|
||||
|
||||
if output_type == 'replace-selection':
|
||||
document.select_range(start, end)
|
||||
else:
|
||||
start = document.get_iter_at_mark(document.get_insert())
|
||||
end = start.copy()
|
||||
|
||||
elif input_type == 'line':
|
||||
start = document.get_iter_at_mark(document.get_insert())
|
||||
end = start.copy()
|
||||
if not start.starts_line():
|
||||
start.set_line_offset(0)
|
||||
if not end.ends_line():
|
||||
end.forward_to_line_end()
|
||||
elif input_type == 'word':
|
||||
start = document.get_iter_at_mark(document.get_insert())
|
||||
end = start.copy()
|
||||
if not start.inside_word():
|
||||
panel.write(_('You must be inside a word to run this command'),
|
||||
panel.command_tag)
|
||||
return
|
||||
if not start.starts_word():
|
||||
start.backward_word_start()
|
||||
if not end.ends_word():
|
||||
end.forward_word_end()
|
||||
|
||||
input_text = document.get_text(start, end)
|
||||
capture.set_input(input_text)
|
||||
|
||||
# Assign the standard output to the chosen "file"
|
||||
if output_type == 'new-document':
|
||||
tab = window.create_tab(True)
|
||||
view = tab.get_view()
|
||||
document = tab.get_document()
|
||||
pos = document.get_start_iter()
|
||||
capture.connect('stdout-line', capture_stdout_line_document, document, pos)
|
||||
document.begin_user_action()
|
||||
view.set_editable(False)
|
||||
view.set_cursor_visible(False)
|
||||
elif output_type != 'output-panel' and output_type != 'nothing' and view is not None:
|
||||
document.begin_user_action()
|
||||
view.set_editable(False)
|
||||
view.set_cursor_visible(False)
|
||||
|
||||
if output_type == 'insert':
|
||||
pos = document.get_iter_at_mark(document.get_mark('insert'))
|
||||
elif output_type == 'replace-selection':
|
||||
document.delete_selection(False, False)
|
||||
pos = document.get_iter_at_mark(document.get_mark('insert'))
|
||||
elif output_type == 'replace-document':
|
||||
document.set_text('')
|
||||
pos = document.get_end_iter()
|
||||
else:
|
||||
pos = document.get_end_iter()
|
||||
capture.connect('stdout-line', capture_stdout_line_document, document, pos)
|
||||
elif output_type != 'nothing':
|
||||
capture.connect('stdout-line', capture_stdout_line_panel, panel)
|
||||
document.begin_user_action()
|
||||
|
||||
capture.connect('stderr-line', capture_stderr_line_panel, panel)
|
||||
capture.connect('begin-execute', capture_begin_execute_panel, panel, view, node.name)
|
||||
capture.connect('end-execute', capture_end_execute_panel, panel, view, output_type)
|
||||
|
||||
# Run the command
|
||||
capture.execute()
|
||||
|
||||
if output_type != 'nothing':
|
||||
document.end_user_action()
|
||||
|
||||
class MultipleDocumentsSaver:
|
||||
def __init__(self, window, docs, node):
|
||||
self._window = window
|
||||
self._node = node
|
||||
self._error = False
|
||||
|
||||
self._counter = len(docs)
|
||||
self._signal_ids = {}
|
||||
self._counter = 0
|
||||
|
||||
signals = {}
|
||||
|
||||
for doc in docs:
|
||||
signals[doc] = doc.connect('saving', self.on_document_saving)
|
||||
gedit.commands.save_document(window, doc)
|
||||
doc.disconnect(signals[doc])
|
||||
|
||||
def on_document_saving(self, doc, size, total_size):
|
||||
self._counter += 1
|
||||
self._signal_ids[doc] = doc.connect('saved', self.on_document_saved)
|
||||
|
||||
def on_document_saved(self, doc, error):
|
||||
if error:
|
||||
self._error = True
|
||||
|
||||
doc.disconnect(self._signal_ids[doc])
|
||||
del self._signal_ids[doc]
|
||||
|
||||
self._counter -= 1
|
||||
|
||||
if self._counter == 0 and not self._error:
|
||||
run_external_tool(self._window, self._node)
|
||||
|
||||
def capture_menu_action(action, window, node):
|
||||
if node.save_files == 'document' and window.get_active_document():
|
||||
MultipleDocumentsSaver(window, [window.get_active_document()], node)
|
||||
return
|
||||
elif node.save_files == 'all':
|
||||
MultipleDocumentsSaver(window, window.get_documents(), node)
|
||||
return
|
||||
|
||||
run_external_tool(window, node)
|
||||
|
||||
def capture_stderr_line_panel(capture, line, panel):
|
||||
if not panel.visible():
|
||||
panel.show()
|
||||
|
||||
panel.write(line, panel.error_tag)
|
||||
|
||||
def capture_begin_execute_panel(capture, panel, view, label):
|
||||
view.get_window(gtk.TEXT_WINDOW_TEXT).set_cursor(gdk.Cursor(gdk.WATCH))
|
||||
|
||||
panel['stop'].set_sensitive(True)
|
||||
panel.clear()
|
||||
panel.write(_("Running tool:"), panel.italic_tag);
|
||||
panel.write(" %s\n\n" % label, panel.bold_tag);
|
||||
|
||||
def capture_end_execute_panel(capture, exit_code, panel, view, output_type):
|
||||
panel['stop'].set_sensitive(False)
|
||||
|
||||
if output_type in ('new-document','replace-document'):
|
||||
doc = view.get_buffer()
|
||||
start = doc.get_start_iter()
|
||||
end = start.copy()
|
||||
end.forward_chars(300)
|
||||
|
||||
mtype = gio.content_type_guess(data=doc.get_text(start, end))
|
||||
lmanager = gedit.get_language_manager()
|
||||
|
||||
language = lmanager.guess_language(doc.get_uri(), mtype)
|
||||
|
||||
if language is not None:
|
||||
doc.set_language(language)
|
||||
|
||||
view.get_window(gtk.TEXT_WINDOW_TEXT).set_cursor(gdk.Cursor(gdk.XTERM))
|
||||
view.set_cursor_visible(True)
|
||||
view.set_editable(True)
|
||||
|
||||
if exit_code == 0:
|
||||
panel.write("\n" + _("Done.") + "\n", panel.italic_tag)
|
||||
else:
|
||||
panel.write("\n" + _("Exited") + ":", panel.italic_tag)
|
||||
panel.write(" %d\n" % exit_code, panel.bold_tag)
|
||||
|
||||
def capture_stdout_line_panel(capture, line, panel):
|
||||
panel.write(line)
|
||||
|
||||
def capture_stdout_line_document(capture, line, document, pos):
|
||||
document.insert(pos, line)
|
||||
|
||||
# ex:ts=4:et:
|
493
plugins/externaltools/tools/library.py
Executable file
493
plugins/externaltools/tools/library.py
Executable file
@@ -0,0 +1,493 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Gedit External Tools plugin
|
||||
# Copyright (C) 2006 Steve Frécinaux <code@istique.net>
|
||||
#
|
||||
# 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 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, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
import os
|
||||
import re
|
||||
import locale
|
||||
import platform
|
||||
|
||||
class Singleton(object):
|
||||
_instance = None
|
||||
|
||||
def __new__(cls, *args, **kwargs):
|
||||
if not cls._instance:
|
||||
cls._instance = super(Singleton, cls).__new__(
|
||||
cls, *args, **kwargs)
|
||||
cls._instance.__init_once__()
|
||||
|
||||
return cls._instance
|
||||
|
||||
class ToolLibrary(Singleton):
|
||||
def __init_once__(self):
|
||||
self.locations = []
|
||||
|
||||
def set_locations(self, datadir):
|
||||
self.locations = []
|
||||
|
||||
if platform.platform() != 'Windows':
|
||||
for d in self.get_xdg_data_dirs():
|
||||
self.locations.append(os.path.join(d, 'gedit-2', 'plugins', 'externaltools', 'tools'))
|
||||
|
||||
self.locations.append(datadir)
|
||||
|
||||
# self.locations[0] is where we save the custom scripts
|
||||
if platform.platform() == 'Windows':
|
||||
toolsdir = os.path.expanduser('~/gedit/tools')
|
||||
else:
|
||||
userdir = os.getenv('MATE22_USER_DIR')
|
||||
if userdir:
|
||||
toolsdir = os.path.join(userdir, 'gedit/tools')
|
||||
else:
|
||||
toolsdir = os.path.expanduser('~/.mate2/gedit/tools')
|
||||
|
||||
self.locations.insert(0, toolsdir);
|
||||
|
||||
if not os.path.isdir(self.locations[0]):
|
||||
os.makedirs(self.locations[0])
|
||||
self.tree = ToolDirectory(self, '')
|
||||
self.import_old_xml_store()
|
||||
else:
|
||||
self.tree = ToolDirectory(self, '')
|
||||
|
||||
# cf. http://standards.freedesktop.org/basedir-spec/latest/
|
||||
def get_xdg_data_dirs(self):
|
||||
dirs = os.getenv('XDG_DATA_DIRS')
|
||||
if dirs:
|
||||
dirs = dirs.split(os.pathsep)
|
||||
else:
|
||||
dirs = ('/usr/local/share', '/usr/share')
|
||||
return dirs
|
||||
|
||||
# This function is meant to be ran only once, when the tools directory is
|
||||
# created. It imports eventual tools that have been saved in the old XML
|
||||
# storage file.
|
||||
def import_old_xml_store(self):
|
||||
import xml.etree.ElementTree as et
|
||||
userdir = os.getenv('MATE22_USER_DIR')
|
||||
if userdir:
|
||||
filename = os.path.join(userdir, 'gedit/gedit-tools.xml')
|
||||
else:
|
||||
filename = os.path.expanduser('~/.mate2/gedit/gedit-tools.xml')
|
||||
|
||||
if not os.path.isfile(filename):
|
||||
return
|
||||
|
||||
print "External tools: importing old tools into the new store..."
|
||||
|
||||
xtree = et.parse(filename)
|
||||
xroot = xtree.getroot()
|
||||
|
||||
for xtool in xroot:
|
||||
for i in self.tree.tools:
|
||||
if i.name == xtool.get('label'):
|
||||
tool = i
|
||||
break
|
||||
else:
|
||||
tool = Tool(self.tree)
|
||||
tool.name = xtool.get('label')
|
||||
tool.autoset_filename()
|
||||
self.tree.tools.append(tool)
|
||||
tool.comment = xtool.get('description')
|
||||
tool.shortcut = xtool.get('accelerator')
|
||||
tool.applicability = xtool.get('applicability')
|
||||
tool.output = xtool.get('output')
|
||||
tool.input = xtool.get('input')
|
||||
|
||||
tool.save_with_script(xtool.text)
|
||||
|
||||
def get_full_path(self, path, mode='r', system = True, local = True):
|
||||
assert (system or local)
|
||||
if path is None:
|
||||
return None
|
||||
if mode == 'r':
|
||||
if system and local:
|
||||
locations = self.locations
|
||||
elif local and not system:
|
||||
locations = [self.locations[0]]
|
||||
elif system and not local:
|
||||
locations = self.locations[1:]
|
||||
else:
|
||||
raise ValueError("system and local can't be both set to False")
|
||||
|
||||
for i in locations:
|
||||
p = os.path.join(i, path)
|
||||
if os.path.lexists(p):
|
||||
return p
|
||||
return None
|
||||
else:
|
||||
path = os.path.join(self.locations[0], path)
|
||||
dirname = os.path.dirname(path)
|
||||
if not os.path.isdir(dirname):
|
||||
os.mkdir(dirname)
|
||||
return path
|
||||
|
||||
class ToolDirectory(object):
|
||||
def __init__(self, parent, dirname):
|
||||
super(ToolDirectory, self).__init__()
|
||||
self.subdirs = list()
|
||||
self.tools = list()
|
||||
if isinstance(parent, ToolDirectory):
|
||||
self.parent = parent
|
||||
self.library = parent.library
|
||||
else:
|
||||
self.parent = None
|
||||
self.library = parent
|
||||
self.dirname = dirname
|
||||
self._load()
|
||||
|
||||
def listdir(self):
|
||||
elements = dict()
|
||||
for l in self.library.locations:
|
||||
d = os.path.join(l, self.dirname)
|
||||
if not os.path.isdir(d):
|
||||
continue
|
||||
for i in os.listdir(d):
|
||||
elements[i] = None
|
||||
keys = elements.keys()
|
||||
keys.sort()
|
||||
return keys
|
||||
|
||||
def _load(self):
|
||||
for p in self.listdir():
|
||||
path = os.path.join(self.dirname, p)
|
||||
full_path = self.library.get_full_path(path)
|
||||
if os.path.isdir(full_path):
|
||||
self.subdirs.append(ToolDirectory(self, p))
|
||||
elif os.path.isfile(full_path) and os.access(full_path, os.X_OK):
|
||||
self.tools.append(Tool(self, p))
|
||||
|
||||
def get_path(self):
|
||||
if self.parent is None:
|
||||
return self.dirname
|
||||
else:
|
||||
return os.path.join(self.parent.get_path(), self.dirname)
|
||||
path = property(get_path)
|
||||
|
||||
def get_name(self):
|
||||
return os.path.basename(self.dirname)
|
||||
name = property(get_name)
|
||||
|
||||
def delete_tool(self, tool):
|
||||
# Only remove it if it lays in $HOME
|
||||
if tool in self.tools:
|
||||
path = tool.get_path()
|
||||
if path is not None:
|
||||
filename = os.path.join(self.library.locations[0], path)
|
||||
if os.path.isfile(filename):
|
||||
os.unlink(filename)
|
||||
self.tools.remove(tool)
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def revert_tool(self, tool):
|
||||
# Only remove it if it lays in $HOME
|
||||
filename = os.path.join(self.library.locations[0], tool.get_path())
|
||||
if tool in self.tools and os.path.isfile(filename):
|
||||
os.unlink(filename)
|
||||
tool._load()
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
class Tool(object):
|
||||
RE_KEY = re.compile('^([a-zA-Z_][a-zA-Z0-9_.\-]*)(\[([a-zA-Z_@]+)\])?$')
|
||||
|
||||
def __init__(self, parent, filename = None):
|
||||
super(Tool, self).__init__()
|
||||
self.parent = parent
|
||||
self.library = parent.library
|
||||
self.filename = filename
|
||||
self.changed = False
|
||||
self._properties = dict()
|
||||
self._transform = {
|
||||
'Languages': [self._to_list, self._from_list]
|
||||
}
|
||||
self._load()
|
||||
|
||||
def _to_list(self, value):
|
||||
if value.strip() == '':
|
||||
return []
|
||||
else:
|
||||
return map(lambda x: x.strip(), value.split(','))
|
||||
|
||||
def _from_list(self, value):
|
||||
return ','.join(value)
|
||||
|
||||
def _parse_value(self, key, value):
|
||||
if key in self._transform:
|
||||
return self._transform[key][0](value)
|
||||
else:
|
||||
return value
|
||||
|
||||
def _load(self):
|
||||
if self.filename is None:
|
||||
return
|
||||
|
||||
filename = self.library.get_full_path(self.get_path())
|
||||
if filename is None:
|
||||
return
|
||||
|
||||
fp = file(filename, 'r', 1)
|
||||
in_block = False
|
||||
lang = locale.getlocale(locale.LC_MESSAGES)[0]
|
||||
|
||||
for line in fp:
|
||||
if not in_block:
|
||||
in_block = line.startswith('# [Gedit Tool]')
|
||||
continue
|
||||
if line.startswith('##') or line.startswith('# #'): continue
|
||||
if not line.startswith('# '): break
|
||||
|
||||
try:
|
||||
(key, value) = [i.strip() for i in line[2:].split('=', 1)]
|
||||
m = self.RE_KEY.match(key)
|
||||
if m.group(3) is None:
|
||||
self._properties[m.group(1)] = self._parse_value(m.group(1), value)
|
||||
elif lang is not None and lang.startswith(m.group(3)):
|
||||
self._properties[m.group(1)] = self._parse_value(m.group(1), value)
|
||||
except ValueError:
|
||||
break
|
||||
fp.close()
|
||||
self.changed = False
|
||||
|
||||
def _set_property_if_changed(self, key, value):
|
||||
if value != self._properties.get(key):
|
||||
self._properties[key] = value
|
||||
|
||||
self.changed = True
|
||||
|
||||
def is_global(self):
|
||||
return self.library.get_full_path(self.get_path(), local=False) is not None
|
||||
|
||||
def is_local(self):
|
||||
return self.library.get_full_path(self.get_path(), system=False) is not None
|
||||
|
||||
def is_global(self):
|
||||
return self.library.get_full_path(self.get_path(), local=False) is not None
|
||||
|
||||
def get_path(self):
|
||||
if self.filename is not None:
|
||||
return os.path.join(self.parent.get_path(), self.filename)
|
||||
else:
|
||||
return None
|
||||
path = property(get_path)
|
||||
|
||||
# This command is the one that is meant to be ran
|
||||
# (later, could have an Exec key or something)
|
||||
def get_command(self):
|
||||
return self.library.get_full_path(self.get_path())
|
||||
command = property(get_command)
|
||||
|
||||
def get_applicability(self):
|
||||
applicability = self._properties.get('Applicability')
|
||||
if applicability: return applicability
|
||||
return 'all'
|
||||
def set_applicability(self, value):
|
||||
self._set_property_if_changed('Applicability', value)
|
||||
applicability = property(get_applicability, set_applicability)
|
||||
|
||||
def get_name(self):
|
||||
name = self._properties.get('Name')
|
||||
if name: return name
|
||||
return os.path.basename(self.filename)
|
||||
def set_name(self, value):
|
||||
self._set_property_if_changed('Name', value)
|
||||
name = property(get_name, set_name)
|
||||
|
||||
def get_shortcut(self):
|
||||
shortcut = self._properties.get('Shortcut')
|
||||
if shortcut: return shortcut
|
||||
return None
|
||||
def set_shortcut(self, value):
|
||||
self._set_property_if_changed('Shortcut', value)
|
||||
shortcut = property(get_shortcut, set_shortcut)
|
||||
|
||||
def get_comment(self):
|
||||
comment = self._properties.get('Comment')
|
||||
if comment: return comment
|
||||
return self.filename
|
||||
def set_comment(self, value):
|
||||
self._set_property_if_changed('Comment', value)
|
||||
comment = property(get_comment, set_comment)
|
||||
|
||||
def get_input(self):
|
||||
input = self._properties.get('Input')
|
||||
if input: return input
|
||||
return 'nothing'
|
||||
def set_input(self, value):
|
||||
self._set_property_if_changed('Input', value)
|
||||
input = property(get_input, set_input)
|
||||
|
||||
def get_output(self):
|
||||
output = self._properties.get('Output')
|
||||
if output: return output
|
||||
return 'output-panel'
|
||||
def set_output(self, value):
|
||||
self._set_property_if_changed('Output', value)
|
||||
output = property(get_output, set_output)
|
||||
|
||||
def get_save_files(self):
|
||||
save_files = self._properties.get('Save-files')
|
||||
if save_files: return save_files
|
||||
return 'nothing'
|
||||
def set_save_files(self, value):
|
||||
self._set_property_if_changed('Save-files', value)
|
||||
save_files = property(get_save_files, set_save_files)
|
||||
|
||||
def get_languages(self):
|
||||
languages = self._properties.get('Languages')
|
||||
if languages: return languages
|
||||
return []
|
||||
def set_languages(self, value):
|
||||
self._set_property_if_changed('Languages', value)
|
||||
languages = property(get_languages, set_languages)
|
||||
|
||||
def has_hash_bang(self):
|
||||
if self.filename is None:
|
||||
return True
|
||||
|
||||
filename = self.library.get_full_path(self.get_path())
|
||||
if filename is None:
|
||||
return True
|
||||
|
||||
fp = open(filename, 'r', 1)
|
||||
for line in fp:
|
||||
if line.strip() == '':
|
||||
continue
|
||||
|
||||
return line.startswith('#!')
|
||||
|
||||
# There is no property for this one because this function is quite
|
||||
# expensive to perform
|
||||
def get_script(self):
|
||||
if self.filename is None:
|
||||
return ["#!/bin/sh\n"]
|
||||
|
||||
filename = self.library.get_full_path(self.get_path())
|
||||
if filename is None:
|
||||
return ["#!/bin/sh\n"]
|
||||
|
||||
fp = open(filename, 'r', 1)
|
||||
lines = list()
|
||||
|
||||
# before entering the data block
|
||||
for line in fp:
|
||||
if line.startswith('# [Gedit Tool]'):
|
||||
break
|
||||
lines.append(line)
|
||||
# in the block:
|
||||
for line in fp:
|
||||
if line.startswith('##'): continue
|
||||
if not (line.startswith('# ') and '=' in line):
|
||||
# after the block: strip one emtpy line (if present)
|
||||
if line.strip() != '':
|
||||
lines.append(line)
|
||||
break
|
||||
# after the block
|
||||
for line in fp:
|
||||
lines.append(line)
|
||||
fp.close()
|
||||
return lines
|
||||
|
||||
def _dump_properties(self):
|
||||
lines = ['# [Gedit Tool]']
|
||||
for item in self._properties.iteritems():
|
||||
if item[0] in self._transform:
|
||||
lines.append('# %s=%s' % (item[0], self._transform[item[0]][1](item[1])))
|
||||
elif item[1] is not None:
|
||||
lines.append('# %s=%s' % item)
|
||||
return '\n'.join(lines) + '\n'
|
||||
|
||||
def save_with_script(self, script):
|
||||
filename = self.library.get_full_path(self.filename, 'w')
|
||||
|
||||
fp = open(filename, 'w', 1)
|
||||
|
||||
# Make sure to first print header (shebang, modeline), then
|
||||
# properties, and then actual content
|
||||
header = []
|
||||
content = []
|
||||
inheader = True
|
||||
|
||||
# Parse
|
||||
for line in script:
|
||||
line = line.rstrip("\n")
|
||||
|
||||
if not inheader:
|
||||
content.append(line)
|
||||
elif line.startswith('#!'):
|
||||
# Shebang (should be always present)
|
||||
header.append(line)
|
||||
elif line.strip().startswith('#') and ('-*-' in line or 'ex:' in line or 'vi:' in line or 'vim:' in line):
|
||||
header.append(line)
|
||||
else:
|
||||
content.append(line)
|
||||
inheader = False
|
||||
|
||||
# Write out header
|
||||
for line in header:
|
||||
fp.write(line + "\n")
|
||||
|
||||
fp.write(self._dump_properties())
|
||||
fp.write("\n")
|
||||
|
||||
for line in content:
|
||||
fp.write(line + "\n")
|
||||
|
||||
fp.close()
|
||||
os.chmod(filename, 0750)
|
||||
self.changed = False
|
||||
|
||||
def save(self):
|
||||
if self.changed:
|
||||
self.save_with_script(self.get_script())
|
||||
|
||||
def autoset_filename(self):
|
||||
if self.filename is not None:
|
||||
return
|
||||
dirname = self.parent.path
|
||||
if dirname != '':
|
||||
dirname += os.path.sep
|
||||
|
||||
basename = self.name.lower().replace(' ', '-').replace('/', '-')
|
||||
|
||||
if self.library.get_full_path(dirname + basename):
|
||||
i = 2
|
||||
while self.library.get_full_path(dirname + "%s-%d" % (basename, i)):
|
||||
i += 1
|
||||
basename = "%s-%d" % (basename, i)
|
||||
self.filename = basename
|
||||
|
||||
if __name__ == '__main__':
|
||||
library = ToolLibrary()
|
||||
|
||||
def print_tool(t, indent):
|
||||
print indent * " " + "%s: %s" % (t.filename, t.name)
|
||||
|
||||
def print_dir(d, indent):
|
||||
print indent * " " + d.dirname + '/'
|
||||
for i in d.subdirs:
|
||||
print_dir(i, indent+1)
|
||||
for i in d.tools:
|
||||
print_tool(i, indent+1)
|
||||
|
||||
print_dir(library.tree, 0)
|
||||
|
||||
# ex:ts=4:et:
|
231
plugins/externaltools/tools/linkparsing.py
Executable file
231
plugins/externaltools/tools/linkparsing.py
Executable file
@@ -0,0 +1,231 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (C) 2009-2010 Per Arneng <per.arneng@anyplanet.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 2 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, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
import re
|
||||
|
||||
class Link:
|
||||
"""
|
||||
This class represents a file link from within a string given by the
|
||||
output of some software tool. A link contains a reference to a file, the
|
||||
line number within the file and the boundaries within the given output
|
||||
string that should be marked as a link.
|
||||
"""
|
||||
|
||||
def __init__(self, path, line_nr, start, end):
|
||||
"""
|
||||
path -- the path of the file (that could be extracted)
|
||||
line_nr -- the line nr of the specified file
|
||||
start -- the index within the string that the link starts at
|
||||
end -- the index within the string where the link ends at
|
||||
"""
|
||||
self.path = path
|
||||
self.line_nr = int(line_nr)
|
||||
self.start = start
|
||||
self.end = end
|
||||
|
||||
def __repr__(self):
|
||||
return "%s[%s](%s:%s)" % (self.path, self.line_nr,
|
||||
self.start, self.end)
|
||||
|
||||
class LinkParser:
|
||||
"""
|
||||
Parses a text using different parsing providers with the goal of finding one
|
||||
or more file links within the text. A typical example could be the output
|
||||
from a compiler that specifies an error in a specific file. The path of the
|
||||
file, the line nr and some more info is then returned so that it can be used
|
||||
to be able to navigate from the error output in to the specific file.
|
||||
|
||||
The actual work of parsing the text is done by instances of classes that
|
||||
inherits from AbstractLinkParser or by regular expressions. To add a new
|
||||
parser just create a class that inherits from AbstractLinkParser and then
|
||||
register in this class cunstructor using the method add_parser. If you want
|
||||
to add a regular expression then just call add_regexp in this class
|
||||
constructor and provide your regexp string as argument.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self._providers = []
|
||||
self.add_regexp(REGEXP_STANDARD)
|
||||
self.add_regexp(REGEXP_PYTHON)
|
||||
self.add_regexp(REGEXP_VALAC)
|
||||
self.add_regexp(REGEXP_BASH)
|
||||
self.add_regexp(REGEXP_RUBY)
|
||||
self.add_regexp(REGEXP_PERL)
|
||||
self.add_regexp(REGEXP_MCS)
|
||||
|
||||
def add_parser(self, parser):
|
||||
self._providers.append(parser)
|
||||
|
||||
def add_regexp(self, regexp):
|
||||
"""
|
||||
Adds a regular expression string that should match a link using
|
||||
re.MULTILINE and re.VERBOSE regexp. The area marked as a link should
|
||||
be captured by a group named lnk. The path of the link should be
|
||||
captured by a group named pth. The line number should be captured by
|
||||
a group named ln. To read more about this look at the documentation
|
||||
for the RegexpLinkParser constructor.
|
||||
"""
|
||||
self.add_parser(RegexpLinkParser(regexp))
|
||||
|
||||
def parse(self, text):
|
||||
"""
|
||||
Parses the given text and returns a list of links that are parsed from
|
||||
the text. This method delegates to parser providers that can parse
|
||||
output from different kinds of formats. If no links are found then an
|
||||
empty list is returned.
|
||||
|
||||
text -- the text to scan for file links. 'text' can not be None.
|
||||
"""
|
||||
if text is None:
|
||||
raise ValueError("text can not be None")
|
||||
|
||||
links = []
|
||||
|
||||
for provider in self._providers:
|
||||
links.extend(provider.parse(text))
|
||||
|
||||
return links
|
||||
|
||||
class AbstractLinkParser(object):
|
||||
"""The "abstract" base class for link parses"""
|
||||
|
||||
def parse(self, text):
|
||||
"""
|
||||
This method should be implemented by subclasses. It takes a text as
|
||||
argument (never None) and then returns a list of Link objects. If no
|
||||
links are found then an empty list is expected. The Link class is
|
||||
defined in this module. If you do not override this method then a
|
||||
NotImplementedError will be thrown.
|
||||
|
||||
text -- the text to parse. This argument is never None.
|
||||
"""
|
||||
raise NotImplementedError("need to implement a parse method")
|
||||
|
||||
class RegexpLinkParser(AbstractLinkParser):
|
||||
"""
|
||||
A class that represents parsers that only use one single regular expression.
|
||||
It can be used by subclasses or by itself. See the constructor documentation
|
||||
for details about the rules surrouning the regexp.
|
||||
"""
|
||||
|
||||
def __init__(self, regex):
|
||||
"""
|
||||
Creates a new RegexpLinkParser based on the given regular expression.
|
||||
The regular expression is multiline and verbose (se python docs on
|
||||
compilation flags). The regular expression should contain three named
|
||||
capturing groups 'lnk', 'pth' and 'ln'. 'lnk' represents the area wich
|
||||
should be marked as a link in the text. 'pth' is the path that should
|
||||
be looked for and 'ln' is the line number in that file.
|
||||
"""
|
||||
self.re = re.compile(regex, re.MULTILINE | re.VERBOSE)
|
||||
|
||||
def parse(self, text):
|
||||
links = []
|
||||
for m in re.finditer(self.re, text):
|
||||
path = m.group("pth")
|
||||
line_nr = m.group("ln")
|
||||
start = m.start("lnk")
|
||||
end = m.end("lnk")
|
||||
link = Link(path, line_nr, start, end)
|
||||
links.append(link)
|
||||
|
||||
return links
|
||||
|
||||
# gcc 'test.c:13: warning: ...'
|
||||
# javac 'Test.java:13: ...'
|
||||
# ruby 'test.rb:5: ...'
|
||||
# scalac 'Test.scala:5: ...'
|
||||
# 6g (go) 'test.go:9: ...'
|
||||
REGEXP_STANDARD = r"""
|
||||
^
|
||||
(?P<lnk>
|
||||
(?P<pth> .*[a-z0-9] )
|
||||
\:
|
||||
(?P<ln> \d+)
|
||||
)
|
||||
\:\s"""
|
||||
|
||||
# python ' File "test.py", line 13'
|
||||
REGEXP_PYTHON = r"""
|
||||
^\s\sFile\s
|
||||
(?P<lnk>
|
||||
\"
|
||||
(?P<pth> [^\"]+ )
|
||||
\",\sline\s
|
||||
(?P<ln> \d+ )
|
||||
),"""
|
||||
|
||||
# python 'test.sh: line 5:'
|
||||
REGEXP_BASH = r"""
|
||||
^(?P<lnk>
|
||||
(?P<pth> .* )
|
||||
\:\sline\s
|
||||
(?P<ln> \d+ )
|
||||
)\:"""
|
||||
|
||||
# valac 'Test.vala:13.1-13.3: ...'
|
||||
REGEXP_VALAC = r"""
|
||||
^(?P<lnk>
|
||||
(?P<pth>
|
||||
.*vala
|
||||
)
|
||||
\:
|
||||
(?P<ln>
|
||||
\d+
|
||||
)
|
||||
\.\d+-\d+\.\d+
|
||||
)\: """
|
||||
|
||||
#ruby
|
||||
#test.rb:5: ...
|
||||
# from test.rb:3:in `each'
|
||||
# fist line parsed by REGEXP_STANDARD
|
||||
REGEXP_RUBY = r"""
|
||||
^\s+from\s
|
||||
(?P<lnk>
|
||||
(?P<pth>
|
||||
.*
|
||||
)
|
||||
\:
|
||||
(?P<ln>
|
||||
\d+
|
||||
)
|
||||
)"""
|
||||
|
||||
# perl 'syntax error at test.pl line 88, near "$fake_var'
|
||||
REGEXP_PERL = r"""
|
||||
\sat\s
|
||||
(?P<lnk>
|
||||
(?P<pth> .* )
|
||||
\sline\s
|
||||
(?P<ln> \d+ )
|
||||
)"""
|
||||
|
||||
# mcs (C#) 'Test.cs(12,7): error CS0103: The name `fakeMethod'
|
||||
REGEXP_MCS = r"""
|
||||
^
|
||||
(?P<lnk>
|
||||
(?P<pth> .*\.[cC][sS] )
|
||||
\(
|
||||
(?P<ln> \d+ )
|
||||
,\d+\)
|
||||
)
|
||||
\:\s
|
||||
"""
|
||||
|
||||
# ex:ts=4:et:
|
948
plugins/externaltools/tools/manager.py
Executable file
948
plugins/externaltools/tools/manager.py
Executable file
@@ -0,0 +1,948 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Gedit External Tools plugin
|
||||
# Copyright (C) 2005-2006 Steve Frécinaux <steve@istique.net>
|
||||
#
|
||||
# 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 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, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
__all__ = ('Manager', )
|
||||
|
||||
import gedit
|
||||
import gtk
|
||||
import gtksourceview2 as gsv
|
||||
import os.path
|
||||
from library import *
|
||||
from functions import *
|
||||
import hashlib
|
||||
from xml.sax import saxutils
|
||||
import gobject
|
||||
|
||||
class LanguagesPopup(gtk.Window):
|
||||
COLUMN_NAME = 0
|
||||
COLUMN_ID = 1
|
||||
COLUMN_ENABLED = 2
|
||||
|
||||
def __init__(self, languages):
|
||||
gtk.Window.__init__(self, gtk.WINDOW_POPUP)
|
||||
|
||||
self.set_default_size(200, 200)
|
||||
self.props.can_focus = True
|
||||
|
||||
self.build()
|
||||
self.init_languages(languages)
|
||||
|
||||
self.show()
|
||||
self.map()
|
||||
|
||||
self.grab_add()
|
||||
|
||||
gtk.gdk.keyboard_grab(self.window, False, 0L)
|
||||
gtk.gdk.pointer_grab(self.window, False, gtk.gdk.BUTTON_PRESS_MASK |
|
||||
gtk.gdk.BUTTON_RELEASE_MASK |
|
||||
gtk.gdk.POINTER_MOTION_MASK |
|
||||
gtk.gdk.ENTER_NOTIFY_MASK |
|
||||
gtk.gdk.LEAVE_NOTIFY_MASK |
|
||||
gtk.gdk.PROXIMITY_IN_MASK |
|
||||
gtk.gdk.PROXIMITY_OUT_MASK, None, None, 0L)
|
||||
|
||||
self.view.get_selection().select_path((0,))
|
||||
|
||||
def build(self):
|
||||
self.model = gtk.ListStore(str, str, bool)
|
||||
|
||||
self.sw = gtk.ScrolledWindow()
|
||||
self.sw.show()
|
||||
|
||||
self.sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
|
||||
self.sw.set_shadow_type(gtk.SHADOW_ETCHED_IN)
|
||||
|
||||
self.view = gtk.TreeView(self.model)
|
||||
self.view.show()
|
||||
|
||||
self.view.set_headers_visible(False)
|
||||
|
||||
column = gtk.TreeViewColumn()
|
||||
|
||||
renderer = gtk.CellRendererToggle()
|
||||
column.pack_start(renderer, False)
|
||||
column.set_attributes(renderer, active=self.COLUMN_ENABLED)
|
||||
|
||||
renderer.connect('toggled', self.on_language_toggled)
|
||||
|
||||
renderer = gtk.CellRendererText()
|
||||
column.pack_start(renderer, True)
|
||||
column.set_attributes(renderer, text=self.COLUMN_NAME)
|
||||
|
||||
self.view.append_column(column)
|
||||
self.view.set_row_separator_func(self.on_separator)
|
||||
|
||||
self.sw.add(self.view)
|
||||
|
||||
self.add(self.sw)
|
||||
|
||||
def enabled_languages(self, model, path, piter, ret):
|
||||
enabled = model.get_value(piter, self.COLUMN_ENABLED)
|
||||
|
||||
if path == (0,) and enabled:
|
||||
return True
|
||||
|
||||
if enabled:
|
||||
ret.append(model.get_value(piter, self.COLUMN_ID))
|
||||
|
||||
return False
|
||||
|
||||
def languages(self):
|
||||
ret = []
|
||||
|
||||
self.model.foreach(self.enabled_languages, ret)
|
||||
return ret
|
||||
|
||||
def on_separator(self, model, piter):
|
||||
val = model.get_value(piter, self.COLUMN_NAME)
|
||||
return val == '-'
|
||||
|
||||
def init_languages(self, languages):
|
||||
manager = gsv.LanguageManager()
|
||||
langs = gedit.language_manager_list_languages_sorted(manager, True)
|
||||
|
||||
self.model.append([_('All languages'), None, not languages])
|
||||
self.model.append(['-', None, False])
|
||||
self.model.append([_('Plain Text'), 'plain', 'plain' in languages])
|
||||
self.model.append(['-', None, False])
|
||||
|
||||
for lang in langs:
|
||||
self.model.append([lang.get_name(), lang.get_id(), lang.get_id() in languages])
|
||||
|
||||
def correct_all(self, model, path, piter, enabled):
|
||||
if path == (0,):
|
||||
return False
|
||||
|
||||
model.set_value(piter, self.COLUMN_ENABLED, enabled)
|
||||
|
||||
def on_language_toggled(self, renderer, path):
|
||||
piter = self.model.get_iter(path)
|
||||
|
||||
enabled = self.model.get_value(piter, self.COLUMN_ENABLED)
|
||||
self.model.set_value(piter, self.COLUMN_ENABLED, not enabled)
|
||||
|
||||
if path == '0':
|
||||
self.model.foreach(self.correct_all, False)
|
||||
else:
|
||||
self.model.set_value(self.model.get_iter_first(), self.COLUMN_ENABLED, False)
|
||||
|
||||
def do_key_press_event(self, event):
|
||||
if event.keyval == gtk.keysyms.Escape:
|
||||
self.destroy()
|
||||
return True
|
||||
else:
|
||||
event.window = self.view.get_bin_window()
|
||||
return self.view.event(event)
|
||||
|
||||
def do_key_release_event(self, event):
|
||||
event.window = self.view.get_bin_window()
|
||||
return self.view.event(event)
|
||||
|
||||
def in_window(self, event, window=None):
|
||||
if not window:
|
||||
window = self.window
|
||||
|
||||
geometry = window.get_geometry()
|
||||
origin = window.get_origin()
|
||||
|
||||
return event.x_root >= origin[0] and \
|
||||
event.x_root <= origin[0] + geometry[2] and \
|
||||
event.y_root >= origin[1] and \
|
||||
event.y_root <= origin[1] + geometry[3]
|
||||
|
||||
def do_destroy(self):
|
||||
gtk.gdk.keyboard_ungrab(0L)
|
||||
gtk.gdk.pointer_ungrab(0L)
|
||||
|
||||
return gtk.Window.do_destroy(self)
|
||||
|
||||
def setup_event(self, event, window):
|
||||
fr = event.window.get_origin()
|
||||
to = window.get_origin()
|
||||
|
||||
event.window = window
|
||||
event.x += fr[0] - to[0]
|
||||
event.y += fr[1] - to[1]
|
||||
|
||||
def resolve_widgets(self, root):
|
||||
res = [root]
|
||||
|
||||
if isinstance(root, gtk.Container):
|
||||
root.forall(lambda x, y: res.extend(self.resolve_widgets(x)), None)
|
||||
|
||||
return res
|
||||
|
||||
def resolve_windows(self, window):
|
||||
if not window:
|
||||
return []
|
||||
|
||||
res = [window]
|
||||
res.extend(window.get_children())
|
||||
|
||||
return res
|
||||
|
||||
def propagate_mouse_event(self, event):
|
||||
allwidgets = self.resolve_widgets(self.get_child())
|
||||
allwidgets.reverse()
|
||||
|
||||
orig = [event.x, event.y]
|
||||
|
||||
for widget in allwidgets:
|
||||
windows = self.resolve_windows(widget.window)
|
||||
windows.reverse()
|
||||
|
||||
for window in windows:
|
||||
if not (window.get_events() & event.type):
|
||||
continue
|
||||
|
||||
if self.in_window(event, window):
|
||||
self.setup_event(event, window)
|
||||
|
||||
if widget.event(event):
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def do_button_press_event(self, event):
|
||||
if not self.in_window(event):
|
||||
self.destroy()
|
||||
else:
|
||||
return self.propagate_mouse_event(event)
|
||||
|
||||
def do_button_release_event(self, event):
|
||||
if not self.in_window(event):
|
||||
self.destroy()
|
||||
else:
|
||||
return self.propagate_mouse_event(event)
|
||||
|
||||
def do_scroll_event(self, event):
|
||||
return self.propagate_mouse_event(event)
|
||||
|
||||
def do_motion_notify_event(self, event):
|
||||
return self.propagate_mouse_event(event)
|
||||
|
||||
def do_enter_notify_event(self, event):
|
||||
return self.propagate_mouse_event(event)
|
||||
|
||||
def do_leave_notify_event(self, event):
|
||||
return self.propagate_mouse_event(event)
|
||||
|
||||
def do_proximity_in_event(self, event):
|
||||
return self.propagate_mouse_event(event)
|
||||
|
||||
def do_proximity_out_event(self, event):
|
||||
return self.propagate_mouse_event(event)
|
||||
|
||||
gobject.type_register(LanguagesPopup)
|
||||
|
||||
class Manager:
|
||||
TOOL_COLUMN = 0 # For Tree
|
||||
NAME_COLUMN = 1 # For Combo
|
||||
|
||||
def __init__(self, datadir):
|
||||
self.datadir = datadir
|
||||
self.dialog = None
|
||||
self._languages = {}
|
||||
self._tool_rows = {}
|
||||
|
||||
self.build()
|
||||
|
||||
def build(self):
|
||||
callbacks = {
|
||||
'on_new_tool_button_clicked' : self.on_new_tool_button_clicked,
|
||||
'on_remove_tool_button_clicked' : self.on_remove_tool_button_clicked,
|
||||
'on_tool_manager_dialog_response' : self.on_tool_manager_dialog_response,
|
||||
'on_tool_manager_dialog_focus_out': self.on_tool_manager_dialog_focus_out,
|
||||
'on_accelerator_key_press' : self.on_accelerator_key_press,
|
||||
'on_accelerator_focus_in' : self.on_accelerator_focus_in,
|
||||
'on_accelerator_focus_out' : self.on_accelerator_focus_out,
|
||||
'on_languages_button_clicked' : self.on_languages_button_clicked
|
||||
}
|
||||
|
||||
# Load the "main-window" widget from the ui file.
|
||||
self.ui = gtk.Builder()
|
||||
self.ui.add_from_file(os.path.join(self.datadir, 'ui', 'tools.ui'))
|
||||
self.ui.connect_signals(callbacks)
|
||||
self.dialog = self.ui.get_object('tool-manager-dialog')
|
||||
|
||||
self.view = self.ui.get_object('view')
|
||||
|
||||
self.__init_tools_model()
|
||||
self.__init_tools_view()
|
||||
|
||||
for name in ['input', 'output', 'applicability', 'save-files']:
|
||||
self.__init_combobox(name)
|
||||
|
||||
self.do_update()
|
||||
|
||||
def expand_from_doc(self, doc):
|
||||
row = None
|
||||
|
||||
if doc:
|
||||
if doc.get_language():
|
||||
lid = doc.get_language().get_id()
|
||||
|
||||
if lid in self._languages:
|
||||
row = self._languages[lid]
|
||||
elif 'plain' in self._languages:
|
||||
row = self._languages['plain']
|
||||
|
||||
if not row and None in self._languages:
|
||||
row = self._languages[None]
|
||||
|
||||
if not row:
|
||||
return
|
||||
|
||||
self.view.expand_row(row.get_path(), False)
|
||||
self.view.get_selection().select_path(row.get_path())
|
||||
|
||||
def run(self, window):
|
||||
if self.dialog == None:
|
||||
self.build()
|
||||
|
||||
# Open up language
|
||||
self.expand_from_doc(window.get_active_document())
|
||||
|
||||
self.dialog.set_transient_for(window)
|
||||
window.get_group().add_window(self.dialog)
|
||||
self.dialog.present()
|
||||
|
||||
def add_accelerator(self, item):
|
||||
if not item.shortcut:
|
||||
return
|
||||
|
||||
if item.shortcut in self.accelerators:
|
||||
if not item in self.accelerators[item.shortcut]:
|
||||
self.accelerators[item.shortcut].append(item)
|
||||
else:
|
||||
self.accelerators[item.shortcut] = [item]
|
||||
|
||||
def remove_accelerator(self, item, shortcut=None):
|
||||
if not shortcut:
|
||||
shortcut = item.shortcut
|
||||
|
||||
if not shortcut in self.accelerators:
|
||||
return
|
||||
|
||||
self.accelerators[shortcut].remove(item)
|
||||
|
||||
if not self.accelerators[shortcut]:
|
||||
del self.accelerators[shortcut]
|
||||
|
||||
def add_tool_to_language(self, tool, language):
|
||||
if isinstance(language, gsv.Language):
|
||||
lid = language.get_id()
|
||||
else:
|
||||
lid = language
|
||||
|
||||
if not lid in self._languages:
|
||||
piter = self.model.append(None, [language])
|
||||
|
||||
parent = gtk.TreeRowReference(self.model, self.model.get_path(piter))
|
||||
self._languages[lid] = parent
|
||||
else:
|
||||
parent = self._languages[lid]
|
||||
|
||||
piter = self.model.get_iter(parent.get_path())
|
||||
child = self.model.append(piter, [tool])
|
||||
|
||||
if not tool in self._tool_rows:
|
||||
self._tool_rows[tool] = []
|
||||
|
||||
self._tool_rows[tool].append(gtk.TreeRowReference(self.model, self.model.get_path(child)))
|
||||
return child
|
||||
|
||||
def add_tool(self, tool):
|
||||
manager = gsv.LanguageManager()
|
||||
ret = None
|
||||
|
||||
for lang in tool.languages:
|
||||
l = manager.get_language(lang)
|
||||
|
||||
if l:
|
||||
ret = self.add_tool_to_language(tool, l)
|
||||
elif lang == 'plain':
|
||||
ret = self.add_tool_to_language(tool, 'plain')
|
||||
|
||||
if not ret:
|
||||
ret = self.add_tool_to_language(tool, None)
|
||||
|
||||
self.add_accelerator(tool)
|
||||
return ret
|
||||
|
||||
def __init_tools_model(self):
|
||||
self.tools = ToolLibrary()
|
||||
self.current_node = None
|
||||
self.script_hash = None
|
||||
self.accelerators = dict()
|
||||
|
||||
self.model = gtk.TreeStore(object)
|
||||
self.view.set_model(self.model)
|
||||
|
||||
for tool in self.tools.tree.tools:
|
||||
self.add_tool(tool)
|
||||
|
||||
self.model.set_default_sort_func(self.sort_tools)
|
||||
self.model.set_sort_column_id(-1, gtk.SORT_ASCENDING)
|
||||
|
||||
def sort_tools(self, model, iter1, iter2):
|
||||
# For languages, sort All before everything else, otherwise alphabetical
|
||||
t1 = model.get_value(iter1, self.TOOL_COLUMN)
|
||||
t2 = model.get_value(iter2, self.TOOL_COLUMN)
|
||||
|
||||
if model.iter_parent(iter1) == None:
|
||||
if t1 == None:
|
||||
return -1
|
||||
|
||||
if t2 == None:
|
||||
return 1
|
||||
|
||||
def lang_name(lang):
|
||||
if isinstance(lang, gsv.Language):
|
||||
return lang.get_name()
|
||||
else:
|
||||
return _('Plain Text')
|
||||
|
||||
n1 = lang_name(t1)
|
||||
n2 = lang_name(t2)
|
||||
else:
|
||||
n1 = t1.name
|
||||
n2 = t2.name
|
||||
|
||||
return cmp(n1.lower(), n2.lower())
|
||||
|
||||
def __init_tools_view(self):
|
||||
# Tools column
|
||||
column = gtk.TreeViewColumn('Tools')
|
||||
renderer = gtk.CellRendererText()
|
||||
column.pack_start(renderer, False)
|
||||
renderer.set_property('editable', True)
|
||||
self.view.append_column(column)
|
||||
|
||||
column.set_cell_data_func(renderer, self.get_cell_data_cb)
|
||||
|
||||
renderer.connect('edited', self.on_view_label_cell_edited)
|
||||
renderer.connect('editing-started', self.on_view_label_cell_editing_started)
|
||||
|
||||
self.selection_changed_id = self.view.get_selection().connect('changed', self.on_view_selection_changed, None)
|
||||
|
||||
def __init_combobox(self, name):
|
||||
combo = self[name]
|
||||
combo.set_active(0)
|
||||
|
||||
# Convenience function to get an object from its name
|
||||
def __getitem__(self, key):
|
||||
return self.ui.get_object(key)
|
||||
|
||||
def set_active_by_name(self, combo_name, option_name):
|
||||
combo = self[combo_name]
|
||||
model = combo.get_model()
|
||||
piter = model.get_iter_first()
|
||||
while piter is not None:
|
||||
if model.get_value(piter, self.NAME_COLUMN) == option_name:
|
||||
combo.set_active_iter(piter)
|
||||
return True
|
||||
piter = model.iter_next(piter)
|
||||
return False
|
||||
|
||||
def get_selected_tool(self):
|
||||
model, piter = self.view.get_selection().get_selected()
|
||||
|
||||
if piter is not None:
|
||||
tool = model.get_value(piter, self.TOOL_COLUMN)
|
||||
|
||||
if not isinstance(tool, Tool):
|
||||
tool = None
|
||||
|
||||
return piter, tool
|
||||
else:
|
||||
return None, None
|
||||
|
||||
def compute_hash(self, string):
|
||||
return hashlib.md5(string).hexdigest()
|
||||
|
||||
def save_current_tool(self):
|
||||
if self.current_node is None:
|
||||
return
|
||||
|
||||
if self.current_node.filename is None:
|
||||
self.current_node.autoset_filename()
|
||||
|
||||
def combo_value(o, name):
|
||||
combo = o[name]
|
||||
return combo.get_model().get_value(combo.get_active_iter(), self.NAME_COLUMN)
|
||||
|
||||
self.current_node.input = combo_value(self, 'input')
|
||||
self.current_node.output = combo_value(self, 'output')
|
||||
self.current_node.applicability = combo_value(self, 'applicability')
|
||||
self.current_node.save_files = combo_value(self, 'save-files')
|
||||
|
||||
buf = self['commands'].get_buffer()
|
||||
script = buf.get_text(*buf.get_bounds())
|
||||
h = self.compute_hash(script)
|
||||
if h != self.script_hash:
|
||||
# script has changed -> save it
|
||||
self.current_node.save_with_script([line + "\n" for line in script.splitlines()])
|
||||
self.script_hash = h
|
||||
else:
|
||||
self.current_node.save()
|
||||
|
||||
self.update_remove_revert()
|
||||
|
||||
def clear_fields(self):
|
||||
self['accelerator'].set_text('')
|
||||
|
||||
buf = self['commands'].get_buffer()
|
||||
buf.begin_not_undoable_action()
|
||||
buf.set_text('')
|
||||
buf.end_not_undoable_action()
|
||||
|
||||
for nm in ('input', 'output', 'applicability', 'save-files'):
|
||||
self[nm].set_active(0)
|
||||
|
||||
self['languages_label'].set_text(_('All Languages'))
|
||||
|
||||
def fill_languages_button(self):
|
||||
if not self.current_node or not self.current_node.languages:
|
||||
self['languages_label'].set_text(_('All Languages'))
|
||||
else:
|
||||
manager = gsv.LanguageManager()
|
||||
langs = []
|
||||
|
||||
for lang in self.current_node.languages:
|
||||
if lang == 'plain':
|
||||
langs.append(_('Plain Text'))
|
||||
else:
|
||||
l = manager.get_language(lang)
|
||||
|
||||
if l:
|
||||
langs.append(l.get_name())
|
||||
|
||||
self['languages_label'].set_text(', '.join(langs))
|
||||
|
||||
def fill_fields(self):
|
||||
node = self.current_node
|
||||
self['accelerator'].set_text(default(node.shortcut, ''))
|
||||
|
||||
buf = self['commands'].get_buffer()
|
||||
script = default(''.join(node.get_script()), '')
|
||||
|
||||
buf.begin_not_undoable_action()
|
||||
buf.set_text(script)
|
||||
buf.end_not_undoable_action()
|
||||
|
||||
self.script_hash = self.compute_hash(script)
|
||||
contenttype = gio.content_type_guess(data=script)
|
||||
lmanager = gedit.get_language_manager()
|
||||
language = lmanager.guess_language(content_type=contenttype)
|
||||
|
||||
if language is not None:
|
||||
buf.set_language(language)
|
||||
buf.set_highlight_syntax(True)
|
||||
else:
|
||||
buf.set_highlight_syntax(False)
|
||||
|
||||
for nm in ('input', 'output', 'applicability', 'save-files'):
|
||||
model = self[nm].get_model()
|
||||
piter = model.get_iter_first()
|
||||
|
||||
self.set_active_by_name(nm,
|
||||
default(node.__getattribute__(nm.replace('-', '_')),
|
||||
model.get_value(piter, self.NAME_COLUMN)))
|
||||
|
||||
self.fill_languages_button()
|
||||
|
||||
def update_remove_revert(self):
|
||||
piter, node = self.get_selected_tool()
|
||||
|
||||
removable = node is not None and node.is_local()
|
||||
|
||||
self['remove-tool-button'].set_sensitive(removable)
|
||||
self['revert-tool-button'].set_sensitive(removable)
|
||||
|
||||
if node is not None and node.is_global():
|
||||
self['remove-tool-button'].hide()
|
||||
self['revert-tool-button'].show()
|
||||
else:
|
||||
self['remove-tool-button'].show()
|
||||
self['revert-tool-button'].hide()
|
||||
|
||||
def do_update(self):
|
||||
self.update_remove_revert()
|
||||
|
||||
piter, node = self.get_selected_tool()
|
||||
self.current_node = node
|
||||
|
||||
if node is not None:
|
||||
self.fill_fields()
|
||||
self['tool-table'].set_sensitive(True)
|
||||
else:
|
||||
self.clear_fields()
|
||||
self['tool-table'].set_sensitive(False)
|
||||
|
||||
def language_id_from_iter(self, piter):
|
||||
if not piter:
|
||||
return None
|
||||
|
||||
tool = self.model.get_value(piter, self.TOOL_COLUMN)
|
||||
|
||||
if isinstance(tool, Tool):
|
||||
piter = self.model.iter_parent(piter)
|
||||
tool = self.model.get_value(piter, self.TOOL_COLUMN)
|
||||
|
||||
if isinstance(tool, gsv.Language):
|
||||
return tool.get_id()
|
||||
elif tool:
|
||||
return 'plain'
|
||||
|
||||
return None
|
||||
|
||||
def selected_language_id(self):
|
||||
# Find current language if there is any
|
||||
model, piter = self.view.get_selection().get_selected()
|
||||
|
||||
return self.language_id_from_iter(piter)
|
||||
|
||||
def on_new_tool_button_clicked(self, button):
|
||||
self.save_current_tool()
|
||||
|
||||
# block handlers while inserting a new item
|
||||
self.view.get_selection().handler_block(self.selection_changed_id)
|
||||
|
||||
self.current_node = Tool(self.tools.tree);
|
||||
self.current_node.name = _('New tool')
|
||||
self.tools.tree.tools.append(self.current_node)
|
||||
|
||||
lang = self.selected_language_id()
|
||||
|
||||
if lang:
|
||||
self.current_node.languages = [lang]
|
||||
|
||||
piter = self.add_tool(self.current_node)
|
||||
|
||||
self.view.set_cursor(self.model.get_path(piter), self.view.get_column(self.TOOL_COLUMN), True)
|
||||
self.fill_fields()
|
||||
|
||||
self['tool-table'].set_sensitive(True)
|
||||
self.view.get_selection().handler_unblock(self.selection_changed_id)
|
||||
|
||||
def tool_changed(self, tool, refresh=False):
|
||||
for row in self._tool_rows[tool]:
|
||||
self.model.row_changed(row.get_path(), self.model.get_iter(row.get_path()))
|
||||
|
||||
if refresh and tool == self.current_node:
|
||||
self.fill_fields()
|
||||
|
||||
self.update_remove_revert()
|
||||
|
||||
def on_remove_tool_button_clicked(self, button):
|
||||
piter, node = self.get_selected_tool()
|
||||
|
||||
if not node:
|
||||
return
|
||||
|
||||
if node.is_global():
|
||||
shortcut = node.shortcut
|
||||
|
||||
if node.parent.revert_tool(node):
|
||||
self.remove_accelerator(node, shortcut)
|
||||
self.add_accelerator(node)
|
||||
|
||||
self['revert-tool-button'].set_sensitive(False)
|
||||
self.fill_fields()
|
||||
|
||||
self.tool_changed(node)
|
||||
else:
|
||||
parent = self.model.iter_parent(piter)
|
||||
language = self.language_id_from_iter(parent)
|
||||
|
||||
self.model.remove(piter)
|
||||
|
||||
if language in node.languages:
|
||||
node.languages.remove(language)
|
||||
|
||||
self._tool_rows[node] = filter(lambda x: x.valid(), self._tool_rows[node])
|
||||
|
||||
if not self._tool_rows[node]:
|
||||
del self._tool_rows[node]
|
||||
|
||||
if node.parent.delete_tool(node):
|
||||
self.remove_accelerator(node)
|
||||
self.current_node = None
|
||||
self.script_hash = None
|
||||
|
||||
if self.model.iter_is_valid(piter):
|
||||
self.view.set_cursor(self.model.get_path(piter), self.view.get_column(self.TOOL_COLUMN), False)
|
||||
|
||||
self.view.grab_focus()
|
||||
|
||||
path = self._languages[language].get_path()
|
||||
parent = self.model.get_iter(path)
|
||||
|
||||
if not self.model.iter_has_child(parent):
|
||||
self.model.remove(parent)
|
||||
del self._languages[language]
|
||||
|
||||
def on_view_label_cell_edited(self, cell, path, new_text):
|
||||
if new_text != '':
|
||||
piter = self.model.get_iter(path)
|
||||
tool = self.model.get_value(piter, self.TOOL_COLUMN)
|
||||
|
||||
tool.name = new_text
|
||||
|
||||
self.save_current_tool()
|
||||
self.tool_changed(tool)
|
||||
|
||||
def on_view_label_cell_editing_started(self, renderer, editable, path):
|
||||
piter = self.model.get_iter(path)
|
||||
tool = self.model.get_value(piter, self.TOOL_COLUMN)
|
||||
|
||||
if isinstance(editable, gtk.Entry):
|
||||
editable.set_text(tool.name)
|
||||
editable.grab_focus()
|
||||
|
||||
def on_view_selection_changed(self, selection, userdata):
|
||||
self.save_current_tool()
|
||||
self.do_update()
|
||||
|
||||
def accelerator_collision(self, name, node):
|
||||
if not name in self.accelerators:
|
||||
return []
|
||||
|
||||
ret = []
|
||||
|
||||
for other in self.accelerators[name]:
|
||||
if not other.languages or not node.languages:
|
||||
ret.append(other)
|
||||
continue
|
||||
|
||||
for lang in other.languages:
|
||||
if lang in node.languages:
|
||||
ret.append(other)
|
||||
continue
|
||||
|
||||
return ret
|
||||
|
||||
def set_accelerator(self, keyval, mod):
|
||||
# Check whether accelerator already exists
|
||||
self.remove_accelerator(self.current_node)
|
||||
|
||||
name = gtk.accelerator_name(keyval, mod)
|
||||
|
||||
if name == '':
|
||||
self.current_node.shorcut = None
|
||||
self.save_current_tool()
|
||||
return True
|
||||
|
||||
col = self.accelerator_collision(name, self.current_node)
|
||||
|
||||
if col:
|
||||
dialog = gtk.MessageDialog(self.dialog,
|
||||
gtk.DIALOG_MODAL,
|
||||
gtk.MESSAGE_ERROR,
|
||||
gtk.BUTTONS_OK,
|
||||
_('This accelerator is already bound to %s') % (', '.join(map(lambda x: x.name, col)),))
|
||||
|
||||
dialog.run()
|
||||
dialog.destroy()
|
||||
|
||||
self.add_accelerator(self.current_node)
|
||||
return False
|
||||
|
||||
self.current_node.shortcut = name
|
||||
self.add_accelerator(self.current_node)
|
||||
self.save_current_tool()
|
||||
|
||||
return True
|
||||
|
||||
def on_accelerator_key_press(self, entry, event):
|
||||
mask = event.state & gtk.accelerator_get_default_mod_mask()
|
||||
|
||||
if event.keyval == gtk.keysyms.Escape:
|
||||
entry.set_text(default(self.current_node.shortcut, ''))
|
||||
self['commands'].grab_focus()
|
||||
return True
|
||||
elif event.keyval == gtk.keysyms.Delete \
|
||||
or event.keyval == gtk.keysyms.BackSpace:
|
||||
entry.set_text('')
|
||||
self.remove_accelerator(self.current_node)
|
||||
self.current_node.shortcut = None
|
||||
self['commands'].grab_focus()
|
||||
return True
|
||||
elif event.keyval in range(gtk.keysyms.F1, gtk.keysyms.F12 + 1):
|
||||
# New accelerator
|
||||
if self.set_accelerator(event.keyval, mask):
|
||||
entry.set_text(default(self.current_node.shortcut, ''))
|
||||
self['commands'].grab_focus()
|
||||
|
||||
# Capture all `normal characters`
|
||||
return True
|
||||
elif gtk.gdk.keyval_to_unicode(event.keyval):
|
||||
if mask:
|
||||
# New accelerator
|
||||
if self.set_accelerator(event.keyval, mask):
|
||||
entry.set_text(default(self.current_node.shortcut, ''))
|
||||
self['commands'].grab_focus()
|
||||
# Capture all `normal characters`
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def on_accelerator_focus_in(self, entry, event):
|
||||
if self.current_node is None:
|
||||
return
|
||||
if self.current_node.shortcut:
|
||||
entry.set_text(_('Type a new accelerator, or press Backspace to clear'))
|
||||
else:
|
||||
entry.set_text(_('Type a new accelerator'))
|
||||
|
||||
def on_accelerator_focus_out(self, entry, event):
|
||||
if self.current_node is not None:
|
||||
entry.set_text(default(self.current_node.shortcut, ''))
|
||||
self.tool_changed(self.current_node)
|
||||
|
||||
def on_tool_manager_dialog_response(self, dialog, response):
|
||||
if response == gtk.RESPONSE_HELP:
|
||||
gedit.help_display(self.dialog, 'gedit', 'gedit-external-tools-plugin')
|
||||
return
|
||||
|
||||
self.on_tool_manager_dialog_focus_out(dialog, None)
|
||||
|
||||
self.dialog.destroy()
|
||||
self.dialog = None
|
||||
self.tools = None
|
||||
|
||||
def on_tool_manager_dialog_focus_out(self, dialog, event):
|
||||
self.save_current_tool()
|
||||
|
||||
for window in gedit.app_get_default().get_windows():
|
||||
helper = window.get_data("ExternalToolsPluginWindowData")
|
||||
helper.menu.update()
|
||||
|
||||
def get_cell_data_cb(self, column, cell, model, piter):
|
||||
tool = model.get_value(piter, self.TOOL_COLUMN)
|
||||
|
||||
if tool == None or not isinstance(tool, Tool):
|
||||
if tool == None:
|
||||
label = _('All Languages')
|
||||
elif not isinstance(tool, gsv.Language):
|
||||
label = _('Plain Text')
|
||||
else:
|
||||
label = tool.get_name()
|
||||
|
||||
markup = saxutils.escape(label)
|
||||
editable = False
|
||||
else:
|
||||
escaped = saxutils.escape(tool.name)
|
||||
|
||||
if tool.shortcut:
|
||||
markup = '%s (<b>%s</b>)' % (escaped, saxutils.escape(tool.shortcut))
|
||||
else:
|
||||
markup = escaped
|
||||
|
||||
editable = True
|
||||
|
||||
cell.set_properties(markup=markup, editable=editable)
|
||||
|
||||
def tool_in_language(self, tool, lang):
|
||||
if not lang in self._languages:
|
||||
return False
|
||||
|
||||
ref = self._languages[lang]
|
||||
parent = ref.get_path()
|
||||
|
||||
for row in self._tool_rows[tool]:
|
||||
path = row.get_path()
|
||||
|
||||
if path[0] == parent[0]:
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def update_languages(self, popup):
|
||||
self.current_node.languages = popup.languages()
|
||||
self.fill_languages_button()
|
||||
|
||||
piter, node = self.get_selected_tool()
|
||||
ret = None
|
||||
|
||||
if node:
|
||||
ref = gtk.TreeRowReference(self.model, self.model.get_path(piter))
|
||||
|
||||
# Update languages, make sure to inhibit selection change stuff
|
||||
self.view.get_selection().handler_block(self.selection_changed_id)
|
||||
|
||||
# Remove all rows that are no longer
|
||||
for row in list(self._tool_rows[self.current_node]):
|
||||
piter = self.model.get_iter(row.get_path())
|
||||
language = self.language_id_from_iter(piter)
|
||||
|
||||
if (not language and not self.current_node.languages) or \
|
||||
(language in self.current_node.languages):
|
||||
continue
|
||||
|
||||
# Remove from language
|
||||
self.model.remove(piter)
|
||||
self._tool_rows[self.current_node].remove(row)
|
||||
|
||||
# If language is empty, remove it
|
||||
parent = self.model.get_iter(self._languages[language].get_path())
|
||||
|
||||
if not self.model.iter_has_child(parent):
|
||||
self.model.remove(parent)
|
||||
del self._languages[language]
|
||||
|
||||
# Now, add for any that are new
|
||||
manager = gsv.LanguageManager()
|
||||
|
||||
for lang in self.current_node.languages:
|
||||
if not self.tool_in_language(self.current_node, lang):
|
||||
l = manager.get_language(lang)
|
||||
|
||||
if not l:
|
||||
l = 'plain'
|
||||
|
||||
self.add_tool_to_language(self.current_node, l)
|
||||
|
||||
if not self.current_node.languages and not self.tool_in_language(self.current_node, None):
|
||||
self.add_tool_to_language(self.current_node, None)
|
||||
|
||||
# Check if we can still keep the current
|
||||
if not ref or not ref.valid():
|
||||
# Change selection to first language
|
||||
path = self._tool_rows[self.current_node][0].get_path()
|
||||
piter = self.model.get_iter(path)
|
||||
parent = self.model.iter_parent(piter)
|
||||
|
||||
# Expand parent, select child and scroll to it
|
||||
self.view.expand_row(self.model.get_path(parent), False)
|
||||
self.view.get_selection().select_path(path)
|
||||
self.view.set_cursor(path, self.view.get_column(self.TOOL_COLUMN), False)
|
||||
|
||||
self.view.get_selection().handler_unblock(self.selection_changed_id)
|
||||
|
||||
def on_languages_button_clicked(self, button):
|
||||
popup = LanguagesPopup(self.current_node.languages)
|
||||
popup.set_transient_for(self.dialog)
|
||||
|
||||
origin = button.window.get_origin()
|
||||
popup.move(origin[0], origin[1] - popup.allocation.height)
|
||||
|
||||
popup.connect('destroy', self.update_languages)
|
||||
|
||||
# ex:et:ts=4:
|
224
plugins/externaltools/tools/outputpanel.py
Executable file
224
plugins/externaltools/tools/outputpanel.py
Executable file
@@ -0,0 +1,224 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Gedit External Tools plugin
|
||||
# Copyright (C) 2005-2006 Steve Frécinaux <steve@istique.net>
|
||||
# Copyright (C) 2010 Per Arneng <per.arneng@anyplanet.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 2 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, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
__all__ = ('OutputPanel', 'UniqueById')
|
||||
|
||||
import gtk, gedit
|
||||
import pango
|
||||
import gobject
|
||||
import os
|
||||
from weakref import WeakKeyDictionary
|
||||
from capture import *
|
||||
from gtk import gdk
|
||||
import re
|
||||
import gio
|
||||
import linkparsing
|
||||
import filelookup
|
||||
|
||||
class UniqueById:
|
||||
__shared_state = WeakKeyDictionary()
|
||||
|
||||
def __init__(self, i):
|
||||
if i in self.__class__.__shared_state:
|
||||
self.__dict__ = self.__class__.__shared_state[i]
|
||||
return True
|
||||
else:
|
||||
self.__class__.__shared_state[i] = self.__dict__
|
||||
return False
|
||||
|
||||
def states(self):
|
||||
return self.__class__.__shared_state
|
||||
|
||||
class OutputPanel(UniqueById):
|
||||
def __init__(self, datadir, window):
|
||||
if UniqueById.__init__(self, window):
|
||||
return
|
||||
|
||||
callbacks = {
|
||||
'on_stop_clicked' : self.on_stop_clicked,
|
||||
'on_view_visibility_notify_event': self.on_view_visibility_notify_event,
|
||||
'on_view_motion_notify_event': self.on_view_motion_notify_event,
|
||||
'on_view_button_press_event': self.on_view_button_press_event
|
||||
}
|
||||
|
||||
self.window = window
|
||||
self.ui = gtk.Builder()
|
||||
self.ui.add_from_file(os.path.join(datadir, 'ui', 'outputpanel.ui'))
|
||||
self.ui.connect_signals(callbacks)
|
||||
|
||||
self.panel = self["output-panel"]
|
||||
self['view'].modify_font(pango.FontDescription('Monospace'))
|
||||
|
||||
buffer = self['view'].get_buffer()
|
||||
|
||||
self.normal_tag = buffer.create_tag('normal')
|
||||
|
||||
self.error_tag = buffer.create_tag('error')
|
||||
self.error_tag.set_property('foreground', 'red')
|
||||
|
||||
self.italic_tag = buffer.create_tag('italic')
|
||||
self.italic_tag.set_property('style', pango.STYLE_OBLIQUE)
|
||||
|
||||
self.bold_tag = buffer.create_tag('bold')
|
||||
self.bold_tag.set_property('weight', pango.WEIGHT_BOLD)
|
||||
|
||||
self.invalid_link_tag = buffer.create_tag('invalid_link')
|
||||
|
||||
self.link_tag = buffer.create_tag('link')
|
||||
self.link_tag.set_property('underline', pango.UNDERLINE_SINGLE)
|
||||
|
||||
self.link_cursor = gdk.Cursor(gdk.HAND2)
|
||||
self.normal_cursor = gdk.Cursor(gdk.XTERM)
|
||||
|
||||
self.process = None
|
||||
|
||||
self.links = []
|
||||
|
||||
self.link_parser = linkparsing.LinkParser()
|
||||
self.file_lookup = filelookup.FileLookup()
|
||||
|
||||
def set_process(self, process):
|
||||
self.process = process
|
||||
|
||||
def __getitem__(self, key):
|
||||
# Convenience function to get an object from its name
|
||||
return self.ui.get_object(key)
|
||||
|
||||
def on_stop_clicked(self, widget, *args):
|
||||
if self.process is not None:
|
||||
self.write("\n" + _('Stopped.') + "\n",
|
||||
self.italic_tag)
|
||||
self.process.stop(-1)
|
||||
|
||||
def scroll_to_end(self):
|
||||
iter = self['view'].get_buffer().get_end_iter()
|
||||
self['view'].scroll_to_iter(iter, 0.0)
|
||||
return False # don't requeue this handler
|
||||
|
||||
def clear(self):
|
||||
self['view'].get_buffer().set_text("")
|
||||
self.links = []
|
||||
|
||||
def visible(self):
|
||||
panel = self.window.get_bottom_panel()
|
||||
return panel.props.visible and panel.item_is_active(self.panel)
|
||||
|
||||
def write(self, text, tag = None):
|
||||
buffer = self['view'].get_buffer()
|
||||
|
||||
end_iter = buffer.get_end_iter()
|
||||
insert = buffer.create_mark(None, end_iter, True)
|
||||
|
||||
if tag is None:
|
||||
buffer.insert(end_iter, text)
|
||||
else:
|
||||
buffer.insert_with_tags(end_iter, text, tag)
|
||||
|
||||
# find all links and apply the appropriate tag for them
|
||||
links = self.link_parser.parse(text)
|
||||
for lnk in links:
|
||||
|
||||
insert_iter = buffer.get_iter_at_mark(insert)
|
||||
lnk.start = insert_iter.get_offset() + lnk.start
|
||||
lnk.end = insert_iter.get_offset() + lnk.end
|
||||
|
||||
start_iter = buffer.get_iter_at_offset(lnk.start)
|
||||
end_iter = buffer.get_iter_at_offset(lnk.end)
|
||||
|
||||
tag = None
|
||||
|
||||
# if the link points to an existing file then it is a valid link
|
||||
if self.file_lookup.lookup(lnk.path) is not None:
|
||||
self.links.append(lnk)
|
||||
tag = self.link_tag
|
||||
else:
|
||||
tag = self.invalid_link_tag
|
||||
|
||||
buffer.apply_tag(tag, start_iter, end_iter)
|
||||
|
||||
buffer.delete_mark(insert)
|
||||
gobject.idle_add(self.scroll_to_end)
|
||||
|
||||
def show(self):
|
||||
panel = self.window.get_bottom_panel()
|
||||
panel.show()
|
||||
panel.activate_item(self.panel)
|
||||
|
||||
def update_cursor_style(self, view, x, y):
|
||||
if self.get_link_at_location(view, x, y) is not None:
|
||||
cursor = self.link_cursor
|
||||
else:
|
||||
cursor = self.normal_cursor
|
||||
|
||||
view.get_window(gtk.TEXT_WINDOW_TEXT).set_cursor(cursor)
|
||||
|
||||
def on_view_motion_notify_event(self, view, event):
|
||||
if event.window == view.get_window(gtk.TEXT_WINDOW_TEXT):
|
||||
self.update_cursor_style(view, int(event.x), int(event.y))
|
||||
|
||||
return False
|
||||
|
||||
def on_view_visibility_notify_event(self, view, event):
|
||||
if event.window == view.get_window(gtk.TEXT_WINDOW_TEXT):
|
||||
x, y, m = event.window.get_pointer()
|
||||
self.update_cursor_style(view, x, y)
|
||||
|
||||
return False
|
||||
|
||||
def idle_grab_focus(self):
|
||||
self.window.get_active_view().grab_focus()
|
||||
return False
|
||||
|
||||
def get_link_at_location(self, view, x, y):
|
||||
"""
|
||||
Get the link under a specified x,y coordinate. If no link exists then
|
||||
None is returned.
|
||||
"""
|
||||
|
||||
# get the offset within the buffer from the x,y coordinates
|
||||
buff_x, buff_y = view.window_to_buffer_coords(gtk.TEXT_WINDOW_TEXT,
|
||||
x, y)
|
||||
iter_at_xy = view.get_iter_at_location(buff_x, buff_y)
|
||||
offset = iter_at_xy.get_offset()
|
||||
|
||||
# find the first link that contains the offset
|
||||
for lnk in self.links:
|
||||
if offset >= lnk.start and offset <= lnk.end:
|
||||
return lnk
|
||||
|
||||
# no link was found at x,y
|
||||
return None
|
||||
|
||||
def on_view_button_press_event(self, view, event):
|
||||
if event.button != 1 or event.type != gdk.BUTTON_PRESS or \
|
||||
event.window != view.get_window(gtk.TEXT_WINDOW_TEXT):
|
||||
return False
|
||||
|
||||
link = self.get_link_at_location(view, int(event.x), int(event.y))
|
||||
if link is None:
|
||||
return False
|
||||
|
||||
gfile = self.file_lookup.lookup(link.path)
|
||||
|
||||
if gfile:
|
||||
gedit.commands.load_uri(self.window, gfile.get_uri(), None,
|
||||
link.line_nr)
|
||||
gobject.idle_add(self.idle_grab_focus)
|
||||
|
||||
# ex:ts=4:et:
|
53
plugins/externaltools/tools/outputpanel.ui
Executable file
53
plugins/externaltools/tools/outputpanel.ui
Executable file
@@ -0,0 +1,53 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- Generated with glade3
|
||||
Version: 2.91.3
|
||||
Date: Sat Nov 18 13:58:59 2006
|
||||
User: sf
|
||||
Host: antea
|
||||
-->
|
||||
<interface>
|
||||
<object class="GtkHBox" id="output-panel">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="scrolledwindow1">
|
||||
<property name="visible">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>
|
||||
<object class="GtkTextView" id="view">
|
||||
<property name="visible">True</property>
|
||||
<property name="editable">False</property>
|
||||
<property name="wrap_mode">GTK_WRAP_WORD</property>
|
||||
<property name="cursor_visible">False</property>
|
||||
<property name="accepts_tab">False</property>
|
||||
<signal name="button_press_event" handler="on_view_button_press_event"/>
|
||||
<signal name="motion_notify_event" handler="on_view_motion_notify_event"/>
|
||||
<signal name="visibility_notify_event" handler="on_view_visibility_notify_event"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkVButtonBox" id="vbuttonbox1">
|
||||
<property name="visible">True</property>
|
||||
<property name="border_width">6</property>
|
||||
<property name="spacing">6</property>
|
||||
<property name="layout_style">GTK_BUTTONBOX_END</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="stop">
|
||||
<property name="visible">True</property>
|
||||
<property name="sensitive">False</property>
|
||||
<property name="label">gtk-stop</property>
|
||||
<property name="use_stock">True</property>
|
||||
<signal handler="on_stop_clicked" name="clicked"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
606
plugins/externaltools/tools/tools.ui
Executable file
606
plugins/externaltools/tools/tools.ui
Executable file
@@ -0,0 +1,606 @@
|
||||
<?xml version="1.0"?>
|
||||
<interface>
|
||||
<object class="GtkListStore" id="model_save_files">
|
||||
<columns>
|
||||
<!-- column-name gchararray -->
|
||||
<column type="gchararray"/>
|
||||
<!-- column-name gchararray -->
|
||||
<column type="gchararray"/>
|
||||
</columns>
|
||||
<data>
|
||||
<row>
|
||||
<col id="0" translatable="yes">Nothing</col>
|
||||
<col id="1">nothing</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0" translatable="yes">Current document</col>
|
||||
<col id="1">document</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0" translatable="yes">All documents</col>
|
||||
<col id="1">all</col>
|
||||
</row>
|
||||
</data>
|
||||
</object>
|
||||
<object class="GtkListStore" id="model_input">
|
||||
<columns>
|
||||
<column type="gchararray"/>
|
||||
<column type="gchararray"/>
|
||||
</columns>
|
||||
<data>
|
||||
<row>
|
||||
<col id="0" translatable="yes">Nothing</col>
|
||||
<col id="1">nothing</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0" translatable="yes">Current document</col>
|
||||
<col id="1">document</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0" translatable="yes">Current selection</col>
|
||||
<col id="1">selection</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0" translatable="yes">Current selection (default to document)</col>
|
||||
<col id="1">selection-document</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0" translatable="yes">Current line</col>
|
||||
<col id="1">line</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0" translatable="yes">Current word</col>
|
||||
<col id="1">word</col>
|
||||
</row>
|
||||
</data>
|
||||
</object>
|
||||
<object class="GtkListStore" id="model_output">
|
||||
<columns>
|
||||
<!-- column-name gchararray -->
|
||||
<column type="gchararray"/>
|
||||
<!-- column-name gchararray1 -->
|
||||
<column type="gchararray"/>
|
||||
</columns>
|
||||
<data>
|
||||
<row>
|
||||
<col id="0" translatable="yes">Nothing</col>
|
||||
<col id="1">nothing</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0" translatable="yes">Display in bottom pane</col>
|
||||
<col id="1">output-panel</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0" translatable="yes">Create new document</col>
|
||||
<col id="1">new-document</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0" translatable="yes">Append to current document</col>
|
||||
<col id="1">append-document</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0" translatable="yes">Replace current document</col>
|
||||
<col id="1">replace-document</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0" translatable="yes">Replace current selection</col>
|
||||
<col id="1">replace-selection</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0" translatable="yes">Insert at cursor position</col>
|
||||
<col id="1">insert</col>
|
||||
</row>
|
||||
</data>
|
||||
</object>
|
||||
<object class="GtkListStore" id="model_applicability">
|
||||
<columns>
|
||||
<!-- column-name gchararray -->
|
||||
<column type="gchararray"/>
|
||||
<!-- column-name gchararray1 -->
|
||||
<column type="gchararray"/>
|
||||
</columns>
|
||||
<data>
|
||||
<row>
|
||||
<col id="0" translatable="yes">All documents</col>
|
||||
<col id="1">all</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0" translatable="yes">All documents except untitled ones</col>
|
||||
<col id="1">titled</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0" translatable="yes">Local files only</col>
|
||||
<col id="1">local</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0" translatable="yes">Remote files only</col>
|
||||
<col id="1">remote</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0" translatable="yes">Untitled documents only</col>
|
||||
<col id="1">untitled</col>
|
||||
</row>
|
||||
</data>
|
||||
</object>
|
||||
<object class="GeditDocument" id="commands_buffer">
|
||||
<property name="highlight-matching-brackets">True</property>
|
||||
</object>
|
||||
<object class="GtkDialog" id="tool-manager-dialog">
|
||||
<property name="title" translatable="yes">External Tools Manager</property>
|
||||
<property name="default_width">750</property>
|
||||
<property name="default_height">500</property>
|
||||
<property name="type_hint">dialog</property>
|
||||
<property name="skip_taskbar_hint">True</property>
|
||||
<property name="has_separator">False</property>
|
||||
<signal name="focus_out_event" handler="on_tool_manager_dialog_focus_out"/>
|
||||
<signal name="response" handler="on_tool_manager_dialog_response"/>
|
||||
<child internal-child="vbox">
|
||||
<object class="GtkVBox" id="tool-manager-dialog-vbox">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<object class="GtkHPaned" id="paned">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="border_width">6</property>
|
||||
<property name="position">275</property>
|
||||
<child>
|
||||
<object class="GtkVBox" id="vbox2">
|
||||
<property name="visible">True</property>
|
||||
<property name="spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label20">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">_Tools:</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="mnemonic_widget">view</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="scrolled_window1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="hscrollbar_policy">automatic</property>
|
||||
<property name="vscrollbar_policy">automatic</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<child>
|
||||
<object class="GtkTreeView" id="view">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="headers_visible">False</property>
|
||||
<property name="reorderable">True</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkHBox" id="hbox2">
|
||||
<property name="visible">True</property>
|
||||
<property name="spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="new-tool-button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<signal name="clicked" handler="on_new_tool_button_clicked"/>
|
||||
<child>
|
||||
<object class="GtkImage" id="new-tool-image">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-new</property>
|
||||
<property name="icon-size">4</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="revert-tool-button">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="receives_default">False</property>
|
||||
<signal name="clicked" handler="on_remove_tool_button_clicked"/>
|
||||
<child>
|
||||
<object class="GtkImage" id="revert-tool-image">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-revert-to-saved</property>
|
||||
<property name="icon-size">4</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="pack_type">end</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="remove-tool-button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<signal name="clicked" handler="on_remove_tool_button_clicked"/>
|
||||
<child>
|
||||
<object class="GtkImage" id="remove-tool-image">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-delete</property>
|
||||
<property name="icon-size">4</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="pack_type">end</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="resize">False</property>
|
||||
<property name="shrink">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkVBox" id="vbox5">
|
||||
<property name="visible">True</property>
|
||||
<property name="spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="title">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="label" translatable="yes">_Edit:</property>
|
||||
<property name="mnemonic_widget">commands</property>
|
||||
<property name="use_underline">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkHBox" id="hbox7">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label22">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes"> </property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTable" id="tool-table">
|
||||
<property name="visible">True</property>
|
||||
<property name="n_rows">6</property>
|
||||
<property name="n_columns">2</property>
|
||||
<property name="column_spacing">6</property>
|
||||
<property name="row_spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkEntry" id="accelerator">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<signal name="key_press_event" handler="on_accelerator_key_press"/>
|
||||
<signal name="focus_out_event" handler="on_accelerator_focus_out"/>
|
||||
<signal name="focus_in_event" handler="on_accelerator_focus_in"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="bottom_attach">2</property>
|
||||
<property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
|
||||
<property name="y_options">GTK_FILL</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkHBox" id="hbox1">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<object class="GtkComboBox" id="applicability">
|
||||
<property name="visible">True</property>
|
||||
<property name="model">model_applicability</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText" id="applicability_renderer"/>
|
||||
<attributes>
|
||||
<attribute name="text">0</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEventBox" id="languages_event_box">
|
||||
<property name="visible">True</property>
|
||||
<property name="visible-window">True</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="languages_button">
|
||||
<property name="visible">True</property>
|
||||
<signal name="clicked" handler="on_languages_button_clicked"/>
|
||||
<child>
|
||||
<object class="GtkLabel" id="languages_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">All Languages</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="ellipsize">PANGO_ELLIPSIZE_MIDDLE</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">5</property>
|
||||
<property name="bottom_attach">6</property>
|
||||
<property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
|
||||
<property name="y_options">GTK_FILL</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkComboBox" id="output">
|
||||
<property name="visible">True</property>
|
||||
<property name="model">model_output</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText" id="output_renderer"/>
|
||||
<attributes>
|
||||
<attribute name="text">0</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">4</property>
|
||||
<property name="bottom_attach">5</property>
|
||||
<property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
|
||||
<property name="y_options">GTK_FILL</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkComboBox" id="input">
|
||||
<property name="visible">True</property>
|
||||
<property name="model">model_input</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText" id="input_renderer"/>
|
||||
<attributes>
|
||||
<attribute name="text">0</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">3</property>
|
||||
<property name="bottom_attach">4</property>
|
||||
<property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
|
||||
<property name="y_options">GTK_FILL</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkComboBox" id="save-files">
|
||||
<property name="model">model_save_files</property>
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText" id="renderer1"/>
|
||||
<attributes>
|
||||
<attribute name="text">0</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">2</property>
|
||||
<property name="bottom_attach">3</property>
|
||||
<property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
|
||||
<property name="y_options">GTK_FILL</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label23">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">_Applicability:</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="mnemonic_widget">applicability</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="top_attach">5</property>
|
||||
<property name="bottom_attach">6</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label8">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">_Output:</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="mnemonic_widget">output</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="top_attach">4</property>
|
||||
<property name="bottom_attach">5</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label7">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">_Input:</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="mnemonic_widget">input</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="top_attach">3</property>
|
||||
<property name="bottom_attach">4</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label6">
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">_Save:</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="mnemonic_widget">save-files</property>
|
||||
<property name="visible">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="top_attach">2</property>
|
||||
<property name="bottom_attach">3</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label3">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">_Shortcut Key:</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="mnemonic_widget">accelerator</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="bottom_attach">2</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="scrolledwindow1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="hscrollbar_policy">automatic</property>
|
||||
<property name="vscrollbar_policy">automatic</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<child>
|
||||
<object class="GeditView" id="commands">
|
||||
<property name="buffer">commands_buffer</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="auto-indent">True</property>
|
||||
<property name="insert-spaces-instead-of-tabs">False</property>
|
||||
<property name="smart-home-end">GTK_SOURCE_SMART_HOME_END_AFTER</property>
|
||||
<property name="tab-width">2</property>
|
||||
<property name="highlight-current-line">True</property>
|
||||
<property name="show-right-margin">False</property>
|
||||
<property name="show-line-numbers">True</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="right_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="resize">True</property>
|
||||
<property name="shrink">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child internal-child="action_area">
|
||||
<object class="GtkHButtonBox" id="hbuttonbox1">
|
||||
<property name="visible">True</property>
|
||||
<property name="layout_style">end</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="button1">
|
||||
<property name="label">gtk-help</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="use_stock">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="button2">
|
||||
<property name="label">gtk-close</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="use_stock">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="pack_type">end</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<action-widgets>
|
||||
<action-widget response="-11">button1</action-widget>
|
||||
<action-widget response="-7">button2</action-widget>
|
||||
</action-widgets>
|
||||
</object>
|
||||
</interface>
|
104
plugins/filebrowser/Makefile.am
Executable file
104
plugins/filebrowser/Makefile.am
Executable file
@@ -0,0 +1,104 @@
|
||||
# filebrowser
|
||||
|
||||
plugindir = $(GEDIT_PLUGINS_LIBS_DIR)
|
||||
|
||||
INCLUDES = \
|
||||
-I$(top_srcdir) \
|
||||
$(GEDIT_CFLAGS) \
|
||||
$(WARN_CFLAGS) \
|
||||
$(DISABLE_DEPRECATED_CFLAGS)
|
||||
|
||||
BUILT_SOURCES = \
|
||||
gedit-file-browser-enum-types.h \
|
||||
gedit-file-browser-enum-types.c \
|
||||
gedit-file-browser-marshal.h \
|
||||
gedit-file-browser-marshal.c
|
||||
|
||||
plugin_LTLIBRARIES = libfilebrowser.la
|
||||
|
||||
NOINST_H_FILES = \
|
||||
gedit-file-bookmarks-store.h \
|
||||
gedit-file-browser-store.h \
|
||||
gedit-file-browser-view.h \
|
||||
gedit-file-browser-widget.h \
|
||||
gedit-file-browser-error.h \
|
||||
gedit-file-browser-utils.h \
|
||||
gedit-file-browser-plugin.h \
|
||||
gedit-file-browser-messages.h
|
||||
|
||||
libfilebrowser_la_SOURCES = \
|
||||
$(BUILT_SOURCES) \
|
||||
gedit-file-bookmarks-store.c \
|
||||
gedit-file-browser-store.c \
|
||||
gedit-file-browser-view.c \
|
||||
gedit-file-browser-widget.c \
|
||||
gedit-file-browser-utils.c \
|
||||
gedit-file-browser-plugin.c \
|
||||
gedit-file-browser-messages.c \
|
||||
$(NOINST_H_FILES)
|
||||
|
||||
libfilebrowser_la_LDFLAGS = $(PLUGIN_LIBTOOL_FLAGS)
|
||||
libfilebrowser_la_LIBADD = $(GEDIT_LIBS)
|
||||
|
||||
# UI files (if you use ui for your plugin, list those files here)
|
||||
uidir = $(GEDIT_PLUGINS_DATA_DIR)/filebrowser
|
||||
ui_DATA = gedit-file-browser-widget-ui.xml
|
||||
|
||||
plugin_in_files = filebrowser.gedit-plugin.desktop.in
|
||||
|
||||
%.gedit-plugin: %.gedit-plugin.desktop.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
|
||||
|
||||
gedit-file-browser-enum-types.h: gedit-file-browser-enum-types.h.template $(NOINST_H_FILES) $(GLIB_MKENUMS)
|
||||
(cd $(srcdir) && $(GLIB_MKENUMS) --template gedit-file-browser-enum-types.h.template $(NOINST_H_FILES)) > $@
|
||||
|
||||
gedit-file-browser-enum-types.c: gedit-file-browser-enum-types.c.template gedit-file-browser-enum-register.c.template $(NOINST_H_FILES) $(GLIB_MKENUMS)
|
||||
$(AM_V_GEN) (cd $(srcdir) && \
|
||||
$(GLIB_MKENUMS) --template gedit-file-browser-enum-types.c.template $(NOINST_H_FILES) && \
|
||||
$(GLIB_MKENUMS) --template gedit-file-browser-enum-register.c.template $(NOINST_H_FILES)) > $@
|
||||
|
||||
gedit-file-browser-marshal.h: gedit-file-browser-marshal.list $(GLIB_GENMARSHAL)
|
||||
$(AM_V_GEN) $(GLIB_GENMARSHAL) $< --header --prefix=gedit_file_browser_marshal > $@
|
||||
|
||||
gedit-file-browser-marshal.c: gedit-file-browser-marshal.list $(GLIB_GENMARSHAL)
|
||||
$(AM_V_GEN) echo "#include \"gedit-file-browser-marshal.h\"" > $@ && \
|
||||
$(GLIB_GENMARSHAL) $< --body --prefix=gedit_file_browser_marshal >> $@
|
||||
|
||||
plugin_DATA = $(plugin_in_files:.gedit-plugin.desktop.in=.gedit-plugin)
|
||||
|
||||
schemasdir = $(MATECONF_SCHEMA_FILE_DIR)
|
||||
schemas_in_files = gedit-file-browser.schemas.in
|
||||
schemas_DATA = $(schemas_in_files:.schemas.in=.schemas)
|
||||
@INTLTOOL_SCHEMAS_RULE@
|
||||
|
||||
if MATECONF_SCHEMAS_INSTALL
|
||||
install-data-local:
|
||||
if test -z "$(DESTDIR)" ; then \
|
||||
for p in $(schemas_DATA) ; do \
|
||||
MATECONF_CONFIG_SOURCE=$(MATECONF_SCHEMA_CONFIG_SOURCE) $(MATECONFTOOL) --makefile-install-rule $(top_builddir)/plugins/filebrowser/$$p ; \
|
||||
done \
|
||||
fi
|
||||
else
|
||||
install-data-local:
|
||||
endif
|
||||
|
||||
|
||||
EXTRA_DIST = \
|
||||
$(ui_DATA) \
|
||||
$(plugin_in_files) \
|
||||
$(schemas_in_files) \
|
||||
gedit-file-browser-enum-types.h.template \
|
||||
gedit-file-browser-enum-types.c.template \
|
||||
gedit-file-browser-enum-register.c.template \
|
||||
gedit-file-browser-marshal.list
|
||||
|
||||
CLEANFILES = \
|
||||
$(plugin_DATA) \
|
||||
$(schemas_DATA) \
|
||||
$(BUILT_SOURCES)
|
||||
|
||||
DISTCLEANFILES = \
|
||||
$(plugin_DATA) \
|
||||
$(schemas_DATA) \
|
||||
$(BUILT_SOURCES)
|
||||
|
||||
-include $(top_srcdir)/git.mk
|
10
plugins/filebrowser/filebrowser.gedit-plugin.desktop.in
Executable file
10
plugins/filebrowser/filebrowser.gedit-plugin.desktop.in
Executable file
@@ -0,0 +1,10 @@
|
||||
[Gedit Plugin]
|
||||
Loader=C
|
||||
Module=filebrowser
|
||||
IAge=2
|
||||
_Name=File Browser Pane
|
||||
_Description=Easy file access from the side pane
|
||||
Icon=system-file-manager
|
||||
Authors=Jesse van den Kieboom <jesse@icecrew.nl>
|
||||
Copyright=Copyright © 2006 Jesse van den Kieboom
|
||||
Website=http://www.gedit.org
|
879
plugins/filebrowser/gedit-file-bookmarks-store.c
Executable file
879
plugins/filebrowser/gedit-file-bookmarks-store.c
Executable file
@@ -0,0 +1,879 @@
|
||||
/*
|
||||
* gedit-file-bookmarks-store.c - Gedit plugin providing easy file access
|
||||
* from the sidepanel
|
||||
*
|
||||
* Copyright (C) 2006 - Jesse van den Kieboom <jesse@icecrew.nl>
|
||||
*
|
||||
* 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 <string.h>
|
||||
#include <glib/gi18n.h>
|
||||
#include <gio/gio.h>
|
||||
#include <gedit/gedit-utils.h>
|
||||
#include <gedit/gedit-plugin.h>
|
||||
|
||||
#include "gedit-file-bookmarks-store.h"
|
||||
#include "gedit-file-browser-utils.h"
|
||||
|
||||
#define GEDIT_FILE_BOOKMARKS_STORE_GET_PRIVATE(object)( \
|
||||
G_TYPE_INSTANCE_GET_PRIVATE((object), GEDIT_TYPE_FILE_BOOKMARKS_STORE, \
|
||||
GeditFileBookmarksStorePrivate))
|
||||
|
||||
struct _GeditFileBookmarksStorePrivate
|
||||
{
|
||||
GVolumeMonitor * volume_monitor;
|
||||
GFileMonitor * bookmarks_monitor;
|
||||
};
|
||||
|
||||
static void remove_node (GtkTreeModel * model,
|
||||
GtkTreeIter * iter);
|
||||
|
||||
static void on_fs_changed (GVolumeMonitor *monitor,
|
||||
GObject *object,
|
||||
GeditFileBookmarksStore *model);
|
||||
|
||||
static void on_bookmarks_file_changed (GFileMonitor * monitor,
|
||||
GFile * file,
|
||||
GFile * other_file,
|
||||
GFileMonitorEvent event_type,
|
||||
GeditFileBookmarksStore * model);
|
||||
static gboolean find_with_flags (GtkTreeModel * model,
|
||||
GtkTreeIter * iter,
|
||||
gpointer obj,
|
||||
guint flags,
|
||||
guint notflags);
|
||||
|
||||
GEDIT_PLUGIN_DEFINE_TYPE(GeditFileBookmarksStore, gedit_file_bookmarks_store, GTK_TYPE_TREE_STORE)
|
||||
|
||||
static void
|
||||
gedit_file_bookmarks_store_dispose (GObject * object)
|
||||
{
|
||||
GeditFileBookmarksStore *obj = GEDIT_FILE_BOOKMARKS_STORE (object);
|
||||
|
||||
if (obj->priv->volume_monitor != NULL) {
|
||||
g_signal_handlers_disconnect_by_func (obj->priv->volume_monitor,
|
||||
on_fs_changed,
|
||||
obj);
|
||||
|
||||
g_object_unref (obj->priv->volume_monitor);
|
||||
obj->priv->volume_monitor = NULL;
|
||||
}
|
||||
|
||||
if (obj->priv->bookmarks_monitor != NULL) {
|
||||
g_object_unref (obj->priv->bookmarks_monitor);
|
||||
obj->priv->bookmarks_monitor = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (gedit_file_bookmarks_store_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gedit_file_bookmarks_store_finalize (GObject * object)
|
||||
{
|
||||
G_OBJECT_CLASS (gedit_file_bookmarks_store_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gedit_file_bookmarks_store_class_init (GeditFileBookmarksStoreClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->dispose = gedit_file_bookmarks_store_dispose;
|
||||
object_class->finalize = gedit_file_bookmarks_store_finalize;
|
||||
|
||||
g_type_class_add_private (object_class, sizeof (GeditFileBookmarksStorePrivate));
|
||||
}
|
||||
|
||||
static void
|
||||
gedit_file_bookmarks_store_init (GeditFileBookmarksStore * obj)
|
||||
{
|
||||
obj->priv = GEDIT_FILE_BOOKMARKS_STORE_GET_PRIVATE (obj);
|
||||
}
|
||||
|
||||
/* Private */
|
||||
static void
|
||||
add_node (GeditFileBookmarksStore *model,
|
||||
GdkPixbuf *pixbuf,
|
||||
const gchar *name,
|
||||
GObject *obj,
|
||||
guint flags,
|
||||
GtkTreeIter *iter)
|
||||
{
|
||||
GtkTreeIter newiter;
|
||||
|
||||
gtk_tree_store_append (GTK_TREE_STORE (model), &newiter, NULL);
|
||||
|
||||
gtk_tree_store_set (GTK_TREE_STORE (model), &newiter,
|
||||
GEDIT_FILE_BOOKMARKS_STORE_COLUMN_ICON, pixbuf,
|
||||
GEDIT_FILE_BOOKMARKS_STORE_COLUMN_NAME, name,
|
||||
GEDIT_FILE_BOOKMARKS_STORE_COLUMN_OBJECT, obj,
|
||||
GEDIT_FILE_BOOKMARKS_STORE_COLUMN_FLAGS, flags,
|
||||
-1);
|
||||
|
||||
if (iter != NULL)
|
||||
*iter = newiter;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
add_file (GeditFileBookmarksStore *model,
|
||||
GFile *file,
|
||||
const gchar *name,
|
||||
guint flags,
|
||||
GtkTreeIter *iter)
|
||||
{
|
||||
GdkPixbuf *pixbuf = NULL;
|
||||
gboolean native;
|
||||
gchar *newname;
|
||||
|
||||
native = g_file_is_native (file);
|
||||
|
||||
if (native && !g_file_query_exists (file, NULL)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (flags & GEDIT_FILE_BOOKMARKS_STORE_IS_HOME)
|
||||
pixbuf = gedit_file_browser_utils_pixbuf_from_theme ("user-home", GTK_ICON_SIZE_MENU);
|
||||
else if (flags & GEDIT_FILE_BOOKMARKS_STORE_IS_DESKTOP)
|
||||
pixbuf = gedit_file_browser_utils_pixbuf_from_theme ("user-desktop", GTK_ICON_SIZE_MENU);
|
||||
else if (flags & GEDIT_FILE_BOOKMARKS_STORE_IS_ROOT)
|
||||
pixbuf = gedit_file_browser_utils_pixbuf_from_theme ("drive-harddisk", GTK_ICON_SIZE_MENU);
|
||||
|
||||
if (pixbuf == NULL) {
|
||||
/* getting the icon is a sync get_info call, so we just do it for local files */
|
||||
if (native) {
|
||||
pixbuf = gedit_file_browser_utils_pixbuf_from_file (file, GTK_ICON_SIZE_MENU);
|
||||
} else {
|
||||
pixbuf = gedit_file_browser_utils_pixbuf_from_theme ("folder", GTK_ICON_SIZE_MENU);
|
||||
}
|
||||
}
|
||||
|
||||
if (name == NULL) {
|
||||
newname = gedit_file_browser_utils_file_basename (file);
|
||||
} else {
|
||||
newname = g_strdup (name);
|
||||
}
|
||||
|
||||
add_node (model, pixbuf, newname, G_OBJECT (file), flags, iter);
|
||||
|
||||
if (pixbuf)
|
||||
g_object_unref (pixbuf);
|
||||
|
||||
g_free (newname);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
check_mount_separator (GeditFileBookmarksStore * model, guint flags,
|
||||
gboolean added)
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
gboolean found;
|
||||
|
||||
found =
|
||||
find_with_flags (GTK_TREE_MODEL (model), &iter, NULL,
|
||||
flags |
|
||||
GEDIT_FILE_BOOKMARKS_STORE_IS_SEPARATOR, 0);
|
||||
|
||||
if (added && !found) {
|
||||
/* Add the separator */
|
||||
add_node (model, NULL, NULL, NULL,
|
||||
flags | GEDIT_FILE_BOOKMARKS_STORE_IS_SEPARATOR,
|
||||
NULL);
|
||||
} else if (!added && found) {
|
||||
remove_node (GTK_TREE_MODEL (model), &iter);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
init_special_directories (GeditFileBookmarksStore * model)
|
||||
{
|
||||
gchar const *path;
|
||||
GFile * file;
|
||||
|
||||
path = g_get_home_dir ();
|
||||
if (path != NULL)
|
||||
{
|
||||
file = g_file_new_for_path (path);
|
||||
add_file (model, file, NULL, GEDIT_FILE_BOOKMARKS_STORE_IS_HOME |
|
||||
GEDIT_FILE_BOOKMARKS_STORE_IS_SPECIAL_DIR, NULL);
|
||||
g_object_unref (file);
|
||||
}
|
||||
|
||||
path = g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP);
|
||||
if (path != NULL)
|
||||
{
|
||||
file = g_file_new_for_path (path);
|
||||
add_file (model, file, NULL, GEDIT_FILE_BOOKMARKS_STORE_IS_DESKTOP |
|
||||
GEDIT_FILE_BOOKMARKS_STORE_IS_SPECIAL_DIR, NULL);
|
||||
g_object_unref (file);
|
||||
}
|
||||
|
||||
path = g_get_user_special_dir (G_USER_DIRECTORY_DOCUMENTS);
|
||||
if (path != NULL)
|
||||
{
|
||||
file = g_file_new_for_path (path);
|
||||
add_file (model, file, NULL, GEDIT_FILE_BOOKMARKS_STORE_IS_DOCUMENTS |
|
||||
GEDIT_FILE_BOOKMARKS_STORE_IS_SPECIAL_DIR, NULL);
|
||||
g_object_unref (file);
|
||||
}
|
||||
|
||||
file = g_file_new_for_uri ("file:///");
|
||||
add_file (model, file, _("File System"), GEDIT_FILE_BOOKMARKS_STORE_IS_ROOT, NULL);
|
||||
g_object_unref (file);
|
||||
|
||||
check_mount_separator (model, GEDIT_FILE_BOOKMARKS_STORE_IS_ROOT, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
get_fs_properties (gpointer fs,
|
||||
gchar **name,
|
||||
GdkPixbuf **pixbuf,
|
||||
guint *flags)
|
||||
{
|
||||
GIcon *icon = NULL;
|
||||
|
||||
*flags = GEDIT_FILE_BOOKMARKS_STORE_IS_FS;
|
||||
*name = NULL;
|
||||
*pixbuf = NULL;
|
||||
|
||||
if (G_IS_DRIVE (fs))
|
||||
{
|
||||
icon = g_drive_get_icon (G_DRIVE (fs));
|
||||
*name = g_drive_get_name (G_DRIVE (fs));
|
||||
|
||||
*flags |= GEDIT_FILE_BOOKMARKS_STORE_IS_DRIVE;
|
||||
}
|
||||
else if (G_IS_VOLUME (fs))
|
||||
{
|
||||
icon = g_volume_get_icon (G_VOLUME (fs));
|
||||
*name = g_volume_get_name (G_VOLUME (fs));
|
||||
|
||||
*flags |= GEDIT_FILE_BOOKMARKS_STORE_IS_VOLUME;
|
||||
}
|
||||
else if (G_IS_MOUNT (fs))
|
||||
{
|
||||
icon = g_mount_get_icon (G_MOUNT (fs));
|
||||
*name = g_mount_get_name (G_MOUNT (fs));
|
||||
|
||||
*flags |= GEDIT_FILE_BOOKMARKS_STORE_IS_MOUNT;
|
||||
}
|
||||
|
||||
if (icon)
|
||||
{
|
||||
*pixbuf = gedit_file_browser_utils_pixbuf_from_icon (icon, GTK_ICON_SIZE_MENU);
|
||||
g_object_unref (icon);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
add_fs (GeditFileBookmarksStore *model,
|
||||
gpointer fs,
|
||||
guint flags,
|
||||
GtkTreeIter *iter)
|
||||
{
|
||||
gchar *name;
|
||||
GdkPixbuf *pixbuf;
|
||||
guint fsflags;
|
||||
|
||||
get_fs_properties (fs, &name, &pixbuf, &fsflags);
|
||||
add_node (model, pixbuf, name, fs, flags | fsflags, iter);
|
||||
|
||||
if (pixbuf)
|
||||
g_object_unref (pixbuf);
|
||||
|
||||
g_free (name);
|
||||
check_mount_separator (model, GEDIT_FILE_BOOKMARKS_STORE_IS_FS, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
process_volume_cb (GVolume *volume,
|
||||
GeditFileBookmarksStore *model)
|
||||
{
|
||||
GMount *mount;
|
||||
guint flags = GEDIT_FILE_BOOKMARKS_STORE_NONE;
|
||||
mount = g_volume_get_mount (volume);
|
||||
|
||||
/* CHECK: should we use the LOCAL/REMOTE thing still? */
|
||||
if (mount)
|
||||
{
|
||||
/* Show mounted volume */
|
||||
add_fs (model, mount, flags, NULL);
|
||||
g_object_unref (mount);
|
||||
}
|
||||
else if (g_volume_can_mount (volume))
|
||||
{
|
||||
/* We also show the unmounted volume here so users can
|
||||
mount it if they want to access it */
|
||||
add_fs (model, volume, flags, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
process_drive_novolumes (GeditFileBookmarksStore *model,
|
||||
GDrive *drive)
|
||||
{
|
||||
if (g_drive_is_media_removable (drive) &&
|
||||
!g_drive_is_media_check_automatic (drive) &&
|
||||
g_drive_can_poll_for_media (drive))
|
||||
{
|
||||
/* This can be the case for floppy drives or other
|
||||
drives where media detection fails. We show the
|
||||
drive and poll for media when the user activates
|
||||
it */
|
||||
add_fs (model, drive, GEDIT_FILE_BOOKMARKS_STORE_NONE, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
process_drive_cb (GDrive *drive,
|
||||
GeditFileBookmarksStore *model)
|
||||
{
|
||||
GList *volumes;
|
||||
|
||||
volumes = g_drive_get_volumes (drive);
|
||||
|
||||
if (volumes)
|
||||
{
|
||||
/* Add all volumes for the drive */
|
||||
g_list_foreach (volumes, (GFunc)process_volume_cb, model);
|
||||
g_list_free (volumes);
|
||||
}
|
||||
else
|
||||
{
|
||||
process_drive_novolumes (model, drive);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
init_drives (GeditFileBookmarksStore *model)
|
||||
{
|
||||
GList *drives;
|
||||
|
||||
drives = g_volume_monitor_get_connected_drives (model->priv->volume_monitor);
|
||||
|
||||
g_list_foreach (drives, (GFunc)process_drive_cb, model);
|
||||
g_list_foreach (drives, (GFunc)g_object_unref, NULL);
|
||||
g_list_free (drives);
|
||||
}
|
||||
|
||||
static void
|
||||
process_volume_nodrive_cb (GVolume *volume,
|
||||
GeditFileBookmarksStore *model)
|
||||
{
|
||||
GDrive *drive;
|
||||
|
||||
drive = g_volume_get_drive (volume);
|
||||
|
||||
if (drive)
|
||||
{
|
||||
g_object_unref (drive);
|
||||
return;
|
||||
}
|
||||
|
||||
process_volume_cb (volume, model);
|
||||
}
|
||||
|
||||
static void
|
||||
init_volumes (GeditFileBookmarksStore *model)
|
||||
{
|
||||
GList *volumes;
|
||||
|
||||
volumes = g_volume_monitor_get_volumes (model->priv->volume_monitor);
|
||||
|
||||
g_list_foreach (volumes, (GFunc)process_volume_nodrive_cb, model);
|
||||
g_list_foreach (volumes, (GFunc)g_object_unref, NULL);
|
||||
g_list_free (volumes);
|
||||
}
|
||||
|
||||
static void
|
||||
process_mount_novolume_cb (GMount *mount,
|
||||
GeditFileBookmarksStore *model)
|
||||
{
|
||||
GVolume *volume;
|
||||
|
||||
volume = g_mount_get_volume (mount);
|
||||
|
||||
if (volume)
|
||||
{
|
||||
g_object_unref (volume);
|
||||
}
|
||||
else if (!g_mount_is_shadowed (mount))
|
||||
{
|
||||
/* Add the mount */
|
||||
add_fs (model, mount, GEDIT_FILE_BOOKMARKS_STORE_NONE, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
init_mounts (GeditFileBookmarksStore *model)
|
||||
{
|
||||
GList *mounts;
|
||||
|
||||
mounts = g_volume_monitor_get_mounts (model->priv->volume_monitor);
|
||||
|
||||
g_list_foreach (mounts, (GFunc)process_mount_novolume_cb, model);
|
||||
g_list_foreach (mounts, (GFunc)g_object_unref, NULL);
|
||||
g_list_free (mounts);
|
||||
}
|
||||
|
||||
static void
|
||||
init_fs (GeditFileBookmarksStore * model)
|
||||
{
|
||||
if (model->priv->volume_monitor == NULL) {
|
||||
const gchar **ptr;
|
||||
const gchar *signals[] = {
|
||||
"drive-connected", "drive-changed", "drive-disconnected",
|
||||
"volume-added", "volume-removed", "volume-changed",
|
||||
"mount-added", "mount-removed", "mount-changed",
|
||||
NULL
|
||||
};
|
||||
|
||||
model->priv->volume_monitor = g_volume_monitor_get ();
|
||||
|
||||
/* Connect signals */
|
||||
for (ptr = signals; *ptr; ptr++)
|
||||
{
|
||||
g_signal_connect (model->priv->volume_monitor,
|
||||
*ptr,
|
||||
G_CALLBACK (on_fs_changed), model);
|
||||
}
|
||||
}
|
||||
|
||||
/* First go through all the connected drives */
|
||||
init_drives (model);
|
||||
|
||||
/* Then add all volumes, not associated with a drive */
|
||||
init_volumes (model);
|
||||
|
||||
/* Then finally add all mounts that have no volume */
|
||||
init_mounts (model);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
add_bookmark (GeditFileBookmarksStore * model,
|
||||
gchar const * name,
|
||||
gchar const * uri)
|
||||
{
|
||||
GFile * file;
|
||||
gboolean ret;
|
||||
guint flags = GEDIT_FILE_BOOKMARKS_STORE_IS_BOOKMARK;
|
||||
GtkTreeIter iter;
|
||||
|
||||
file = g_file_new_for_uri (uri);
|
||||
|
||||
if (g_file_is_native (file)) {
|
||||
flags |= GEDIT_FILE_BOOKMARKS_STORE_IS_LOCAL_BOOKMARK;
|
||||
} else {
|
||||
flags |= GEDIT_FILE_BOOKMARKS_STORE_IS_REMOTE_BOOKMARK;
|
||||
}
|
||||
|
||||
ret = add_file (model, file, name, flags, &iter);
|
||||
|
||||
g_object_unref (file);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
init_bookmarks (GeditFileBookmarksStore * model)
|
||||
{
|
||||
gchar *bookmarks;
|
||||
GError *error = NULL;
|
||||
gchar *contents;
|
||||
gchar **lines;
|
||||
gchar **line;
|
||||
gboolean added = FALSE;
|
||||
|
||||
/* Read the bookmarks file */
|
||||
bookmarks = g_build_filename (g_get_home_dir (),
|
||||
".gtk-bookmarks",
|
||||
NULL);
|
||||
|
||||
if (g_file_get_contents (bookmarks, &contents, NULL, &error)) {
|
||||
lines = g_strsplit (contents, "\n", 0);
|
||||
|
||||
for (line = lines; *line; ++line) {
|
||||
if (**line) {
|
||||
gchar *pos;
|
||||
gchar *name;
|
||||
|
||||
/* CHECK: is this really utf8? */
|
||||
pos = g_utf8_strchr (*line, -1, ' ');
|
||||
|
||||
if (pos != NULL) {
|
||||
*pos = '\0';
|
||||
name = pos + 1;
|
||||
} else {
|
||||
name = NULL;
|
||||
}
|
||||
|
||||
/* the bookmarks file should contain valid
|
||||
* URIs, but paranoia is good */
|
||||
if (gedit_utils_is_valid_uri (*line)) {
|
||||
added |= add_bookmark (model, name, *line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g_strfreev (lines);
|
||||
g_free (contents);
|
||||
|
||||
/* Add a watch */
|
||||
if (model->priv->bookmarks_monitor == NULL) {
|
||||
GFile * file;
|
||||
|
||||
file = g_file_new_for_path (bookmarks);
|
||||
model->priv->bookmarks_monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE, NULL, NULL);
|
||||
g_object_unref (file);
|
||||
|
||||
g_signal_connect (model->priv->bookmarks_monitor,
|
||||
"changed",
|
||||
(GCallback)on_bookmarks_file_changed,
|
||||
model);
|
||||
}
|
||||
} else {
|
||||
/* The bookmarks file doesn't exist (which is perfectly fine) */
|
||||
g_error_free (error);
|
||||
}
|
||||
|
||||
if (added) {
|
||||
/* Bookmarks separator */
|
||||
add_node (model, NULL, NULL, NULL,
|
||||
GEDIT_FILE_BOOKMARKS_STORE_IS_BOOKMARK |
|
||||
GEDIT_FILE_BOOKMARKS_STORE_IS_SEPARATOR, NULL);
|
||||
}
|
||||
|
||||
g_free (bookmarks);
|
||||
}
|
||||
|
||||
static gint flags_order[] = {
|
||||
GEDIT_FILE_BOOKMARKS_STORE_IS_HOME,
|
||||
GEDIT_FILE_BOOKMARKS_STORE_IS_DESKTOP,
|
||||
GEDIT_FILE_BOOKMARKS_STORE_IS_SPECIAL_DIR,
|
||||
GEDIT_FILE_BOOKMARKS_STORE_IS_ROOT,
|
||||
GEDIT_FILE_BOOKMARKS_STORE_IS_FS,
|
||||
GEDIT_FILE_BOOKMARKS_STORE_IS_BOOKMARK,
|
||||
-1
|
||||
};
|
||||
|
||||
static gint
|
||||
utf8_casecmp (gchar const *s1, const gchar * s2)
|
||||
{
|
||||
gchar *n1;
|
||||
gchar *n2;
|
||||
gint result;
|
||||
|
||||
n1 = g_utf8_casefold (s1, -1);
|
||||
n2 = g_utf8_casefold (s2, -1);
|
||||
|
||||
result = g_utf8_collate (n1, n2);
|
||||
|
||||
g_free (n1);
|
||||
g_free (n2);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static gint
|
||||
bookmarks_compare_names (GtkTreeModel * model, GtkTreeIter * a,
|
||||
GtkTreeIter * b)
|
||||
{
|
||||
gchar *n1;
|
||||
gchar *n2;
|
||||
gint result;
|
||||
guint f1;
|
||||
guint f2;
|
||||
|
||||
gtk_tree_model_get (model, a,
|
||||
GEDIT_FILE_BOOKMARKS_STORE_COLUMN_NAME, &n1,
|
||||
GEDIT_FILE_BOOKMARKS_STORE_COLUMN_FLAGS, &f1,
|
||||
-1);
|
||||
gtk_tree_model_get (model, b,
|
||||
GEDIT_FILE_BOOKMARKS_STORE_COLUMN_NAME, &n2,
|
||||
GEDIT_FILE_BOOKMARKS_STORE_COLUMN_FLAGS, &f2,
|
||||
-1);
|
||||
|
||||
/* do not sort actual bookmarks to keep same order as in caja */
|
||||
if ((f1 & GEDIT_FILE_BOOKMARKS_STORE_IS_BOOKMARK) &&
|
||||
(f2 & GEDIT_FILE_BOOKMARKS_STORE_IS_BOOKMARK))
|
||||
result = 0;
|
||||
else if (n1 == NULL && n2 == NULL)
|
||||
result = 0;
|
||||
else if (n1 == NULL)
|
||||
result = -1;
|
||||
else if (n2 == NULL)
|
||||
result = 1;
|
||||
else
|
||||
result = utf8_casecmp (n1, n2);
|
||||
|
||||
g_free (n1);
|
||||
g_free (n2);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static gint
|
||||
bookmarks_compare_flags (GtkTreeModel * model, GtkTreeIter * a,
|
||||
GtkTreeIter * b)
|
||||
{
|
||||
guint f1;
|
||||
guint f2;
|
||||
gint *flags;
|
||||
guint sep;
|
||||
|
||||
sep = GEDIT_FILE_BOOKMARKS_STORE_IS_SEPARATOR;
|
||||
|
||||
gtk_tree_model_get (model, a,
|
||||
GEDIT_FILE_BOOKMARKS_STORE_COLUMN_FLAGS, &f1,
|
||||
-1);
|
||||
gtk_tree_model_get (model, b,
|
||||
GEDIT_FILE_BOOKMARKS_STORE_COLUMN_FLAGS, &f2,
|
||||
-1);
|
||||
|
||||
for (flags = flags_order; *flags != -1; ++flags) {
|
||||
if ((f1 & *flags) != (f2 & *flags)) {
|
||||
if (f1 & *flags) {
|
||||
return -1;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
} else if ((f1 & *flags) && (f1 & sep) != (f2 & sep)) {
|
||||
if (f1 & sep)
|
||||
return -1;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static gint
|
||||
bookmarks_compare_func (GtkTreeModel * model, GtkTreeIter * a,
|
||||
GtkTreeIter * b, gpointer user_data)
|
||||
{
|
||||
gint result;
|
||||
|
||||
result = bookmarks_compare_flags (model, a, b);
|
||||
|
||||
if (result == 0)
|
||||
result = bookmarks_compare_names (model, a, b);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
find_with_flags (GtkTreeModel * model, GtkTreeIter * iter, gpointer obj,
|
||||
guint flags, guint notflags)
|
||||
{
|
||||
GtkTreeIter child;
|
||||
guint childflags = 0;
|
||||
GObject * childobj;
|
||||
gboolean fequal;
|
||||
|
||||
if (!gtk_tree_model_get_iter_first (model, &child))
|
||||
return FALSE;
|
||||
|
||||
do {
|
||||
gtk_tree_model_get (model, &child,
|
||||
GEDIT_FILE_BOOKMARKS_STORE_COLUMN_OBJECT,
|
||||
&childobj,
|
||||
GEDIT_FILE_BOOKMARKS_STORE_COLUMN_FLAGS,
|
||||
&childflags, -1);
|
||||
|
||||
fequal = (obj == childobj);
|
||||
|
||||
if (childobj)
|
||||
g_object_unref (childobj);
|
||||
|
||||
if ((obj == NULL || fequal) &&
|
||||
(childflags & flags) == flags
|
||||
&& !(childflags & notflags)) {
|
||||
*iter = child;
|
||||
return TRUE;
|
||||
}
|
||||
} while (gtk_tree_model_iter_next (model, &child));
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
remove_node (GtkTreeModel * model, GtkTreeIter * iter)
|
||||
{
|
||||
guint flags;
|
||||
|
||||
gtk_tree_model_get (model, iter,
|
||||
GEDIT_FILE_BOOKMARKS_STORE_COLUMN_FLAGS, &flags,
|
||||
-1);
|
||||
|
||||
if (!(flags & GEDIT_FILE_BOOKMARKS_STORE_IS_SEPARATOR)) {
|
||||
if (flags & GEDIT_FILE_BOOKMARKS_STORE_IS_FS) {
|
||||
check_mount_separator (GEDIT_FILE_BOOKMARKS_STORE (model),
|
||||
flags & GEDIT_FILE_BOOKMARKS_STORE_IS_FS,
|
||||
FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
gtk_tree_store_remove (GTK_TREE_STORE (model), iter);
|
||||
}
|
||||
|
||||
static void
|
||||
remove_bookmarks (GeditFileBookmarksStore * model)
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
|
||||
while (find_with_flags (GTK_TREE_MODEL (model), &iter, NULL,
|
||||
GEDIT_FILE_BOOKMARKS_STORE_IS_BOOKMARK,
|
||||
0)) {
|
||||
remove_node (GTK_TREE_MODEL (model), &iter);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
initialize_fill (GeditFileBookmarksStore * model)
|
||||
{
|
||||
init_special_directories (model);
|
||||
init_fs (model);
|
||||
init_bookmarks (model);
|
||||
}
|
||||
|
||||
/* Public */
|
||||
GeditFileBookmarksStore *
|
||||
gedit_file_bookmarks_store_new (void)
|
||||
{
|
||||
GeditFileBookmarksStore *model;
|
||||
GType column_types[] = {
|
||||
GDK_TYPE_PIXBUF,
|
||||
G_TYPE_STRING,
|
||||
G_TYPE_OBJECT,
|
||||
G_TYPE_UINT
|
||||
};
|
||||
|
||||
model = g_object_new (GEDIT_TYPE_FILE_BOOKMARKS_STORE, NULL);
|
||||
gtk_tree_store_set_column_types (GTK_TREE_STORE (model),
|
||||
GEDIT_FILE_BOOKMARKS_STORE_N_COLUMNS,
|
||||
column_types);
|
||||
|
||||
gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE (model),
|
||||
bookmarks_compare_func,
|
||||
NULL, NULL);
|
||||
gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (model),
|
||||
GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID,
|
||||
GTK_SORT_ASCENDING);
|
||||
|
||||
initialize_fill (model);
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
gchar *
|
||||
gedit_file_bookmarks_store_get_uri (GeditFileBookmarksStore * model,
|
||||
GtkTreeIter * iter)
|
||||
{
|
||||
GObject * obj;
|
||||
GFile * file = NULL;
|
||||
guint flags;
|
||||
gchar * ret = NULL;
|
||||
gboolean isfs;
|
||||
|
||||
g_return_val_if_fail (GEDIT_IS_FILE_BOOKMARKS_STORE (model), NULL);
|
||||
g_return_val_if_fail (iter != NULL, NULL);
|
||||
|
||||
gtk_tree_model_get (GTK_TREE_MODEL (model), iter,
|
||||
GEDIT_FILE_BOOKMARKS_STORE_COLUMN_FLAGS,
|
||||
&flags,
|
||||
GEDIT_FILE_BOOKMARKS_STORE_COLUMN_OBJECT,
|
||||
&obj,
|
||||
-1);
|
||||
|
||||
if (obj == NULL)
|
||||
return NULL;
|
||||
|
||||
isfs = (flags & GEDIT_FILE_BOOKMARKS_STORE_IS_FS);
|
||||
|
||||
if (isfs && (flags & GEDIT_FILE_BOOKMARKS_STORE_IS_MOUNT))
|
||||
{
|
||||
file = g_mount_get_root (G_MOUNT (obj));
|
||||
}
|
||||
else if (!isfs)
|
||||
{
|
||||
file = g_object_ref (obj);
|
||||
}
|
||||
|
||||
g_object_unref (obj);
|
||||
|
||||
if (file)
|
||||
{
|
||||
ret = g_file_get_uri (file);
|
||||
g_object_unref (file);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
gedit_file_bookmarks_store_refresh (GeditFileBookmarksStore * model)
|
||||
{
|
||||
gtk_tree_store_clear (GTK_TREE_STORE (model));
|
||||
initialize_fill (model);
|
||||
}
|
||||
|
||||
static void
|
||||
on_fs_changed (GVolumeMonitor *monitor,
|
||||
GObject *object,
|
||||
GeditFileBookmarksStore *model)
|
||||
{
|
||||
GtkTreeModel *tree_model = GTK_TREE_MODEL (model);
|
||||
guint flags = GEDIT_FILE_BOOKMARKS_STORE_IS_FS;
|
||||
guint noflags = GEDIT_FILE_BOOKMARKS_STORE_IS_SEPARATOR;
|
||||
GtkTreeIter iter;
|
||||
|
||||
/* clear all fs items */
|
||||
while (find_with_flags (tree_model, &iter, NULL, flags, noflags))
|
||||
remove_node (tree_model, &iter);
|
||||
|
||||
/* then reinitialize */
|
||||
init_fs (model);
|
||||
}
|
||||
|
||||
static void
|
||||
on_bookmarks_file_changed (GFileMonitor * monitor,
|
||||
GFile * file,
|
||||
GFile * other_file,
|
||||
GFileMonitorEvent event_type,
|
||||
GeditFileBookmarksStore * model)
|
||||
{
|
||||
switch (event_type) {
|
||||
case G_FILE_MONITOR_EVENT_CHANGED:
|
||||
case G_FILE_MONITOR_EVENT_CREATED:
|
||||
/* Re-initialize bookmarks */
|
||||
remove_bookmarks (model);
|
||||
init_bookmarks (model);
|
||||
break;
|
||||
case G_FILE_MONITOR_EVENT_DELETED: // FIXME: shouldn't we also monitor the directory?
|
||||
/* Remove bookmarks */
|
||||
remove_bookmarks (model);
|
||||
g_object_unref (monitor);
|
||||
model->priv->bookmarks_monitor = NULL;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// ex:ts=8:noet:
|
90
plugins/filebrowser/gedit-file-bookmarks-store.h
Executable file
90
plugins/filebrowser/gedit-file-bookmarks-store.h
Executable file
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* gedit-file-bookmarks-store.h - Gedit plugin providing easy file access
|
||||
* from the sidepanel
|
||||
*
|
||||
* Copyright (C) 2006 - Jesse van den Kieboom <jesse@icecrew.nl>
|
||||
*
|
||||
* 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 __GEDIT_FILE_BOOKMARKS_STORE_H__
|
||||
#define __GEDIT_FILE_BOOKMARKS_STORE_H__
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
#define GEDIT_TYPE_FILE_BOOKMARKS_STORE (gedit_file_bookmarks_store_get_type ())
|
||||
#define GEDIT_FILE_BOOKMARKS_STORE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEDIT_TYPE_FILE_BOOKMARKS_STORE, GeditFileBookmarksStore))
|
||||
#define GEDIT_FILE_BOOKMARKS_STORE_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEDIT_TYPE_FILE_BOOKMARKS_STORE, GeditFileBookmarksStore const))
|
||||
#define GEDIT_FILE_BOOKMARKS_STORE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GEDIT_TYPE_FILE_BOOKMARKS_STORE, GeditFileBookmarksStoreClass))
|
||||
#define GEDIT_IS_FILE_BOOKMARKS_STORE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEDIT_TYPE_FILE_BOOKMARKS_STORE))
|
||||
#define GEDIT_IS_FILE_BOOKMARKS_STORE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GEDIT_TYPE_FILE_BOOKMARKS_STORE))
|
||||
#define GEDIT_FILE_BOOKMARKS_STORE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GEDIT_TYPE_FILE_BOOKMARKS_STORE, GeditFileBookmarksStoreClass))
|
||||
|
||||
typedef struct _GeditFileBookmarksStore GeditFileBookmarksStore;
|
||||
typedef struct _GeditFileBookmarksStoreClass GeditFileBookmarksStoreClass;
|
||||
typedef struct _GeditFileBookmarksStorePrivate GeditFileBookmarksStorePrivate;
|
||||
|
||||
enum
|
||||
{
|
||||
GEDIT_FILE_BOOKMARKS_STORE_COLUMN_ICON = 0,
|
||||
GEDIT_FILE_BOOKMARKS_STORE_COLUMN_NAME,
|
||||
GEDIT_FILE_BOOKMARKS_STORE_COLUMN_OBJECT,
|
||||
GEDIT_FILE_BOOKMARKS_STORE_COLUMN_FLAGS,
|
||||
GEDIT_FILE_BOOKMARKS_STORE_N_COLUMNS
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
GEDIT_FILE_BOOKMARKS_STORE_NONE = 0,
|
||||
GEDIT_FILE_BOOKMARKS_STORE_IS_SEPARATOR = 1 << 0, /* Separator item */
|
||||
GEDIT_FILE_BOOKMARKS_STORE_IS_SPECIAL_DIR = 1 << 1, /* Special user dir */
|
||||
GEDIT_FILE_BOOKMARKS_STORE_IS_HOME = 1 << 2, /* The special Home user directory */
|
||||
GEDIT_FILE_BOOKMARKS_STORE_IS_DESKTOP = 1 << 3, /* The special Desktop user directory */
|
||||
GEDIT_FILE_BOOKMARKS_STORE_IS_DOCUMENTS = 1 << 4, /* The special Documents user directory */
|
||||
GEDIT_FILE_BOOKMARKS_STORE_IS_FS = 1 << 5, /* A mount object */
|
||||
GEDIT_FILE_BOOKMARKS_STORE_IS_MOUNT = 1 << 6, /* A mount object */
|
||||
GEDIT_FILE_BOOKMARKS_STORE_IS_VOLUME = 1 << 7, /* A volume object */
|
||||
GEDIT_FILE_BOOKMARKS_STORE_IS_DRIVE = 1 << 8, /* A drive object */
|
||||
GEDIT_FILE_BOOKMARKS_STORE_IS_ROOT = 1 << 9, /* The root file system (file:///) */
|
||||
GEDIT_FILE_BOOKMARKS_STORE_IS_BOOKMARK = 1 << 10, /* A gtk bookmark */
|
||||
GEDIT_FILE_BOOKMARKS_STORE_IS_REMOTE_BOOKMARK = 1 << 11, /* A remote gtk bookmark */
|
||||
GEDIT_FILE_BOOKMARKS_STORE_IS_LOCAL_BOOKMARK = 1 << 12 /* A local gtk bookmark */
|
||||
};
|
||||
|
||||
struct _GeditFileBookmarksStore
|
||||
{
|
||||
GtkTreeStore parent;
|
||||
|
||||
GeditFileBookmarksStorePrivate *priv;
|
||||
};
|
||||
|
||||
struct _GeditFileBookmarksStoreClass
|
||||
{
|
||||
GtkTreeStoreClass parent_class;
|
||||
};
|
||||
|
||||
GType gedit_file_bookmarks_store_get_type (void) G_GNUC_CONST;
|
||||
GType gedit_file_bookmarks_store_register_type (GTypeModule * module);
|
||||
|
||||
GeditFileBookmarksStore *gedit_file_bookmarks_store_new (void);
|
||||
gchar *gedit_file_bookmarks_store_get_uri (GeditFileBookmarksStore * model,
|
||||
GtkTreeIter * iter);
|
||||
void gedit_file_bookmarks_store_refresh (GeditFileBookmarksStore * model);
|
||||
|
||||
G_END_DECLS
|
||||
#endif /* __GEDIT_FILE_BOOKMARKS_STORE_H__ */
|
||||
|
||||
// ex:ts=8:noet:
|
20
plugins/filebrowser/gedit-file-browser-enum-register.c.template
Executable file
20
plugins/filebrowser/gedit-file-browser-enum-register.c.template
Executable file
@@ -0,0 +1,20 @@
|
||||
/*** BEGIN file-header ***/
|
||||
void
|
||||
gedit_file_browser_enum_and_flag_register_type (GTypeModule * module)
|
||||
{
|
||||
/*** END file-header ***/
|
||||
|
||||
/*** BEGIN file-production ***/
|
||||
/* Enumerations from "@filename@" */
|
||||
|
||||
/*** END file-production ***/
|
||||
|
||||
/*** BEGIN enumeration-production ***/
|
||||
register_@enum_name@ (module);
|
||||
|
||||
/*** END enumeration-production ***/
|
||||
|
||||
/*** BEGIN file-tail ***/
|
||||
}
|
||||
|
||||
/*** END file-tail ***/
|
45
plugins/filebrowser/gedit-file-browser-enum-types.c.template
Executable file
45
plugins/filebrowser/gedit-file-browser-enum-types.c.template
Executable file
@@ -0,0 +1,45 @@
|
||||
/*** BEGIN file-header ***/
|
||||
#include "gedit-file-browser-enum-types.h"
|
||||
|
||||
/*** END file-header ***/
|
||||
|
||||
/*** BEGIN file-production ***/
|
||||
/* enumerations from "@filename@" */
|
||||
#include "@filename@"
|
||||
|
||||
/*** END file-production ***/
|
||||
|
||||
/*** BEGIN value-header ***/
|
||||
static GType @enum_name@_type = 0;
|
||||
|
||||
static GType
|
||||
register_@enum_name@ (GTypeModule *module)
|
||||
{
|
||||
static const G@Type@Value values[] = {
|
||||
/*** END value-header ***/
|
||||
|
||||
/*** BEGIN value-production ***/
|
||||
{ @VALUENAME@,
|
||||
"@VALUENAME@",
|
||||
"@valuenick@" },
|
||||
/*** END value-production ***/
|
||||
|
||||
/*** BEGIN value-tail ***/
|
||||
{ 0, NULL, NULL }
|
||||
};
|
||||
|
||||
@enum_name@_type =
|
||||
g_type_module_register_@type@ (module,
|
||||
"@EnumName@",
|
||||
values);
|
||||
|
||||
return @enum_name@_type;
|
||||
}
|
||||
|
||||
GType
|
||||
@enum_name@_get_type (void)
|
||||
{
|
||||
return @enum_name@_type;
|
||||
}
|
||||
|
||||
/*** END value-tail ***/
|
29
plugins/filebrowser/gedit-file-browser-enum-types.h.template
Executable file
29
plugins/filebrowser/gedit-file-browser-enum-types.h.template
Executable file
@@ -0,0 +1,29 @@
|
||||
/*** BEGIN file-header ***/
|
||||
#ifndef __GEDIT_FILE_BROWSER_ENUM_TYPES_H__
|
||||
#define __GEDIT_FILE_BROWSER_ENUM_TYPES_H__
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/*** END file-header ***/
|
||||
|
||||
/*** BEGIN file-production ***/
|
||||
/* Enumerations from "@filename@" */
|
||||
|
||||
/*** END file-production ***/
|
||||
|
||||
/*** BEGIN enumeration-production ***/
|
||||
#define GEDIT_TYPE_@ENUMSHORT@ (@enum_name@_get_type())
|
||||
GType @enum_name@_get_type (void) G_GNUC_CONST;
|
||||
|
||||
/*** END enumeration-production ***/
|
||||
|
||||
/*** BEGIN file-tail ***/
|
||||
void gedit_file_browser_enum_and_flag_register_type (GTypeModule * module);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GEDIT_FILE_BROWSER_ENUM_TYPES_H__ */
|
||||
/*** END file-tail ***/
|
||||
|
41
plugins/filebrowser/gedit-file-browser-error.h
Executable file
41
plugins/filebrowser/gedit-file-browser-error.h
Executable file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* gedit-file-browser-error.h - Gedit plugin providing easy file access
|
||||
* from the sidepanel
|
||||
*
|
||||
* Copyright (C) 2006 - Jesse van den Kieboom <jesse@icecrew.nl>
|
||||
*
|
||||
* 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 __GEDIT_FILE_BROWSER_ERROR_H__
|
||||
#define __GEDIT_FILE_BROWSER_ERROR_H__
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef enum {
|
||||
GEDIT_FILE_BROWSER_ERROR_NONE,
|
||||
GEDIT_FILE_BROWSER_ERROR_RENAME,
|
||||
GEDIT_FILE_BROWSER_ERROR_DELETE,
|
||||
GEDIT_FILE_BROWSER_ERROR_NEW_FILE,
|
||||
GEDIT_FILE_BROWSER_ERROR_NEW_DIRECTORY,
|
||||
GEDIT_FILE_BROWSER_ERROR_OPEN_DIRECTORY,
|
||||
GEDIT_FILE_BROWSER_ERROR_SET_ROOT,
|
||||
GEDIT_FILE_BROWSER_ERROR_LOAD_DIRECTORY,
|
||||
GEDIT_FILE_BROWSER_ERROR_NUM
|
||||
} GeditFileBrowserError;
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GEDIT_FILE_BROWSER_ERROR_H__ */
|
5
plugins/filebrowser/gedit-file-browser-marshal.list
Executable file
5
plugins/filebrowser/gedit-file-browser-marshal.list
Executable file
@@ -0,0 +1,5 @@
|
||||
VOID:UINT,STRING
|
||||
VOID:STRING,STRING
|
||||
BOOL:OBJECT,POINTER
|
||||
BOOL:POINTER
|
||||
BOOL:VOID
|
1033
plugins/filebrowser/gedit-file-browser-messages.c
Executable file
1033
plugins/filebrowser/gedit-file-browser-messages.c
Executable file
File diff suppressed because it is too large
Load Diff
35
plugins/filebrowser/gedit-file-browser-messages.h
Executable file
35
plugins/filebrowser/gedit-file-browser-messages.h
Executable file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* gedit-file-browser-messages.h - Gedit plugin providing easy file access
|
||||
* from the sidepanel
|
||||
*
|
||||
* Copyright (C) 2008 - Jesse van den Kieboom <jesse@icecrew.nl>
|
||||
*
|
||||
* 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 __GEDIT_FILE_BROWSER_MESSAGES_H__
|
||||
#define __GEDIT_FILE_BROWSER_MESSAGES_H__
|
||||
|
||||
#include <gedit/gedit-window.h>
|
||||
#include <gedit/gedit-message-bus.h>
|
||||
#include "gedit-file-browser-widget.h"
|
||||
|
||||
void gedit_file_browser_messages_register (GeditWindow *window,
|
||||
GeditFileBrowserWidget *widget);
|
||||
void gedit_file_browser_messages_unregister (GeditWindow *window);
|
||||
|
||||
#endif /* __GEDIT_FILE_BROWSER_MESSAGES_H__ */
|
||||
|
||||
// ex:ts=8:noet:
|
1254
plugins/filebrowser/gedit-file-browser-plugin.c
Executable file
1254
plugins/filebrowser/gedit-file-browser-plugin.c
Executable file
File diff suppressed because it is too large
Load Diff
71
plugins/filebrowser/gedit-file-browser-plugin.h
Executable file
71
plugins/filebrowser/gedit-file-browser-plugin.h
Executable file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* gedit-file-browser-plugin.h - Gedit plugin providing easy file access
|
||||
* from the sidepanel
|
||||
*
|
||||
* Copyright (C) 2006 - Jesse van den Kieboom <jesse@icecrew.nl>
|
||||
*
|
||||
* 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 __GEDIT_FILE_BROWSER_PLUGIN_H__
|
||||
#define __GEDIT_FILE_BROWSER_PLUGIN_H__
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
#include <gedit/gedit-plugin.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
/*
|
||||
* Type checking and casting macros
|
||||
*/
|
||||
#define GEDIT_TYPE_FILE_BROWSER_PLUGIN (filetree_plugin_get_type ())
|
||||
#define GEDIT_FILE_BROWSER_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GEDIT_TYPE_FILE_BROWSER_PLUGIN, GeditFileBrowserPlugin))
|
||||
#define GEDIT_FILE_BROWSER_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GEDIT_TYPE_FILE_BROWSER_PLUGIN, GeditFileBrowserPluginClass))
|
||||
#define GEDIT_IS_FILE_BROWSER_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GEDIT_TYPE_FILE_BROWSER_PLUGIN))
|
||||
#define GEDIT_IS_FILE_BROWSER_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GEDIT_TYPE_FILE_BROWSER_PLUGIN))
|
||||
#define GEDIT_FILE_BROWSER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GEDIT_TYPE_FILE_BROWSER_PLUGIN, GeditFileBrowserPluginClass))
|
||||
|
||||
/* Private structure type */
|
||||
typedef struct _GeditFileBrowserPluginPrivate GeditFileBrowserPluginPrivate;
|
||||
typedef struct _GeditFileBrowserPlugin GeditFileBrowserPlugin;
|
||||
typedef struct _GeditFileBrowserPluginClass GeditFileBrowserPluginClass;
|
||||
|
||||
struct _GeditFileBrowserPlugin
|
||||
{
|
||||
GeditPlugin parent_instance;
|
||||
|
||||
/*< private > */
|
||||
GeditFileBrowserPluginPrivate *priv;
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct _GeditFileBrowserPluginClass
|
||||
{
|
||||
GeditPluginClass parent_class;
|
||||
};
|
||||
|
||||
/*
|
||||
* Public methods
|
||||
*/
|
||||
GType filetree_plugin_get_type (void) G_GNUC_CONST;
|
||||
|
||||
/* All the plugins must implement this function */
|
||||
G_MODULE_EXPORT GType register_gedit_plugin (GTypeModule * module);
|
||||
|
||||
G_END_DECLS
|
||||
#endif /* __GEDIT_FILE_BROWSER_PLUGIN_H__ */
|
||||
|
||||
// ex:ts=8:noet:
|
3625
plugins/filebrowser/gedit-file-browser-store.c
Executable file
3625
plugins/filebrowser/gedit-file-browser-store.c
Executable file
File diff suppressed because it is too large
Load Diff
200
plugins/filebrowser/gedit-file-browser-store.h
Executable file
200
plugins/filebrowser/gedit-file-browser-store.h
Executable file
@@ -0,0 +1,200 @@
|
||||
/*
|
||||
* gedit-file-browser-store.h - Gedit plugin providing easy file access
|
||||
* from the sidepanel
|
||||
*
|
||||
* Copyright (C) 2006 - Jesse van den Kieboom <jesse@icecrew.nl>
|
||||
*
|
||||
* 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 __GEDIT_FILE_BROWSER_STORE_H__
|
||||
#define __GEDIT_FILE_BROWSER_STORE_H__
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
#define GEDIT_TYPE_FILE_BROWSER_STORE (gedit_file_browser_store_get_type ())
|
||||
#define GEDIT_FILE_BROWSER_STORE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEDIT_TYPE_FILE_BROWSER_STORE, GeditFileBrowserStore))
|
||||
#define GEDIT_FILE_BROWSER_STORE_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEDIT_TYPE_FILE_BROWSER_STORE, GeditFileBrowserStore const))
|
||||
#define GEDIT_FILE_BROWSER_STORE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GEDIT_TYPE_FILE_BROWSER_STORE, GeditFileBrowserStoreClass))
|
||||
#define GEDIT_IS_FILE_BROWSER_STORE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEDIT_TYPE_FILE_BROWSER_STORE))
|
||||
#define GEDIT_IS_FILE_BROWSER_STORE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GEDIT_TYPE_FILE_BROWSER_STORE))
|
||||
#define GEDIT_FILE_BROWSER_STORE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GEDIT_TYPE_FILE_BROWSER_STORE, GeditFileBrowserStoreClass))
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GEDIT_FILE_BROWSER_STORE_COLUMN_ICON = 0,
|
||||
GEDIT_FILE_BROWSER_STORE_COLUMN_NAME,
|
||||
GEDIT_FILE_BROWSER_STORE_COLUMN_URI,
|
||||
GEDIT_FILE_BROWSER_STORE_COLUMN_FLAGS,
|
||||
GEDIT_FILE_BROWSER_STORE_COLUMN_EMBLEM,
|
||||
GEDIT_FILE_BROWSER_STORE_COLUMN_NUM
|
||||
} GeditFileBrowserStoreColumn;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GEDIT_FILE_BROWSER_STORE_FLAG_IS_DIRECTORY = 1 << 0,
|
||||
GEDIT_FILE_BROWSER_STORE_FLAG_IS_HIDDEN = 1 << 1,
|
||||
GEDIT_FILE_BROWSER_STORE_FLAG_IS_TEXT = 1 << 2,
|
||||
GEDIT_FILE_BROWSER_STORE_FLAG_LOADED = 1 << 3,
|
||||
GEDIT_FILE_BROWSER_STORE_FLAG_IS_FILTERED = 1 << 4,
|
||||
GEDIT_FILE_BROWSER_STORE_FLAG_IS_DUMMY = 1 << 5
|
||||
} GeditFileBrowserStoreFlag;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GEDIT_FILE_BROWSER_STORE_RESULT_OK,
|
||||
GEDIT_FILE_BROWSER_STORE_RESULT_NO_CHANGE,
|
||||
GEDIT_FILE_BROWSER_STORE_RESULT_ERROR,
|
||||
GEDIT_FILE_BROWSER_STORE_RESULT_NO_TRASH,
|
||||
GEDIT_FILE_BROWSER_STORE_RESULT_MOUNTING,
|
||||
GEDIT_FILE_BROWSER_STORE_RESULT_NUM
|
||||
} GeditFileBrowserStoreResult;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GEDIT_FILE_BROWSER_STORE_FILTER_MODE_NONE = 0,
|
||||
GEDIT_FILE_BROWSER_STORE_FILTER_MODE_HIDE_HIDDEN = 1 << 0,
|
||||
GEDIT_FILE_BROWSER_STORE_FILTER_MODE_HIDE_BINARY = 1 << 1
|
||||
} GeditFileBrowserStoreFilterMode;
|
||||
|
||||
#define FILE_IS_DIR(flags) (flags & GEDIT_FILE_BROWSER_STORE_FLAG_IS_DIRECTORY)
|
||||
#define FILE_IS_HIDDEN(flags) (flags & GEDIT_FILE_BROWSER_STORE_FLAG_IS_HIDDEN)
|
||||
#define FILE_IS_TEXT(flags) (flags & GEDIT_FILE_BROWSER_STORE_FLAG_IS_TEXT)
|
||||
#define FILE_LOADED(flags) (flags & GEDIT_FILE_BROWSER_STORE_FLAG_LOADED)
|
||||
#define FILE_IS_FILTERED(flags) (flags & GEDIT_FILE_BROWSER_STORE_FLAG_IS_FILTERED)
|
||||
#define FILE_IS_DUMMY(flags) (flags & GEDIT_FILE_BROWSER_STORE_FLAG_IS_DUMMY)
|
||||
|
||||
typedef struct _GeditFileBrowserStore GeditFileBrowserStore;
|
||||
typedef struct _GeditFileBrowserStoreClass GeditFileBrowserStoreClass;
|
||||
typedef struct _GeditFileBrowserStorePrivate GeditFileBrowserStorePrivate;
|
||||
|
||||
typedef gboolean (*GeditFileBrowserStoreFilterFunc) (GeditFileBrowserStore
|
||||
* model,
|
||||
GtkTreeIter * iter,
|
||||
gpointer user_data);
|
||||
|
||||
struct _GeditFileBrowserStore
|
||||
{
|
||||
GObject parent;
|
||||
|
||||
GeditFileBrowserStorePrivate *priv;
|
||||
};
|
||||
|
||||
struct _GeditFileBrowserStoreClass {
|
||||
GObjectClass parent_class;
|
||||
|
||||
/* Signals */
|
||||
void (*begin_loading) (GeditFileBrowserStore * model,
|
||||
GtkTreeIter * iter);
|
||||
void (*end_loading) (GeditFileBrowserStore * model,
|
||||
GtkTreeIter * iter);
|
||||
void (*error) (GeditFileBrowserStore * model,
|
||||
guint code,
|
||||
gchar * message);
|
||||
gboolean (*no_trash) (GeditFileBrowserStore * model,
|
||||
GList * files);
|
||||
void (*rename) (GeditFileBrowserStore * model,
|
||||
const gchar * olduri,
|
||||
const gchar * newuri);
|
||||
void (*begin_refresh) (GeditFileBrowserStore * model);
|
||||
void (*end_refresh) (GeditFileBrowserStore * model);
|
||||
void (*unload) (GeditFileBrowserStore * model,
|
||||
const gchar * uri);
|
||||
};
|
||||
|
||||
GType gedit_file_browser_store_get_type (void) G_GNUC_CONST;
|
||||
GType gedit_file_browser_store_register_type (GTypeModule * module);
|
||||
|
||||
GeditFileBrowserStore *gedit_file_browser_store_new (gchar const *root);
|
||||
|
||||
GeditFileBrowserStoreResult
|
||||
gedit_file_browser_store_set_root_and_virtual_root (GeditFileBrowserStore * model,
|
||||
gchar const *root,
|
||||
gchar const *virtual_root);
|
||||
GeditFileBrowserStoreResult
|
||||
gedit_file_browser_store_set_root (GeditFileBrowserStore * model,
|
||||
gchar const *root);
|
||||
GeditFileBrowserStoreResult
|
||||
gedit_file_browser_store_set_virtual_root (GeditFileBrowserStore * model,
|
||||
GtkTreeIter * iter);
|
||||
GeditFileBrowserStoreResult
|
||||
gedit_file_browser_store_set_virtual_root_from_string (GeditFileBrowserStore * model,
|
||||
gchar const *root);
|
||||
GeditFileBrowserStoreResult
|
||||
gedit_file_browser_store_set_virtual_root_up (GeditFileBrowserStore * model);
|
||||
GeditFileBrowserStoreResult
|
||||
gedit_file_browser_store_set_virtual_root_top (GeditFileBrowserStore * model);
|
||||
|
||||
gboolean
|
||||
gedit_file_browser_store_get_iter_virtual_root (GeditFileBrowserStore * model,
|
||||
GtkTreeIter * iter);
|
||||
gboolean gedit_file_browser_store_get_iter_root (GeditFileBrowserStore * model,
|
||||
GtkTreeIter * iter);
|
||||
gchar * gedit_file_browser_store_get_root (GeditFileBrowserStore * model);
|
||||
gchar * gedit_file_browser_store_get_virtual_root (GeditFileBrowserStore * model);
|
||||
|
||||
gboolean gedit_file_browser_store_iter_equal (GeditFileBrowserStore * model,
|
||||
GtkTreeIter * iter1,
|
||||
GtkTreeIter * iter2);
|
||||
|
||||
void gedit_file_browser_store_set_value (GeditFileBrowserStore * tree_model,
|
||||
GtkTreeIter * iter,
|
||||
gint column,
|
||||
GValue * value);
|
||||
|
||||
void _gedit_file_browser_store_iter_expanded (GeditFileBrowserStore * model,
|
||||
GtkTreeIter * iter);
|
||||
void _gedit_file_browser_store_iter_collapsed (GeditFileBrowserStore * model,
|
||||
GtkTreeIter * iter);
|
||||
|
||||
GeditFileBrowserStoreFilterMode
|
||||
gedit_file_browser_store_get_filter_mode (GeditFileBrowserStore * model);
|
||||
void gedit_file_browser_store_set_filter_mode (GeditFileBrowserStore * model,
|
||||
GeditFileBrowserStoreFilterMode mode);
|
||||
void gedit_file_browser_store_set_filter_func (GeditFileBrowserStore * model,
|
||||
GeditFileBrowserStoreFilterFunc func,
|
||||
gpointer user_data);
|
||||
void gedit_file_browser_store_refilter (GeditFileBrowserStore * model);
|
||||
GeditFileBrowserStoreFilterMode
|
||||
gedit_file_browser_store_filter_mode_get_default (void);
|
||||
|
||||
void gedit_file_browser_store_refresh (GeditFileBrowserStore * model);
|
||||
gboolean gedit_file_browser_store_rename (GeditFileBrowserStore * model,
|
||||
GtkTreeIter * iter,
|
||||
gchar const *new_name,
|
||||
GError ** error);
|
||||
GeditFileBrowserStoreResult
|
||||
gedit_file_browser_store_delete (GeditFileBrowserStore * model,
|
||||
GtkTreeIter * iter,
|
||||
gboolean trash);
|
||||
GeditFileBrowserStoreResult
|
||||
gedit_file_browser_store_delete_all (GeditFileBrowserStore * model,
|
||||
GList *rows,
|
||||
gboolean trash);
|
||||
|
||||
gboolean gedit_file_browser_store_new_file (GeditFileBrowserStore * model,
|
||||
GtkTreeIter * parent,
|
||||
GtkTreeIter * iter);
|
||||
gboolean gedit_file_browser_store_new_directory (GeditFileBrowserStore * model,
|
||||
GtkTreeIter * parent,
|
||||
GtkTreeIter * iter);
|
||||
|
||||
void gedit_file_browser_store_cancel_mount_operation (GeditFileBrowserStore *store);
|
||||
|
||||
G_END_DECLS
|
||||
#endif /* __GEDIT_FILE_BROWSER_STORE_H__ */
|
||||
|
||||
// ex:ts=8:noet:
|
198
plugins/filebrowser/gedit-file-browser-utils.c
Executable file
198
plugins/filebrowser/gedit-file-browser-utils.c
Executable file
@@ -0,0 +1,198 @@
|
||||
/*
|
||||
* gedit-file-bookmarks-store.c - Gedit plugin providing easy file access
|
||||
* from the sidepanel
|
||||
*
|
||||
* Copyright (C) 2006 - Jesse van den Kieboom <jesse@icecrew.nl>
|
||||
*
|
||||
* 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 "gedit-file-browser-utils.h"
|
||||
#include <gedit/gedit-utils.h>
|
||||
|
||||
static GdkPixbuf *
|
||||
process_icon_pixbuf (GdkPixbuf * pixbuf,
|
||||
gchar const * name,
|
||||
gint size,
|
||||
GError * error)
|
||||
{
|
||||
GdkPixbuf * scale;
|
||||
|
||||
if (error != NULL) {
|
||||
g_warning ("Could not load theme icon %s: %s",
|
||||
name,
|
||||
error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
|
||||
if (pixbuf && gdk_pixbuf_get_width (pixbuf) > size) {
|
||||
scale = gdk_pixbuf_scale_simple (pixbuf,
|
||||
size,
|
||||
size,
|
||||
GDK_INTERP_BILINEAR);
|
||||
g_object_unref (pixbuf);
|
||||
pixbuf = scale;
|
||||
}
|
||||
|
||||
return pixbuf;
|
||||
}
|
||||
|
||||
GdkPixbuf *
|
||||
gedit_file_browser_utils_pixbuf_from_theme (gchar const * name,
|
||||
GtkIconSize size)
|
||||
{
|
||||
gint width;
|
||||
GError *error = NULL;
|
||||
GdkPixbuf *pixbuf;
|
||||
|
||||
gtk_icon_size_lookup (size, &width, NULL);
|
||||
|
||||
pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (),
|
||||
name,
|
||||
width,
|
||||
0,
|
||||
&error);
|
||||
|
||||
pixbuf = process_icon_pixbuf (pixbuf, name, width, error);
|
||||
|
||||
return pixbuf;
|
||||
}
|
||||
|
||||
GdkPixbuf *
|
||||
gedit_file_browser_utils_pixbuf_from_icon (GIcon * icon,
|
||||
GtkIconSize size)
|
||||
{
|
||||
GdkPixbuf * ret = NULL;
|
||||
GtkIconTheme *theme;
|
||||
GtkIconInfo *info;
|
||||
gint width;
|
||||
|
||||
if (!icon)
|
||||
return NULL;
|
||||
|
||||
theme = gtk_icon_theme_get_default ();
|
||||
gtk_icon_size_lookup (size, &width, NULL);
|
||||
|
||||
info = gtk_icon_theme_lookup_by_gicon (theme,
|
||||
icon,
|
||||
width,
|
||||
GTK_ICON_LOOKUP_USE_BUILTIN);
|
||||
|
||||
if (!info)
|
||||
return NULL;
|
||||
|
||||
ret = gtk_icon_info_load_icon (info, NULL);
|
||||
gtk_icon_info_free (info);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
GdkPixbuf *
|
||||
gedit_file_browser_utils_pixbuf_from_file (GFile * file,
|
||||
GtkIconSize size)
|
||||
{
|
||||
GIcon * icon;
|
||||
GFileInfo * info;
|
||||
GdkPixbuf * ret = NULL;
|
||||
|
||||
info = g_file_query_info (file,
|
||||
G_FILE_ATTRIBUTE_STANDARD_ICON,
|
||||
G_FILE_QUERY_INFO_NONE,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
if (!info)
|
||||
return NULL;
|
||||
|
||||
icon = g_file_info_get_icon (info);
|
||||
if (icon != NULL)
|
||||
ret = gedit_file_browser_utils_pixbuf_from_icon (icon, size);
|
||||
|
||||
g_object_unref (info);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
gchar *
|
||||
gedit_file_browser_utils_file_basename (GFile * file)
|
||||
{
|
||||
gchar *uri;
|
||||
gchar *ret;
|
||||
|
||||
uri = g_file_get_uri (file);
|
||||
ret = gedit_file_browser_utils_uri_basename (uri);
|
||||
g_free (uri);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
gchar *
|
||||
gedit_file_browser_utils_uri_basename (gchar const * uri)
|
||||
{
|
||||
return gedit_utils_basename_for_display (uri);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gedit_file_browser_utils_confirmation_dialog (GeditWindow * window,
|
||||
GtkMessageType type,
|
||||
gchar const *message,
|
||||
gchar const *secondary,
|
||||
gchar const * button_stock,
|
||||
gchar const * button_label)
|
||||
{
|
||||
GtkWidget *dlg;
|
||||
gint ret;
|
||||
GtkWidget *button;
|
||||
|
||||
dlg = gtk_message_dialog_new (GTK_WINDOW (window),
|
||||
GTK_DIALOG_MODAL |
|
||||
GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||
type,
|
||||
GTK_BUTTONS_NONE, "%s", message);
|
||||
|
||||
if (secondary)
|
||||
gtk_message_dialog_format_secondary_text
|
||||
(GTK_MESSAGE_DIALOG (dlg), "%s", secondary);
|
||||
|
||||
/* Add a cancel button */
|
||||
button = gtk_button_new_from_stock (GTK_STOCK_CANCEL);
|
||||
gtk_widget_show (button);
|
||||
|
||||
GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
|
||||
gtk_dialog_add_action_widget (GTK_DIALOG (dlg),
|
||||
button,
|
||||
GTK_RESPONSE_CANCEL);
|
||||
|
||||
/* Add custom button */
|
||||
button = gtk_button_new_from_stock (button_stock);
|
||||
|
||||
if (button_label) {
|
||||
gtk_button_set_use_stock (GTK_BUTTON (button), FALSE);
|
||||
gtk_button_set_label (GTK_BUTTON (button), button_label);
|
||||
}
|
||||
|
||||
gtk_widget_show (button);
|
||||
GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
|
||||
gtk_dialog_add_action_widget (GTK_DIALOG (dlg),
|
||||
button,
|
||||
GTK_RESPONSE_OK);
|
||||
|
||||
ret = gtk_dialog_run (GTK_DIALOG (dlg));
|
||||
gtk_widget_destroy (dlg);
|
||||
|
||||
return (ret == GTK_RESPONSE_OK);
|
||||
}
|
||||
|
||||
// ex:ts=8:noet:
|
27
plugins/filebrowser/gedit-file-browser-utils.h
Executable file
27
plugins/filebrowser/gedit-file-browser-utils.h
Executable file
@@ -0,0 +1,27 @@
|
||||
#ifndef __GEDIT_FILE_BROWSER_UTILS_H__
|
||||
#define __GEDIT_FILE_BROWSER_UTILS_H__
|
||||
|
||||
#include <gedit/gedit-window.h>
|
||||
#include <gio/gio.h>
|
||||
|
||||
GdkPixbuf *gedit_file_browser_utils_pixbuf_from_theme (gchar const *name,
|
||||
GtkIconSize size);
|
||||
|
||||
GdkPixbuf *gedit_file_browser_utils_pixbuf_from_icon (GIcon * icon,
|
||||
GtkIconSize size);
|
||||
GdkPixbuf *gedit_file_browser_utils_pixbuf_from_file (GFile * file,
|
||||
GtkIconSize size);
|
||||
|
||||
gchar * gedit_file_browser_utils_file_basename (GFile * file);
|
||||
gchar * gedit_file_browser_utils_uri_basename (gchar const * uri);
|
||||
|
||||
gboolean gedit_file_browser_utils_confirmation_dialog (GeditWindow * window,
|
||||
GtkMessageType type,
|
||||
gchar const *message,
|
||||
gchar const *secondary,
|
||||
gchar const * button_stock,
|
||||
gchar const * button_label);
|
||||
|
||||
#endif /* __GEDIT_FILE_BROWSER_UTILS_H__ */
|
||||
|
||||
// ex:ts=8:noet:
|
1256
plugins/filebrowser/gedit-file-browser-view.c
Executable file
1256
plugins/filebrowser/gedit-file-browser-view.c
Executable file
File diff suppressed because it is too large
Load Diff
84
plugins/filebrowser/gedit-file-browser-view.h
Executable file
84
plugins/filebrowser/gedit-file-browser-view.h
Executable file
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* gedit-file-browser-view.h - Gedit plugin providing easy file access
|
||||
* from the sidepanel
|
||||
*
|
||||
* Copyright (C) 2006 - Jesse van den Kieboom <jesse@icecrew.nl>
|
||||
*
|
||||
* 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 __GEDIT_FILE_BROWSER_VIEW_H__
|
||||
#define __GEDIT_FILE_BROWSER_VIEW_H__
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
#define GEDIT_TYPE_FILE_BROWSER_VIEW (gedit_file_browser_view_get_type ())
|
||||
#define GEDIT_FILE_BROWSER_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEDIT_TYPE_FILE_BROWSER_VIEW, GeditFileBrowserView))
|
||||
#define GEDIT_FILE_BROWSER_VIEW_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEDIT_TYPE_FILE_BROWSER_VIEW, GeditFileBrowserView const))
|
||||
#define GEDIT_FILE_BROWSER_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GEDIT_TYPE_FILE_BROWSER_VIEW, GeditFileBrowserViewClass))
|
||||
#define GEDIT_IS_FILE_BROWSER_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEDIT_TYPE_FILE_BROWSER_VIEW))
|
||||
#define GEDIT_IS_FILE_BROWSER_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GEDIT_TYPE_FILE_BROWSER_VIEW))
|
||||
#define GEDIT_FILE_BROWSER_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GEDIT_TYPE_FILE_BROWSER_VIEW, GeditFileBrowserViewClass))
|
||||
|
||||
typedef struct _GeditFileBrowserView GeditFileBrowserView;
|
||||
typedef struct _GeditFileBrowserViewClass GeditFileBrowserViewClass;
|
||||
typedef struct _GeditFileBrowserViewPrivate GeditFileBrowserViewPrivate;
|
||||
|
||||
typedef enum {
|
||||
GEDIT_FILE_BROWSER_VIEW_CLICK_POLICY_DOUBLE,
|
||||
GEDIT_FILE_BROWSER_VIEW_CLICK_POLICY_SINGLE
|
||||
} GeditFileBrowserViewClickPolicy;
|
||||
|
||||
struct _GeditFileBrowserView
|
||||
{
|
||||
GtkTreeView parent;
|
||||
|
||||
GeditFileBrowserViewPrivate *priv;
|
||||
};
|
||||
|
||||
struct _GeditFileBrowserViewClass
|
||||
{
|
||||
GtkTreeViewClass parent_class;
|
||||
|
||||
/* Signals */
|
||||
void (*error) (GeditFileBrowserView * filetree,
|
||||
guint code,
|
||||
gchar const *message);
|
||||
void (*file_activated) (GeditFileBrowserView * filetree,
|
||||
GtkTreeIter *iter);
|
||||
void (*directory_activated) (GeditFileBrowserView * filetree,
|
||||
GtkTreeIter *iter);
|
||||
void (*bookmark_activated) (GeditFileBrowserView * filetree,
|
||||
GtkTreeIter *iter);
|
||||
};
|
||||
|
||||
GType gedit_file_browser_view_get_type (void) G_GNUC_CONST;
|
||||
GType gedit_file_browser_view_register_type (GTypeModule * module);
|
||||
|
||||
GtkWidget *gedit_file_browser_view_new (void);
|
||||
void gedit_file_browser_view_set_model (GeditFileBrowserView * tree_view,
|
||||
GtkTreeModel * model);
|
||||
void gedit_file_browser_view_start_rename (GeditFileBrowserView * tree_view,
|
||||
GtkTreeIter * iter);
|
||||
void gedit_file_browser_view_set_click_policy (GeditFileBrowserView * tree_view,
|
||||
GeditFileBrowserViewClickPolicy policy);
|
||||
void gedit_file_browser_view_set_restore_expand_state (GeditFileBrowserView * tree_view,
|
||||
gboolean restore_expand_state);
|
||||
|
||||
G_END_DECLS
|
||||
#endif /* __GEDIT_FILE_BROWSER_VIEW_H__ */
|
||||
|
||||
// ex:ts=8:noet:
|
54
plugins/filebrowser/gedit-file-browser-widget-ui.xml
Executable file
54
plugins/filebrowser/gedit-file-browser-widget-ui.xml
Executable file
@@ -0,0 +1,54 @@
|
||||
<ui>
|
||||
<toolbar name="ToolBar">
|
||||
<placeholder name="Tool_Opt1"/>
|
||||
<toolitem action="DirectoryUp"/>
|
||||
<separator/>
|
||||
<toolitem action="DirectoryRefresh"/>
|
||||
<separator/>
|
||||
<placeholder name="Tool_Opt2"/>
|
||||
<separator/>
|
||||
<toolitem action="FilterHidden"/>
|
||||
<separator/>
|
||||
<placeholder name="Tool_Opt3"/>
|
||||
</toolbar>
|
||||
|
||||
<popup name="FilePopup" action="FilePopupAction">
|
||||
<menuitem action="FileOpen" />
|
||||
<placeholder name="FilePopup_Opt1" />
|
||||
<separator/>
|
||||
<menuitem action="DirectoryNew" />
|
||||
<menuitem action="FileNew" />
|
||||
<separator/>
|
||||
<placeholder name="FilePopup_Opt2" />
|
||||
<separator/>
|
||||
<menuitem action="FileRename"/>
|
||||
<menuitem action="FileMoveToTrash"/>
|
||||
<menuitem action="FileDelete"/>
|
||||
<separator/>
|
||||
<placeholder name="FilePopup_Opt3" />
|
||||
<separator/>
|
||||
<menuitem action="DirectoryRefresh"/>
|
||||
<menuitem action="DirectoryOpen"/>
|
||||
<placeholder name="FilePopup_Opt4" />
|
||||
<separator/>
|
||||
<placeholder name="FilePopup_Opt5" />
|
||||
<separator/>
|
||||
<menu name="FilterMenu" action="FilterMenuAction">
|
||||
<menuitem action="FilterHidden"/>
|
||||
<menuitem action="FilterBinary"/>
|
||||
</menu>
|
||||
<placeholder name="FilePopup_Opt6" />
|
||||
<separator/>
|
||||
</popup>
|
||||
|
||||
<popup name="BookmarkPopup" action="BookmarkPopupAction">
|
||||
<placeholder name="BookmarkPopup_Opt1" />
|
||||
<separator/>
|
||||
<placeholder name="BookmarkPopup_Opt2" />
|
||||
<separator/>
|
||||
<menuitem action="BookmarkOpen"/>
|
||||
<placeholder name="BookmarkPopup_Opt3" />
|
||||
<separator/>
|
||||
<placeholder name="BookmarkPopup_Opt4" />
|
||||
</popup>
|
||||
</ui>
|
3143
plugins/filebrowser/gedit-file-browser-widget.c
Executable file
3143
plugins/filebrowser/gedit-file-browser-widget.c
Executable file
File diff suppressed because it is too large
Load Diff
121
plugins/filebrowser/gedit-file-browser-widget.h
Executable file
121
plugins/filebrowser/gedit-file-browser-widget.h
Executable file
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* gedit-file-browser-widget.h - Gedit plugin providing easy file access
|
||||
* from the sidepanel
|
||||
*
|
||||
* Copyright (C) 2006 - Jesse van den Kieboom <jesse@icecrew.nl>
|
||||
*
|
||||
* 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 __GEDIT_FILE_BROWSER_WIDGET_H__
|
||||
#define __GEDIT_FILE_BROWSER_WIDGET_H__
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include "gedit-file-browser-store.h"
|
||||
#include "gedit-file-bookmarks-store.h"
|
||||
#include "gedit-file-browser-view.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
#define GEDIT_TYPE_FILE_BROWSER_WIDGET (gedit_file_browser_widget_get_type ())
|
||||
#define GEDIT_FILE_BROWSER_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEDIT_TYPE_FILE_BROWSER_WIDGET, GeditFileBrowserWidget))
|
||||
#define GEDIT_FILE_BROWSER_WIDGET_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEDIT_TYPE_FILE_BROWSER_WIDGET, GeditFileBrowserWidget const))
|
||||
#define GEDIT_FILE_BROWSER_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GEDIT_TYPE_FILE_BROWSER_WIDGET, GeditFileBrowserWidgetClass))
|
||||
#define GEDIT_IS_FILE_BROWSER_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEDIT_TYPE_FILE_BROWSER_WIDGET))
|
||||
#define GEDIT_IS_FILE_BROWSER_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GEDIT_TYPE_FILE_BROWSER_WIDGET))
|
||||
#define GEDIT_FILE_BROWSER_WIDGET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GEDIT_TYPE_FILE_BROWSER_WIDGET, GeditFileBrowserWidgetClass))
|
||||
|
||||
typedef struct _GeditFileBrowserWidget GeditFileBrowserWidget;
|
||||
typedef struct _GeditFileBrowserWidgetClass GeditFileBrowserWidgetClass;
|
||||
typedef struct _GeditFileBrowserWidgetPrivate GeditFileBrowserWidgetPrivate;
|
||||
|
||||
typedef
|
||||
gboolean (*GeditFileBrowserWidgetFilterFunc) (GeditFileBrowserWidget * obj,
|
||||
GeditFileBrowserStore *
|
||||
model, GtkTreeIter * iter,
|
||||
gpointer user_data);
|
||||
|
||||
struct _GeditFileBrowserWidget
|
||||
{
|
||||
GtkVBox parent;
|
||||
|
||||
GeditFileBrowserWidgetPrivate *priv;
|
||||
};
|
||||
|
||||
struct _GeditFileBrowserWidgetClass
|
||||
{
|
||||
GtkVBoxClass parent_class;
|
||||
|
||||
/* Signals */
|
||||
void (*uri_activated) (GeditFileBrowserWidget * widget,
|
||||
gchar const *uri);
|
||||
void (*error) (GeditFileBrowserWidget * widget,
|
||||
guint code,
|
||||
gchar const *message);
|
||||
gboolean (*confirm_delete) (GeditFileBrowserWidget * widget,
|
||||
GeditFileBrowserStore * model,
|
||||
GList *list);
|
||||
gboolean (*confirm_no_trash) (GeditFileBrowserWidget * widget,
|
||||
GList *list);
|
||||
};
|
||||
|
||||
GType gedit_file_browser_widget_get_type (void) G_GNUC_CONST;
|
||||
GType gedit_file_browser_widget_register_type (GTypeModule * module);
|
||||
|
||||
GtkWidget *gedit_file_browser_widget_new (const gchar *data_dir);
|
||||
|
||||
void gedit_file_browser_widget_show_bookmarks (GeditFileBrowserWidget * obj);
|
||||
void gedit_file_browser_widget_show_files (GeditFileBrowserWidget * obj);
|
||||
|
||||
void gedit_file_browser_widget_set_root (GeditFileBrowserWidget * obj,
|
||||
gchar const *root,
|
||||
gboolean virtual_root);
|
||||
void
|
||||
gedit_file_browser_widget_set_root_and_virtual_root (GeditFileBrowserWidget * obj,
|
||||
gchar const *root,
|
||||
gchar const *virtual_root);
|
||||
|
||||
gboolean
|
||||
gedit_file_browser_widget_get_selected_directory (GeditFileBrowserWidget * obj,
|
||||
GtkTreeIter * iter);
|
||||
|
||||
GeditFileBrowserStore *
|
||||
gedit_file_browser_widget_get_browser_store (GeditFileBrowserWidget * obj);
|
||||
GeditFileBookmarksStore *
|
||||
gedit_file_browser_widget_get_bookmarks_store (GeditFileBrowserWidget * obj);
|
||||
GeditFileBrowserView *
|
||||
gedit_file_browser_widget_get_browser_view (GeditFileBrowserWidget * obj);
|
||||
GtkWidget *
|
||||
gedit_file_browser_widget_get_filter_entry (GeditFileBrowserWidget * obj);
|
||||
|
||||
GtkUIManager *
|
||||
gedit_file_browser_widget_get_ui_manager (GeditFileBrowserWidget * obj);
|
||||
|
||||
gulong gedit_file_browser_widget_add_filter (GeditFileBrowserWidget * obj,
|
||||
GeditFileBrowserWidgetFilterFunc func,
|
||||
gpointer user_data,
|
||||
GDestroyNotify notify);
|
||||
void gedit_file_browser_widget_remove_filter (GeditFileBrowserWidget * obj,
|
||||
gulong id);
|
||||
void gedit_file_browser_widget_set_filter_pattern (GeditFileBrowserWidget * obj,
|
||||
gchar const *pattern);
|
||||
|
||||
void gedit_file_browser_widget_refresh (GeditFileBrowserWidget * obj);
|
||||
void gedit_file_browser_widget_history_back (GeditFileBrowserWidget * obj);
|
||||
void gedit_file_browser_widget_history_forward (GeditFileBrowserWidget * obj);
|
||||
|
||||
G_END_DECLS
|
||||
#endif /* __GEDIT_FILE_BROWSER_WIDGET_H__ */
|
||||
|
||||
// ex:ts=8:noet:
|
97
plugins/filebrowser/gedit-file-browser.schemas.in
Executable file
97
plugins/filebrowser/gedit-file-browser.schemas.in
Executable file
@@ -0,0 +1,97 @@
|
||||
<mateconfschemafile>
|
||||
<schemalist>
|
||||
<schema>
|
||||
<key>/schemas/apps/gedit-2/plugins/filebrowser/on_load/tree_view</key>
|
||||
<applyto>/apps/gedit-2/plugins/filebrowser/on_load/tree_view</applyto>
|
||||
<owner>gedit</owner>
|
||||
<type>bool</type>
|
||||
<default>TRUE</default>
|
||||
<locale name="C">
|
||||
<short>Open With Tree View</short>
|
||||
<long>Open the tree view when the file browser plugin gets loaded instead of the bookmarks view</long>
|
||||
</locale>
|
||||
</schema>
|
||||
|
||||
<schema>
|
||||
<key>/schemas/apps/gedit-2/plugins/filebrowser/on_load/root</key>
|
||||
<applyto>/apps/gedit-2/plugins/filebrowser/on_load/root</applyto>
|
||||
<owner>gedit</owner>
|
||||
<type>string</type>
|
||||
<default></default>
|
||||
<locale name="C">
|
||||
<short>File Browser Root Directory</short>
|
||||
<long>The file browser root directory to use when loading the file
|
||||
browser plugin and onload/tree_view is TRUE.</long>
|
||||
</locale>
|
||||
</schema>
|
||||
|
||||
<schema>
|
||||
<key>/schemas/apps/gedit-2/plugins/filebrowser/on_load/virtual_root</key>
|
||||
<applyto>/apps/gedit-2/plugins/filebrowser/on_load/virtual_root</applyto>
|
||||
<owner>gedit</owner>
|
||||
<type>string</type>
|
||||
<default></default>
|
||||
<locale name="C">
|
||||
<short>File Browser Virtual Root Directory</short>
|
||||
<long>The file browser virtual root directory to use when loading the
|
||||
file browser plugin when onload/tree_view is TRUE. The virtual root
|
||||
must always be below the actual root.</long>
|
||||
</locale>
|
||||
</schema>
|
||||
|
||||
<schema>
|
||||
<key>/schemas/apps/gedit-2/plugins/filebrowser/on_load/enable_remote</key>
|
||||
<applyto>/apps/gedit-2/plugins/filebrowser/on_load/enable_remote</applyto>
|
||||
<owner>gedit</owner>
|
||||
<type>bool</type>
|
||||
<default>FALSE</default>
|
||||
<locale name="C">
|
||||
<short>Enable Restore of Remote Locations</short>
|
||||
<long>Sets whether to enable restoring of remote locations.</long>
|
||||
</locale>
|
||||
</schema>
|
||||
|
||||
<schema>
|
||||
<key>/schemas/apps/gedit-2/plugins/filebrowser/open_at_first_doc</key>
|
||||
<applyto>/apps/gedit-2/plugins/filebrowser/open_at_first_doc</applyto>
|
||||
<owner>gedit</owner>
|
||||
<type>bool</type>
|
||||
<default>TRUE</default>
|
||||
<locale name="C">
|
||||
<short>Set Location to First Document</short>
|
||||
<long>If TRUE the file browser plugin will view the directory of
|
||||
the first opened document given that the file browser hasn't been
|
||||
used yet. (Thus this generally applies to opening a document from
|
||||
the command line or opening it with Caja, etc.)</long>
|
||||
</locale>
|
||||
</schema>
|
||||
|
||||
<schema>
|
||||
<key>/schemas/apps/gedit-2/plugins/filebrowser/filter_mode</key>
|
||||
<applyto>/apps/gedit-2/plugins/filebrowser/filter_mode</applyto>
|
||||
<owner>gedit</owner>
|
||||
<type>string</type>
|
||||
<default>hidden_and_binary</default>
|
||||
<locale name="C">
|
||||
<short>File Browser Filter Mode</short>
|
||||
<long>This value determines what files get filtered from the file
|
||||
browser. Valid values are: none (filter nothing),
|
||||
hidden (filter hidden files), binary (filter binary files) and
|
||||
hidden_and_binary (filter both hidden and binary files).</long>
|
||||
</locale>
|
||||
</schema>
|
||||
|
||||
<schema>
|
||||
<key>/schemas/apps/gedit-2/plugins/filebrowser/filter_pattern</key>
|
||||
<applyto>/apps/gedit-2/plugins/filebrowser/filter_pattern</applyto>
|
||||
<owner>gedit</owner>
|
||||
<type>string</type>
|
||||
<default></default>
|
||||
<locale name="C">
|
||||
<short>File Browser Filter Pattern</short>
|
||||
<long>The filter pattern to filter the file browser with. This filter
|
||||
works on top of the filter_mode.</long>
|
||||
</locale>
|
||||
</schema>
|
||||
</schemalist>
|
||||
</mateconfschemafile>
|
38
plugins/modelines/Makefile.am
Executable file
38
plugins/modelines/Makefile.am
Executable file
@@ -0,0 +1,38 @@
|
||||
# Modelines Plugin
|
||||
plugindir = $(GEDIT_PLUGINS_LIBS_DIR)
|
||||
|
||||
INCLUDES = \
|
||||
-I$(top_srcdir) \
|
||||
$(GEDIT_CFLAGS) \
|
||||
$(WARN_CFLAGS) \
|
||||
$(DISABLE_DEPRECATED_CFLAGS)
|
||||
|
||||
modelinesdir = $(GEDIT_PLUGINS_DATA_DIR)/modelines
|
||||
modelines_DATA = \
|
||||
language-mappings
|
||||
|
||||
plugin_LTLIBRARIES = libmodelines.la
|
||||
|
||||
libmodelines_la_SOURCES = \
|
||||
gedit-modeline-plugin.h \
|
||||
gedit-modeline-plugin.c \
|
||||
modeline-parser.h \
|
||||
modeline-parser.c
|
||||
|
||||
libmodelines_la_LDFLAGS = $(PLUGIN_LIBTOOL_FLAGS)
|
||||
libmodelines_la_LIBADD = $(GEDIT_LIBS)
|
||||
|
||||
plugin_in_files = modelines.gedit-plugin.desktop.in
|
||||
%.gedit-plugin: %.gedit-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:.gedit-plugin.desktop.in=.gedit-plugin)
|
||||
|
||||
EXTRA_DIST = \
|
||||
$(plugin_in_files) \
|
||||
$(modelines_DATA)
|
||||
|
||||
CLEANFILES = $(plugin_DATA)
|
||||
DISTCLEANFILES = $(plugin_DATA)
|
||||
|
||||
|
||||
-include $(top_srcdir)/git.mk
|
248
plugins/modelines/gedit-modeline-plugin.c
Executable file
248
plugins/modelines/gedit-modeline-plugin.c
Executable file
@@ -0,0 +1,248 @@
|
||||
/*
|
||||
* gedit-modeline-plugin.c
|
||||
* Emacs, Kate and Vim-style modelines support for gedit.
|
||||
*
|
||||
* Copyright (C) 2005-2007 - Steve Frécinaux <code@istique.net>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <glib/gi18n-lib.h>
|
||||
#include <gmodule.h>
|
||||
#include "gedit-modeline-plugin.h"
|
||||
#include "modeline-parser.h"
|
||||
|
||||
#include <gedit/gedit-debug.h>
|
||||
#include <gedit/gedit-utils.h>
|
||||
|
||||
#define WINDOW_DATA_KEY "GeditModelinePluginWindowData"
|
||||
#define DOCUMENT_DATA_KEY "GeditModelinePluginDocumentData"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
gulong tab_added_handler_id;
|
||||
gulong tab_removed_handler_id;
|
||||
} WindowData;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
gulong document_loaded_handler_id;
|
||||
gulong document_saved_handler_id;
|
||||
} DocumentData;
|
||||
|
||||
static void gedit_modeline_plugin_activate (GeditPlugin *plugin, GeditWindow *window);
|
||||
static void gedit_modeline_plugin_deactivate (GeditPlugin *plugin, GeditWindow *window);
|
||||
static GObject *gedit_modeline_plugin_constructor (GType type, guint n_construct_properties, GObjectConstructParam *construct_param);
|
||||
static void gedit_modeline_plugin_finalize (GObject *object);
|
||||
|
||||
GEDIT_PLUGIN_REGISTER_TYPE(GeditModelinePlugin, gedit_modeline_plugin)
|
||||
|
||||
static void
|
||||
window_data_free (WindowData *wdata)
|
||||
{
|
||||
g_slice_free (WindowData, wdata);
|
||||
}
|
||||
|
||||
static void
|
||||
document_data_free (DocumentData *ddata)
|
||||
{
|
||||
g_slice_free (DocumentData, ddata);
|
||||
}
|
||||
|
||||
static void
|
||||
gedit_modeline_plugin_class_init (GeditModelinePluginClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GeditPluginClass *plugin_class = GEDIT_PLUGIN_CLASS (klass);
|
||||
|
||||
object_class->constructor = gedit_modeline_plugin_constructor;
|
||||
object_class->finalize = gedit_modeline_plugin_finalize;
|
||||
|
||||
plugin_class->activate = gedit_modeline_plugin_activate;
|
||||
plugin_class->deactivate = gedit_modeline_plugin_deactivate;
|
||||
}
|
||||
|
||||
static GObject *
|
||||
gedit_modeline_plugin_constructor (GType type,
|
||||
guint n_construct_properties,
|
||||
GObjectConstructParam *construct_param)
|
||||
{
|
||||
GObject *object;
|
||||
gchar *data_dir;
|
||||
|
||||
object = G_OBJECT_CLASS (gedit_modeline_plugin_parent_class)->constructor (type,
|
||||
n_construct_properties,
|
||||
construct_param);
|
||||
|
||||
data_dir = gedit_plugin_get_data_dir (GEDIT_PLUGIN (object));
|
||||
|
||||
modeline_parser_init (data_dir);
|
||||
|
||||
g_free (data_dir);
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
static void
|
||||
gedit_modeline_plugin_init (GeditModelinePlugin *plugin)
|
||||
{
|
||||
gedit_debug_message (DEBUG_PLUGINS, "GeditModelinePlugin initializing");
|
||||
}
|
||||
|
||||
static void
|
||||
gedit_modeline_plugin_finalize (GObject *object)
|
||||
{
|
||||
gedit_debug_message (DEBUG_PLUGINS, "GeditModelinePlugin finalizing");
|
||||
|
||||
modeline_parser_shutdown ();
|
||||
|
||||
G_OBJECT_CLASS (gedit_modeline_plugin_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
on_document_loaded_or_saved (GeditDocument *document,
|
||||
const GError *error,
|
||||
GtkSourceView *view)
|
||||
{
|
||||
modeline_parser_apply_modeline (view);
|
||||
}
|
||||
|
||||
static void
|
||||
connect_handlers (GeditView *view)
|
||||
{
|
||||
DocumentData *data;
|
||||
GtkTextBuffer *doc;
|
||||
|
||||
doc = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
|
||||
|
||||
data = g_slice_new (DocumentData);
|
||||
|
||||
data->document_loaded_handler_id =
|
||||
g_signal_connect (doc, "loaded",
|
||||
G_CALLBACK (on_document_loaded_or_saved),
|
||||
view);
|
||||
data->document_saved_handler_id =
|
||||
g_signal_connect (doc, "saved",
|
||||
G_CALLBACK (on_document_loaded_or_saved),
|
||||
view);
|
||||
|
||||
g_object_set_data_full (G_OBJECT (doc), DOCUMENT_DATA_KEY,
|
||||
data, (GDestroyNotify) document_data_free);
|
||||
}
|
||||
|
||||
static void
|
||||
disconnect_handlers (GeditView *view)
|
||||
{
|
||||
DocumentData *data;
|
||||
GtkTextBuffer *doc;
|
||||
|
||||
doc = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
|
||||
|
||||
data = g_object_steal_data (G_OBJECT (doc), DOCUMENT_DATA_KEY);
|
||||
|
||||
if (data)
|
||||
{
|
||||
g_signal_handler_disconnect (doc, data->document_loaded_handler_id);
|
||||
g_signal_handler_disconnect (doc, data->document_saved_handler_id);
|
||||
|
||||
document_data_free (data);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_warning ("Modeline handlers not found");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
on_window_tab_added (GeditWindow *window,
|
||||
GeditTab *tab,
|
||||
gpointer user_data)
|
||||
{
|
||||
connect_handlers (gedit_tab_get_view (tab));
|
||||
}
|
||||
|
||||
static void
|
||||
on_window_tab_removed (GeditWindow *window,
|
||||
GeditTab *tab,
|
||||
gpointer user_data)
|
||||
{
|
||||
disconnect_handlers (gedit_tab_get_view (tab));
|
||||
}
|
||||
|
||||
static void
|
||||
gedit_modeline_plugin_activate (GeditPlugin *plugin,
|
||||
GeditWindow *window)
|
||||
{
|
||||
WindowData *wdata;
|
||||
GList *views;
|
||||
GList *l;
|
||||
|
||||
gedit_debug (DEBUG_PLUGINS);
|
||||
|
||||
views = gedit_window_get_views (window);
|
||||
for (l = views; l != NULL; l = l->next)
|
||||
{
|
||||
connect_handlers (GEDIT_VIEW (l->data));
|
||||
modeline_parser_apply_modeline (GTK_SOURCE_VIEW (l->data));
|
||||
}
|
||||
g_list_free (views);
|
||||
|
||||
wdata = g_slice_new (WindowData);
|
||||
|
||||
wdata->tab_added_handler_id =
|
||||
g_signal_connect (window, "tab-added",
|
||||
G_CALLBACK (on_window_tab_added), NULL);
|
||||
|
||||
wdata->tab_removed_handler_id =
|
||||
g_signal_connect (window, "tab-removed",
|
||||
G_CALLBACK (on_window_tab_removed), NULL);
|
||||
|
||||
g_object_set_data_full (G_OBJECT (window), WINDOW_DATA_KEY,
|
||||
wdata, (GDestroyNotify) window_data_free);
|
||||
}
|
||||
|
||||
static void
|
||||
gedit_modeline_plugin_deactivate (GeditPlugin *plugin,
|
||||
GeditWindow *window)
|
||||
{
|
||||
WindowData *wdata;
|
||||
GList *views;
|
||||
GList *l;
|
||||
|
||||
gedit_debug (DEBUG_PLUGINS);
|
||||
|
||||
wdata = g_object_steal_data (G_OBJECT (window), WINDOW_DATA_KEY);
|
||||
|
||||
g_signal_handler_disconnect (window, wdata->tab_added_handler_id);
|
||||
g_signal_handler_disconnect (window, wdata->tab_removed_handler_id);
|
||||
|
||||
window_data_free (wdata);
|
||||
|
||||
views = gedit_window_get_views (window);
|
||||
|
||||
for (l = views; l != NULL; l = l->next)
|
||||
{
|
||||
disconnect_handlers (GEDIT_VIEW (l->data));
|
||||
|
||||
modeline_parser_deactivate (GTK_SOURCE_VIEW (l->data));
|
||||
}
|
||||
|
||||
g_list_free (views);
|
||||
}
|
||||
|
48
plugins/modelines/gedit-modeline-plugin.h
Executable file
48
plugins/modelines/gedit-modeline-plugin.h
Executable file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* gedit-modeline-plugin.h
|
||||
* Emacs, Kate and Vim-style modelines support for gedit.
|
||||
*
|
||||
* Copyright (C) 2005-2007 - Steve Frécinaux <code@istique.net>
|
||||
*
|
||||
* 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 __GEDIT_MODELINE_PLUGIN_H__
|
||||
#define __GEDIT_MODELINE_PLUGIN_H__
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
#include <gedit/gedit-plugin.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GEDIT_TYPE_MODELINE_PLUGIN (gedit_modeline_plugin_get_type ())
|
||||
#define GEDIT_MODELINE_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GEDIT_TYPE_MODELINE_PLUGIN, GeditModelinePlugin))
|
||||
#define GEDIT_MODELINE_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GEDIT_TYPE_MODELINE_PLUGIN, GeditModelinePluginClass))
|
||||
#define GEDIT_IS_MODELINE_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GEDIT_TYPE_MODELINE_PLUGIN))
|
||||
#define GEDIT_IS_MODELINE_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GEDIT_TYPE_MODELINE_PLUGIN))
|
||||
#define GEDIT_MODELINE_PLUGIN_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GEDIT_TYPE_MODELINE_PLUGIN, GeditModelinePluginClass))
|
||||
|
||||
/* Private structure type */
|
||||
typedef GeditPluginClass GeditModelinePluginClass;
|
||||
typedef GeditPlugin GeditModelinePlugin;
|
||||
|
||||
GType gedit_modeline_plugin_get_type (void) G_GNUC_CONST;
|
||||
|
||||
G_MODULE_EXPORT GType register_gedit_plugin (GTypeModule *module);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GEDIT_MODELINE_PLUGIN_H__ */
|
14
plugins/modelines/language-mappings
Executable file
14
plugins/modelines/language-mappings
Executable file
@@ -0,0 +1,14 @@
|
||||
[vim]
|
||||
cs=c-sharp
|
||||
docbk=docbook
|
||||
javascript=js
|
||||
lhaskell=haskell-literate
|
||||
spec=rpmspec
|
||||
tex=latex
|
||||
xhtml=html
|
||||
|
||||
[emacs]
|
||||
c++=cpp
|
||||
|
||||
[kate]
|
||||
|
852
plugins/modelines/modeline-parser.c
Executable file
852
plugins/modelines/modeline-parser.c
Executable file
@@ -0,0 +1,852 @@
|
||||
/*
|
||||
* modeline-parser.c
|
||||
* Emacs, Kate and Vim-style modelines support for gedit.
|
||||
*
|
||||
* Copyright (C) 2005-2007 - Steve Frécinaux <code@istique.net>
|
||||
*
|
||||
* 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 <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <gedit/gedit-language-manager.h>
|
||||
#include <gedit/gedit-prefs-manager.h>
|
||||
#include <gedit/gedit-debug.h>
|
||||
#include "modeline-parser.h"
|
||||
|
||||
#define MODELINES_LANGUAGE_MAPPINGS_FILE "language-mappings"
|
||||
|
||||
/* base dir to lookup configuration files */
|
||||
static gchar *modelines_data_dir;
|
||||
|
||||
/* Mappings: language name -> Gedit language ID */
|
||||
static GHashTable *vim_languages;
|
||||
static GHashTable *emacs_languages;
|
||||
static GHashTable *kate_languages;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MODELINE_SET_NONE = 0,
|
||||
MODELINE_SET_TAB_WIDTH = 1 << 0,
|
||||
MODELINE_SET_INDENT_WIDTH = 1 << 1,
|
||||
MODELINE_SET_WRAP_MODE = 1 << 2,
|
||||
MODELINE_SET_SHOW_RIGHT_MARGIN = 1 << 3,
|
||||
MODELINE_SET_RIGHT_MARGIN_POSITION = 1 << 4,
|
||||
MODELINE_SET_LANGUAGE = 1 << 5,
|
||||
MODELINE_SET_INSERT_SPACES = 1 << 6
|
||||
} ModelineSet;
|
||||
|
||||
typedef struct _ModelineOptions
|
||||
{
|
||||
gchar *language_id;
|
||||
|
||||
/* these options are similar to the GtkSourceView properties of the
|
||||
* same names.
|
||||
*/
|
||||
gboolean insert_spaces;
|
||||
guint tab_width;
|
||||
guint indent_width;
|
||||
GtkWrapMode wrap_mode;
|
||||
gboolean display_right_margin;
|
||||
guint right_margin_position;
|
||||
|
||||
ModelineSet set;
|
||||
} ModelineOptions;
|
||||
|
||||
#define MODELINE_OPTIONS_DATA_KEY "ModelineOptionsDataKey"
|
||||
|
||||
static gboolean
|
||||
has_option (ModelineOptions *options,
|
||||
ModelineSet set)
|
||||
{
|
||||
return options->set & set;
|
||||
}
|
||||
|
||||
void
|
||||
modeline_parser_init (const gchar *data_dir)
|
||||
{
|
||||
modelines_data_dir = g_strdup (data_dir);
|
||||
}
|
||||
|
||||
void
|
||||
modeline_parser_shutdown ()
|
||||
{
|
||||
if (vim_languages != NULL)
|
||||
g_hash_table_destroy (vim_languages);
|
||||
|
||||
if (emacs_languages != NULL)
|
||||
g_hash_table_destroy (emacs_languages);
|
||||
|
||||
if (kate_languages != NULL)
|
||||
g_hash_table_destroy (kate_languages);
|
||||
|
||||
vim_languages = NULL;
|
||||
emacs_languages = NULL;
|
||||
kate_languages = NULL;
|
||||
|
||||
g_free (modelines_data_dir);
|
||||
}
|
||||
|
||||
static GHashTable *
|
||||
load_language_mappings_group (GKeyFile *key_file, const gchar *group)
|
||||
{
|
||||
GHashTable *table;
|
||||
gchar **keys;
|
||||
gsize length = 0;
|
||||
int i;
|
||||
|
||||
table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
|
||||
|
||||
keys = g_key_file_get_keys (key_file, group, &length, NULL);
|
||||
|
||||
gedit_debug_message (DEBUG_PLUGINS,
|
||||
"%" G_GSIZE_FORMAT " mappings in group %s",
|
||||
length, group);
|
||||
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
gchar *name = keys[i];
|
||||
gchar *id = g_key_file_get_string (key_file, group, name, NULL);
|
||||
g_hash_table_insert (table, name, id);
|
||||
}
|
||||
g_free (keys);
|
||||
|
||||
return table;
|
||||
}
|
||||
|
||||
/* lazy loading of language mappings */
|
||||
static void
|
||||
load_language_mappings (void)
|
||||
{
|
||||
gchar *fname;
|
||||
GKeyFile *mappings;
|
||||
GError *error = NULL;
|
||||
|
||||
fname = g_build_filename (modelines_data_dir,
|
||||
MODELINES_LANGUAGE_MAPPINGS_FILE,
|
||||
NULL);
|
||||
|
||||
mappings = g_key_file_new ();
|
||||
|
||||
if (g_key_file_load_from_file (mappings, fname, 0, &error))
|
||||
{
|
||||
gedit_debug_message (DEBUG_PLUGINS,
|
||||
"Loaded language mappings from %s",
|
||||
fname);
|
||||
|
||||
vim_languages = load_language_mappings_group (mappings, "vim");
|
||||
emacs_languages = load_language_mappings_group (mappings, "emacs");
|
||||
kate_languages = load_language_mappings_group (mappings, "kate");
|
||||
}
|
||||
else
|
||||
{
|
||||
gedit_debug_message (DEBUG_PLUGINS,
|
||||
"Failed to loaded language mappings from %s: %s",
|
||||
fname, error->message);
|
||||
|
||||
g_error_free (error);
|
||||
}
|
||||
|
||||
g_key_file_free (mappings);
|
||||
g_free (fname);
|
||||
}
|
||||
|
||||
static gchar *
|
||||
get_language_id (const gchar *language_name, GHashTable *mapping)
|
||||
{
|
||||
gchar *name;
|
||||
gchar *language_id;
|
||||
|
||||
name = g_ascii_strdown (language_name, -1);
|
||||
|
||||
language_id = g_hash_table_lookup (mapping, name);
|
||||
|
||||
if (language_id != NULL)
|
||||
{
|
||||
g_free (name);
|
||||
return g_strdup (language_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* by default assume that the gtksourcevuew id is the same */
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
static gchar *
|
||||
get_language_id_vim (const gchar *language_name)
|
||||
{
|
||||
if (vim_languages == NULL)
|
||||
load_language_mappings ();
|
||||
|
||||
return get_language_id (language_name, vim_languages);
|
||||
}
|
||||
|
||||
static gchar *
|
||||
get_language_id_emacs (const gchar *language_name)
|
||||
{
|
||||
if (emacs_languages == NULL)
|
||||
load_language_mappings ();
|
||||
|
||||
return get_language_id (language_name, emacs_languages);
|
||||
}
|
||||
|
||||
static gchar *
|
||||
get_language_id_kate (const gchar *language_name)
|
||||
{
|
||||
if (kate_languages == NULL)
|
||||
load_language_mappings ();
|
||||
|
||||
return get_language_id (language_name, kate_languages);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
skip_whitespaces (gchar **s)
|
||||
{
|
||||
while (**s != '\0' && g_ascii_isspace (**s))
|
||||
(*s)++;
|
||||
return **s != '\0';
|
||||
}
|
||||
|
||||
/* Parse vi(m) modelines.
|
||||
* Vi(m) modelines looks like this:
|
||||
* - first form: [text]{white}{vi:|vim:|ex:}[white]{options}
|
||||
* - second form: [text]{white}{vi:|vim:|ex:}[white]se[t] {options}:[text]
|
||||
* They can happen on the three first or last lines.
|
||||
*/
|
||||
static gchar *
|
||||
parse_vim_modeline (gchar *s,
|
||||
ModelineOptions *options)
|
||||
{
|
||||
gboolean in_set = FALSE;
|
||||
gboolean neg;
|
||||
guint intval;
|
||||
GString *key, *value;
|
||||
|
||||
key = g_string_sized_new (8);
|
||||
value = g_string_sized_new (8);
|
||||
|
||||
while (*s != '\0' && !(in_set && *s == ':'))
|
||||
{
|
||||
while (*s != '\0' && (*s == ':' || g_ascii_isspace (*s)))
|
||||
s++;
|
||||
|
||||
if (*s == '\0')
|
||||
break;
|
||||
|
||||
if (strncmp (s, "set ", 4) == 0 ||
|
||||
strncmp (s, "se ", 3) == 0)
|
||||
{
|
||||
s = strchr(s, ' ') + 1;
|
||||
in_set = TRUE;
|
||||
}
|
||||
|
||||
neg = FALSE;
|
||||
if (strncmp (s, "no", 2) == 0)
|
||||
{
|
||||
neg = TRUE;
|
||||
s += 2;
|
||||
}
|
||||
|
||||
g_string_assign (key, "");
|
||||
g_string_assign (value, "");
|
||||
|
||||
while (*s != '\0' && *s != ':' && *s != '=' &&
|
||||
!g_ascii_isspace (*s))
|
||||
{
|
||||
g_string_append_c (key, *s);
|
||||
s++;
|
||||
}
|
||||
|
||||
if (*s == '=')
|
||||
{
|
||||
s++;
|
||||
while (*s != '\0' && *s != ':' &&
|
||||
!g_ascii_isspace (*s))
|
||||
{
|
||||
g_string_append_c (value, *s);
|
||||
s++;
|
||||
}
|
||||
}
|
||||
|
||||
if (strcmp (key->str, "ft") == 0 ||
|
||||
strcmp (key->str, "filetype") == 0)
|
||||
{
|
||||
g_free (options->language_id);
|
||||
options->language_id = get_language_id_vim (value->str);
|
||||
|
||||
options->set |= MODELINE_SET_LANGUAGE;
|
||||
}
|
||||
else if (strcmp (key->str, "et") == 0 ||
|
||||
strcmp (key->str, "expandtab") == 0)
|
||||
{
|
||||
options->insert_spaces = !neg;
|
||||
options->set |= MODELINE_SET_INSERT_SPACES;
|
||||
}
|
||||
else if (strcmp (key->str, "ts") == 0 ||
|
||||
strcmp (key->str, "tabstop") == 0)
|
||||
{
|
||||
intval = atoi (value->str);
|
||||
|
||||
if (intval)
|
||||
{
|
||||
options->tab_width = intval;
|
||||
options->set |= MODELINE_SET_TAB_WIDTH;
|
||||
}
|
||||
}
|
||||
else if (strcmp (key->str, "sw") == 0 ||
|
||||
strcmp (key->str, "shiftwidth") == 0)
|
||||
{
|
||||
intval = atoi (value->str);
|
||||
|
||||
if (intval)
|
||||
{
|
||||
options->indent_width = intval;
|
||||
options->set |= MODELINE_SET_INDENT_WIDTH;
|
||||
}
|
||||
}
|
||||
else if (strcmp (key->str, "wrap") == 0)
|
||||
{
|
||||
options->wrap_mode = neg ? GTK_WRAP_NONE : GTK_WRAP_WORD;
|
||||
|
||||
options->set |= MODELINE_SET_WRAP_MODE;
|
||||
}
|
||||
else if (strcmp (key->str, "textwidth") == 0)
|
||||
{
|
||||
intval = atoi (value->str);
|
||||
|
||||
if (intval)
|
||||
{
|
||||
options->right_margin_position = intval;
|
||||
options->display_right_margin = TRUE;
|
||||
|
||||
options->set |= MODELINE_SET_SHOW_RIGHT_MARGIN |
|
||||
MODELINE_SET_RIGHT_MARGIN_POSITION;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g_string_free (key, TRUE);
|
||||
g_string_free (value, TRUE);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
/* Parse emacs modelines.
|
||||
* Emacs modelines looks like this: "-*- key1: value1; key2: value2 -*-"
|
||||
* They can happen on the first line, or on the second one if the first line is
|
||||
* a shebang (#!)
|
||||
* See http://www.delorie.com/gnu/docs/emacs/emacs_486.html
|
||||
*/
|
||||
static gchar *
|
||||
parse_emacs_modeline (gchar *s,
|
||||
ModelineOptions *options)
|
||||
{
|
||||
guint intval;
|
||||
GString *key, *value;
|
||||
|
||||
key = g_string_sized_new (8);
|
||||
value = g_string_sized_new (8);
|
||||
|
||||
while (*s != '\0')
|
||||
{
|
||||
while (*s != '\0' && (*s == ';' || g_ascii_isspace (*s)))
|
||||
s++;
|
||||
if (*s == '\0' || strncmp (s, "-*-", 3) == 0)
|
||||
break;
|
||||
|
||||
g_string_assign (key, "");
|
||||
g_string_assign (value, "");
|
||||
|
||||
while (*s != '\0' && *s != ':' && *s != ';' &&
|
||||
!g_ascii_isspace (*s))
|
||||
{
|
||||
g_string_append_c (key, *s);
|
||||
s++;
|
||||
}
|
||||
|
||||
if (!skip_whitespaces (&s))
|
||||
break;
|
||||
|
||||
if (*s != ':')
|
||||
continue;
|
||||
s++;
|
||||
|
||||
if (!skip_whitespaces (&s))
|
||||
break;
|
||||
|
||||
while (*s != '\0' && *s != ';' && !g_ascii_isspace (*s))
|
||||
{
|
||||
g_string_append_c (value, *s);
|
||||
s++;
|
||||
}
|
||||
|
||||
gedit_debug_message (DEBUG_PLUGINS,
|
||||
"Emacs modeline bit: %s = %s",
|
||||
key->str, value->str);
|
||||
|
||||
/* "Mode" key is case insenstive */
|
||||
if (g_ascii_strcasecmp (key->str, "Mode") == 0)
|
||||
{
|
||||
g_free (options->language_id);
|
||||
options->language_id = get_language_id_emacs (value->str);
|
||||
|
||||
options->set |= MODELINE_SET_LANGUAGE;
|
||||
}
|
||||
else if (strcmp (key->str, "tab-width") == 0)
|
||||
{
|
||||
intval = atoi (value->str);
|
||||
|
||||
if (intval)
|
||||
{
|
||||
options->tab_width = intval;
|
||||
options->set |= MODELINE_SET_TAB_WIDTH;
|
||||
}
|
||||
}
|
||||
else if (strcmp (key->str, "indent-offset") == 0)
|
||||
{
|
||||
intval = atoi (value->str);
|
||||
|
||||
if (intval)
|
||||
{
|
||||
options->indent_width = intval;
|
||||
options->set |= MODELINE_SET_INDENT_WIDTH;
|
||||
}
|
||||
}
|
||||
else if (strcmp (key->str, "indent-tabs-mode") == 0)
|
||||
{
|
||||
intval = strcmp (value->str, "nil") == 0;
|
||||
options->insert_spaces = intval;
|
||||
|
||||
options->set |= MODELINE_SET_INSERT_SPACES;
|
||||
}
|
||||
else if (strcmp (key->str, "autowrap") == 0)
|
||||
{
|
||||
intval = strcmp (value->str, "nil") != 0;
|
||||
options->wrap_mode = intval ? GTK_WRAP_WORD : GTK_WRAP_NONE;
|
||||
|
||||
options->set |= MODELINE_SET_WRAP_MODE;
|
||||
}
|
||||
}
|
||||
|
||||
g_string_free (key, TRUE);
|
||||
g_string_free (value, TRUE);
|
||||
|
||||
return *s == '\0' ? s : s + 2;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse kate modelines.
|
||||
* Kate modelines are of the form "kate: key1 value1; key2 value2;"
|
||||
* These can happen on the 10 first or 10 last lines of the buffer.
|
||||
* See http://wiki.kate-editor.org/index.php/Modelines
|
||||
*/
|
||||
static gchar *
|
||||
parse_kate_modeline (gchar *s,
|
||||
ModelineOptions *options)
|
||||
{
|
||||
guint intval;
|
||||
GString *key, *value;
|
||||
|
||||
key = g_string_sized_new (8);
|
||||
value = g_string_sized_new (8);
|
||||
|
||||
while (*s != '\0')
|
||||
{
|
||||
while (*s != '\0' && (*s == ';' || g_ascii_isspace (*s)))
|
||||
s++;
|
||||
if (*s == '\0')
|
||||
break;
|
||||
|
||||
g_string_assign (key, "");
|
||||
g_string_assign (value, "");
|
||||
|
||||
while (*s != '\0' && *s != ';' && !g_ascii_isspace (*s))
|
||||
{
|
||||
g_string_append_c (key, *s);
|
||||
s++;
|
||||
}
|
||||
|
||||
if (!skip_whitespaces (&s))
|
||||
break;
|
||||
if (*s == ';')
|
||||
continue;
|
||||
|
||||
while (*s != '\0' && *s != ';' &&
|
||||
!g_ascii_isspace (*s))
|
||||
{
|
||||
g_string_append_c (value, *s);
|
||||
s++;
|
||||
}
|
||||
|
||||
gedit_debug_message (DEBUG_PLUGINS,
|
||||
"Kate modeline bit: %s = %s",
|
||||
key->str, value->str);
|
||||
|
||||
if (strcmp (key->str, "hl") == 0 ||
|
||||
strcmp (key->str, "syntax") == 0)
|
||||
{
|
||||
g_free (options->language_id);
|
||||
options->language_id = get_language_id_kate (value->str);
|
||||
|
||||
options->set |= MODELINE_SET_LANGUAGE;
|
||||
}
|
||||
else if (strcmp (key->str, "tab-width") == 0)
|
||||
{
|
||||
intval = atoi (value->str);
|
||||
|
||||
if (intval)
|
||||
{
|
||||
options->tab_width = intval;
|
||||
options->set |= MODELINE_SET_TAB_WIDTH;
|
||||
}
|
||||
}
|
||||
else if (strcmp (key->str, "indent-width") == 0)
|
||||
{
|
||||
intval = atoi (value->str);
|
||||
if (intval) options->indent_width = intval;
|
||||
}
|
||||
else if (strcmp (key->str, "space-indent") == 0)
|
||||
{
|
||||
intval = strcmp (value->str, "on") == 0 ||
|
||||
strcmp (value->str, "true") == 0 ||
|
||||
strcmp (value->str, "1") == 0;
|
||||
|
||||
options->insert_spaces = intval;
|
||||
options->set |= MODELINE_SET_INSERT_SPACES;
|
||||
}
|
||||
else if (strcmp (key->str, "word-wrap") == 0)
|
||||
{
|
||||
intval = strcmp (value->str, "on") == 0 ||
|
||||
strcmp (value->str, "true") == 0 ||
|
||||
strcmp (value->str, "1") == 0;
|
||||
|
||||
options->wrap_mode = intval ? GTK_WRAP_WORD : GTK_WRAP_NONE;
|
||||
|
||||
options->set |= MODELINE_SET_WRAP_MODE;
|
||||
}
|
||||
else if (strcmp (key->str, "word-wrap-column") == 0)
|
||||
{
|
||||
intval = atoi (value->str);
|
||||
|
||||
if (intval)
|
||||
{
|
||||
options->right_margin_position = intval;
|
||||
options->display_right_margin = TRUE;
|
||||
|
||||
options->set |= MODELINE_SET_RIGHT_MARGIN_POSITION |
|
||||
MODELINE_SET_SHOW_RIGHT_MARGIN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g_string_free (key, TRUE);
|
||||
g_string_free (value, TRUE);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
/* Scan a line for vi(m)/emacs/kate modelines.
|
||||
* Line numbers are counted starting at one.
|
||||
*/
|
||||
static void
|
||||
parse_modeline (gchar *s,
|
||||
gint line_number,
|
||||
gint line_count,
|
||||
ModelineOptions *options)
|
||||
{
|
||||
gchar prev;
|
||||
|
||||
/* look for the beginning of a modeline */
|
||||
for (prev = ' '; (s != NULL) && (*s != '\0'); prev = *(s++))
|
||||
{
|
||||
if (!g_ascii_isspace (prev))
|
||||
continue;
|
||||
|
||||
if ((line_number <= 3 || line_number > line_count - 3) &&
|
||||
(strncmp (s, "ex:", 3) == 0 ||
|
||||
strncmp (s, "vi:", 3) == 0 ||
|
||||
strncmp (s, "vim:", 4) == 0))
|
||||
{
|
||||
gedit_debug_message (DEBUG_PLUGINS, "Vim modeline on line %d", line_number);
|
||||
|
||||
while (*s != ':') s++;
|
||||
s = parse_vim_modeline (s + 1, options);
|
||||
}
|
||||
else if (line_number <= 2 && strncmp (s, "-*-", 3) == 0)
|
||||
{
|
||||
gedit_debug_message (DEBUG_PLUGINS, "Emacs modeline on line %d", line_number);
|
||||
|
||||
s = parse_emacs_modeline (s + 3, options);
|
||||
}
|
||||
else if ((line_number <= 10 || line_number > line_count - 10) &&
|
||||
strncmp (s, "kate:", 5) == 0)
|
||||
{
|
||||
gedit_debug_message (DEBUG_PLUGINS, "Kate modeline on line %d", line_number);
|
||||
|
||||
s = parse_kate_modeline (s + 5, options);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
check_previous (GtkSourceView *view,
|
||||
ModelineOptions *previous,
|
||||
ModelineSet set)
|
||||
{
|
||||
GtkSourceBuffer *buffer = GTK_SOURCE_BUFFER (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)));
|
||||
|
||||
/* Do not restore default when this is the first time */
|
||||
if (!previous)
|
||||
return FALSE;
|
||||
|
||||
/* Do not restore default when previous was not set */
|
||||
if (!(previous->set & set))
|
||||
return FALSE;
|
||||
|
||||
/* Only restore default when setting has not changed */
|
||||
switch (set)
|
||||
{
|
||||
case MODELINE_SET_INSERT_SPACES:
|
||||
return gtk_source_view_get_insert_spaces_instead_of_tabs (view) ==
|
||||
previous->insert_spaces;
|
||||
break;
|
||||
case MODELINE_SET_TAB_WIDTH:
|
||||
return gtk_source_view_get_tab_width (view) == previous->tab_width;
|
||||
break;
|
||||
case MODELINE_SET_INDENT_WIDTH:
|
||||
return gtk_source_view_get_indent_width (view) == previous->indent_width;
|
||||
break;
|
||||
case MODELINE_SET_WRAP_MODE:
|
||||
return gtk_text_view_get_wrap_mode (GTK_TEXT_VIEW (view)) ==
|
||||
previous->wrap_mode;
|
||||
break;
|
||||
case MODELINE_SET_RIGHT_MARGIN_POSITION:
|
||||
return gtk_source_view_get_right_margin_position (view) ==
|
||||
previous->right_margin_position;
|
||||
break;
|
||||
case MODELINE_SET_SHOW_RIGHT_MARGIN:
|
||||
return gtk_source_view_get_show_right_margin (view) ==
|
||||
previous->display_right_margin;
|
||||
break;
|
||||
case MODELINE_SET_LANGUAGE:
|
||||
{
|
||||
GtkSourceLanguage *language = gtk_source_buffer_get_language (buffer);
|
||||
|
||||
return (language == NULL && previous->language_id == NULL) ||
|
||||
(language != NULL && g_strcmp0 (gtk_source_language_get_id (language),
|
||||
previous->language_id) == 0);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
free_modeline_options (ModelineOptions *options)
|
||||
{
|
||||
g_free (options->language_id);
|
||||
g_slice_free (ModelineOptions, options);
|
||||
}
|
||||
|
||||
void
|
||||
modeline_parser_apply_modeline (GtkSourceView *view)
|
||||
{
|
||||
ModelineOptions options;
|
||||
GtkTextBuffer *buffer;
|
||||
GtkTextIter iter, liter;
|
||||
gint line_count;
|
||||
|
||||
options.language_id = NULL;
|
||||
options.set = MODELINE_SET_NONE;
|
||||
|
||||
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
|
||||
gtk_text_buffer_get_start_iter (buffer, &iter);
|
||||
|
||||
line_count = gtk_text_buffer_get_line_count (buffer);
|
||||
|
||||
/* Parse the modelines on the 10 first lines... */
|
||||
while ((gtk_text_iter_get_line (&iter) < 10) &&
|
||||
!gtk_text_iter_is_end (&iter))
|
||||
{
|
||||
gchar *line;
|
||||
|
||||
liter = iter;
|
||||
gtk_text_iter_forward_to_line_end (&iter);
|
||||
line = gtk_text_buffer_get_text (buffer, &liter, &iter, TRUE);
|
||||
|
||||
parse_modeline (line,
|
||||
1 + gtk_text_iter_get_line (&iter),
|
||||
line_count,
|
||||
&options);
|
||||
|
||||
gtk_text_iter_forward_line (&iter);
|
||||
|
||||
g_free (line);
|
||||
}
|
||||
|
||||
/* ...and on the 10 last ones (modelines are not allowed in between) */
|
||||
if (!gtk_text_iter_is_end (&iter))
|
||||
{
|
||||
gint cur_line;
|
||||
guint remaining_lines;
|
||||
|
||||
/* we are on the 11th line (count from 0) */
|
||||
cur_line = gtk_text_iter_get_line (&iter);
|
||||
/* g_assert (10 == cur_line); */
|
||||
|
||||
remaining_lines = line_count - cur_line - 1;
|
||||
|
||||
if (remaining_lines > 10)
|
||||
{
|
||||
gtk_text_buffer_get_end_iter (buffer, &iter);
|
||||
gtk_text_iter_backward_lines (&iter, 9);
|
||||
}
|
||||
}
|
||||
|
||||
while (!gtk_text_iter_is_end (&iter))
|
||||
{
|
||||
gchar *line;
|
||||
|
||||
liter = iter;
|
||||
gtk_text_iter_forward_to_line_end (&iter);
|
||||
line = gtk_text_buffer_get_text (buffer, &liter, &iter, TRUE);
|
||||
|
||||
parse_modeline (line,
|
||||
1 + gtk_text_iter_get_line (&iter),
|
||||
line_count,
|
||||
&options);
|
||||
|
||||
gtk_text_iter_forward_line (&iter);
|
||||
|
||||
g_free (line);
|
||||
}
|
||||
|
||||
/* Try to set language */
|
||||
if (has_option (&options, MODELINE_SET_LANGUAGE) && options.language_id)
|
||||
{
|
||||
GtkSourceLanguageManager *manager;
|
||||
GtkSourceLanguage *language;
|
||||
|
||||
manager = gedit_get_language_manager ();
|
||||
language = gtk_source_language_manager_get_language
|
||||
(manager, options.language_id);
|
||||
|
||||
if (language != NULL)
|
||||
{
|
||||
gtk_source_buffer_set_language (GTK_SOURCE_BUFFER (buffer),
|
||||
language);
|
||||
}
|
||||
}
|
||||
|
||||
ModelineOptions *previous = g_object_get_data (G_OBJECT (buffer),
|
||||
MODELINE_OPTIONS_DATA_KEY);
|
||||
|
||||
/* Apply the options we got from modelines and restore defaults if
|
||||
we set them before */
|
||||
if (has_option (&options, MODELINE_SET_INSERT_SPACES))
|
||||
{
|
||||
gtk_source_view_set_insert_spaces_instead_of_tabs
|
||||
(view, options.insert_spaces);
|
||||
}
|
||||
else if (check_previous (view, previous, MODELINE_SET_INSERT_SPACES))
|
||||
{
|
||||
gtk_source_view_set_insert_spaces_instead_of_tabs
|
||||
(view,
|
||||
gedit_prefs_manager_get_insert_spaces ());
|
||||
}
|
||||
|
||||
if (has_option (&options, MODELINE_SET_TAB_WIDTH))
|
||||
{
|
||||
gtk_source_view_set_tab_width (view, options.tab_width);
|
||||
}
|
||||
else if (check_previous (view, previous, MODELINE_SET_TAB_WIDTH))
|
||||
{
|
||||
gtk_source_view_set_tab_width (view,
|
||||
gedit_prefs_manager_get_tabs_size ());
|
||||
}
|
||||
|
||||
if (has_option (&options, MODELINE_SET_INDENT_WIDTH))
|
||||
{
|
||||
gtk_source_view_set_indent_width (view, options.indent_width);
|
||||
}
|
||||
else if (check_previous (view, previous, MODELINE_SET_INDENT_WIDTH))
|
||||
{
|
||||
gtk_source_view_set_indent_width (view, -1);
|
||||
}
|
||||
|
||||
if (has_option (&options, MODELINE_SET_WRAP_MODE))
|
||||
{
|
||||
gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (view), options.wrap_mode);
|
||||
}
|
||||
else if (check_previous (view, previous, MODELINE_SET_WRAP_MODE))
|
||||
{
|
||||
gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (view),
|
||||
gedit_prefs_manager_get_wrap_mode ());
|
||||
}
|
||||
|
||||
if (has_option (&options, MODELINE_SET_RIGHT_MARGIN_POSITION))
|
||||
{
|
||||
gtk_source_view_set_right_margin_position (view, options.right_margin_position);
|
||||
}
|
||||
else if (check_previous (view, previous, MODELINE_SET_RIGHT_MARGIN_POSITION))
|
||||
{
|
||||
gtk_source_view_set_right_margin_position (view,
|
||||
gedit_prefs_manager_get_right_margin_position ());
|
||||
}
|
||||
|
||||
if (has_option (&options, MODELINE_SET_SHOW_RIGHT_MARGIN))
|
||||
{
|
||||
gtk_source_view_set_show_right_margin (view, options.display_right_margin);
|
||||
}
|
||||
else if (check_previous (view, previous, MODELINE_SET_SHOW_RIGHT_MARGIN))
|
||||
{
|
||||
gtk_source_view_set_show_right_margin (view,
|
||||
gedit_prefs_manager_get_display_right_margin ());
|
||||
}
|
||||
|
||||
if (previous)
|
||||
{
|
||||
*previous = options;
|
||||
previous->language_id = g_strdup (options.language_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
previous = g_slice_new (ModelineOptions);
|
||||
*previous = options;
|
||||
previous->language_id = g_strdup (options.language_id);
|
||||
|
||||
g_object_set_data_full (G_OBJECT (buffer),
|
||||
MODELINE_OPTIONS_DATA_KEY,
|
||||
previous,
|
||||
(GDestroyNotify)free_modeline_options);
|
||||
}
|
||||
|
||||
g_free (options.language_id);
|
||||
}
|
||||
|
||||
void
|
||||
modeline_parser_deactivate (GtkSourceView *view)
|
||||
{
|
||||
g_object_set_data (G_OBJECT (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view))),
|
||||
MODELINE_OPTIONS_DATA_KEY,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/* vi:ts=8 */
|
37
plugins/modelines/modeline-parser.h
Executable file
37
plugins/modelines/modeline-parser.h
Executable file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* modelie-parser.h
|
||||
* Emacs, Kate and Vim-style modelines support for gedit.
|
||||
*
|
||||
* Copyright (C) 2005-2007 - Steve Frécinaux <code@istique.net>
|
||||
*
|
||||
* 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 __MODELINE_PARSER_H__
|
||||
#define __MODELINE_PARSER_H__
|
||||
|
||||
#include <glib.h>
|
||||
#include <gtksourceview/gtksourceview.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
void modeline_parser_init (const gchar *data_dir);
|
||||
void modeline_parser_shutdown (void);
|
||||
void modeline_parser_apply_modeline (GtkSourceView *view);
|
||||
void modeline_parser_deactivate (GtkSourceView *view);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __MODELINE_PARSER_H__ */
|
8
plugins/modelines/modelines.gedit-plugin.desktop.in
Executable file
8
plugins/modelines/modelines.gedit-plugin.desktop.in
Executable file
@@ -0,0 +1,8 @@
|
||||
[Gedit Plugin]
|
||||
Module=modelines
|
||||
IAge=2
|
||||
_Name=Modelines
|
||||
_Description=Emacs, Kate and Vim-style modelines support for gedit.
|
||||
Authors=Steve Frécinaux <steve@istique.net>
|
||||
Copyright=Copyright © 2005 Steve Frécinaux
|
||||
Website=http://www.gedit.org
|
15
plugins/pythonconsole/Makefile.am
Executable file
15
plugins/pythonconsole/Makefile.am
Executable file
@@ -0,0 +1,15 @@
|
||||
# Python Console Plugin
|
||||
SUBDIRS = pythonconsole
|
||||
plugindir = $(GEDIT_PLUGINS_LIBS_DIR)
|
||||
|
||||
plugin_in_files = pythonconsole.gedit-plugin.desktop.in
|
||||
%.gedit-plugin: %.gedit-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:.gedit-plugin.desktop.in=.gedit-plugin)
|
||||
|
||||
EXTRA_DIST = $(plugin_in_files)
|
||||
|
||||
CLEANFILES = $(plugin_DATA)
|
||||
DISTCLEANFILES = $(plugin_DATA)
|
||||
|
||||
-include $(top_srcdir)/git.mk
|
10
plugins/pythonconsole/pythonconsole.gedit-plugin.desktop.in
Executable file
10
plugins/pythonconsole/pythonconsole.gedit-plugin.desktop.in
Executable file
@@ -0,0 +1,10 @@
|
||||
[Gedit Plugin]
|
||||
Loader=python
|
||||
Module=pythonconsole
|
||||
IAge=2
|
||||
_Name=Python Console
|
||||
_Description=Interactive Python console standing in the bottom panel
|
||||
Icon=mate-mime-text-x-python
|
||||
Authors=Steve Frécinaux <steve@istique.net>
|
||||
Copyright=Copyright © 2006 Steve Frécinaux
|
||||
Website=http://www.gedit.org
|
17
plugins/pythonconsole/pythonconsole/Makefile.am
Executable file
17
plugins/pythonconsole/pythonconsole/Makefile.am
Executable file
@@ -0,0 +1,17 @@
|
||||
# Python console plugin
|
||||
|
||||
plugindir = $(GEDIT_PLUGINS_LIBS_DIR)/pythonconsole
|
||||
plugin_PYTHON = \
|
||||
__init__.py \
|
||||
console.py \
|
||||
config.py
|
||||
|
||||
uidir = $(GEDIT_PLUGINS_DATA_DIR)/pythonconsole/ui
|
||||
ui_DATA = config.ui
|
||||
|
||||
EXTRA_DIST = $(ui_DATA)
|
||||
|
||||
CLEANFILES =
|
||||
DISTCLEANFILES =
|
||||
|
||||
-include $(top_srcdir)/git.mk
|
78
plugins/pythonconsole/pythonconsole/__init__.py
Executable file
78
plugins/pythonconsole/pythonconsole/__init__.py
Executable file
@@ -0,0 +1,78 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# __init__.py -- plugin object
|
||||
#
|
||||
# Copyright (C) 2006 - Steve Frécinaux
|
||||
#
|
||||
# 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.
|
||||
|
||||
# Parts from "Interactive Python-GTK Console" (stolen from epiphany's console.py)
|
||||
# Copyright (C), 1998 James Henstridge <james@daa.com.au>
|
||||
# Copyright (C), 2005 Adam Hooper <adamh@densi.com>
|
||||
# Bits from gedit Python Console Plugin
|
||||
# Copyrignt (C), 2005 Raphaël Slinckx
|
||||
|
||||
import gtk
|
||||
import gedit
|
||||
|
||||
from console import PythonConsole
|
||||
from config import PythonConsoleConfigDialog
|
||||
from config import PythonConsoleConfig
|
||||
|
||||
PYTHON_ICON = 'mate-mime-text-x-python'
|
||||
|
||||
class PythonConsolePlugin(gedit.Plugin):
|
||||
def __init__(self):
|
||||
gedit.Plugin.__init__(self)
|
||||
self.dlg = None
|
||||
|
||||
def activate(self, window):
|
||||
console = PythonConsole(namespace = {'__builtins__' : __builtins__,
|
||||
'gedit' : gedit,
|
||||
'window' : window})
|
||||
console.eval('print "You can access the main window through ' \
|
||||
'\'window\' :\\n%s" % window', False)
|
||||
bottom = window.get_bottom_panel()
|
||||
image = gtk.Image()
|
||||
image.set_from_icon_name(PYTHON_ICON, gtk.ICON_SIZE_MENU)
|
||||
bottom.add_item(console, _('Python Console'), image)
|
||||
window.set_data('PythonConsolePluginInfo', console)
|
||||
|
||||
def deactivate(self, window):
|
||||
console = window.get_data("PythonConsolePluginInfo")
|
||||
console.stop()
|
||||
window.set_data("PythonConsolePluginInfo", None)
|
||||
bottom = window.get_bottom_panel()
|
||||
bottom.remove_item(console)
|
||||
|
||||
def create_configure_dialog(self):
|
||||
|
||||
if not self.dlg:
|
||||
self.dlg = PythonConsoleConfigDialog(self.get_data_dir())
|
||||
|
||||
dialog = self.dlg.dialog()
|
||||
window = gedit.app_get_default().get_active_window()
|
||||
if window:
|
||||
dialog.set_transient_for(window)
|
||||
|
||||
return dialog
|
||||
|
||||
# Here we dynamically insert create_configure_dialog based on if configuration
|
||||
# is enabled. This has to be done like this because gedit checks if a plugin
|
||||
# is configurable solely on the fact that it has this member defined or not
|
||||
if PythonConsoleConfig.enabled():
|
||||
PythonConsolePlugin.create_configure_dialog = create_configure_dialog
|
||||
|
||||
# ex:et:ts=4:
|
134
plugins/pythonconsole/pythonconsole/config.py
Executable file
134
plugins/pythonconsole/pythonconsole/config.py
Executable file
@@ -0,0 +1,134 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# config.py -- Config dialog
|
||||
#
|
||||
# Copyright (C) 2008 - B. Clausius
|
||||
#
|
||||
# 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.
|
||||
|
||||
# Parts from "Interactive Python-GTK Console" (stolen from epiphany's console.py)
|
||||
# Copyright (C), 1998 James Henstridge <james@daa.com.au>
|
||||
# Copyright (C), 2005 Adam Hooper <adamh@densi.com>
|
||||
# Bits from gedit Python Console Plugin
|
||||
# Copyrignt (C), 2005 Raphaël Slinckx
|
||||
|
||||
import os
|
||||
import gtk
|
||||
|
||||
__all__ = ('PythonConsoleConfig', 'PythonConsoleConfigDialog')
|
||||
|
||||
MATECONF_KEY_BASE = '/apps/gedit-2/plugins/pythonconsole'
|
||||
MATECONF_KEY_COMMAND_COLOR = MATECONF_KEY_BASE + '/command-color'
|
||||
MATECONF_KEY_ERROR_COLOR = MATECONF_KEY_BASE + '/error-color'
|
||||
|
||||
DEFAULT_COMMAND_COLOR = '#314e6c' # Blue Shadow
|
||||
DEFAULT_ERROR_COLOR = '#990000' # Accent Red Dark
|
||||
|
||||
class PythonConsoleConfig(object):
|
||||
try:
|
||||
import mateconf
|
||||
except ImportError:
|
||||
mateconf = None
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def enabled():
|
||||
return PythonConsoleConfig.mateconf != None
|
||||
|
||||
@staticmethod
|
||||
def add_handler(handler):
|
||||
if PythonConsoleConfig.mateconf:
|
||||
PythonConsoleConfig.mateconf.client_get_default().notify_add(MATECONF_KEY_BASE, handler)
|
||||
|
||||
color_command = property(
|
||||
lambda self: self.mateconf_get_str(MATECONF_KEY_COMMAND_COLOR, DEFAULT_COMMAND_COLOR),
|
||||
lambda self, value: self.mateconf_set_str(MATECONF_KEY_COMMAND_COLOR, value))
|
||||
|
||||
color_error = property(
|
||||
lambda self: self.mateconf_get_str(MATECONF_KEY_ERROR_COLOR, DEFAULT_ERROR_COLOR),
|
||||
lambda self, value: self.mateconf_set_str(MATECONF_KEY_ERROR_COLOR, value))
|
||||
|
||||
@staticmethod
|
||||
def mateconf_get_str(key, default=''):
|
||||
if not PythonConsoleConfig.mateconf:
|
||||
return default
|
||||
|
||||
val = PythonConsoleConfig.mateconf.client_get_default().get(key)
|
||||
if val is not None and val.type == mateconf.VALUE_STRING:
|
||||
return val.get_string()
|
||||
else:
|
||||
return default
|
||||
|
||||
@staticmethod
|
||||
def mateconf_set_str(key, value):
|
||||
if not PythonConsoleConfig.mateconf:
|
||||
return
|
||||
|
||||
v = PythonConsoleConfig.mateconf.Value(mateconf.VALUE_STRING)
|
||||
v.set_string(value)
|
||||
PythonConsoleConfig.mateconf.client_get_default().set(key, v)
|
||||
|
||||
class PythonConsoleConfigDialog(object):
|
||||
|
||||
def __init__(self, datadir):
|
||||
object.__init__(self)
|
||||
self._dialog = None
|
||||
self._ui_path = os.path.join(datadir, 'ui', 'config.ui')
|
||||
self.config = PythonConsoleConfig()
|
||||
|
||||
def dialog(self):
|
||||
if self._dialog is None:
|
||||
self._ui = gtk.Builder()
|
||||
self._ui.add_from_file(self._ui_path)
|
||||
|
||||
self.set_colorbutton_color(self._ui.get_object('colorbutton-command'),
|
||||
self.config.color_command)
|
||||
self.set_colorbutton_color(self._ui.get_object('colorbutton-error'),
|
||||
self.config.color_error)
|
||||
|
||||
self._ui.connect_signals(self)
|
||||
|
||||
self._dialog = self._ui.get_object('dialog-config')
|
||||
self._dialog.show_all()
|
||||
else:
|
||||
self._dialog.present()
|
||||
|
||||
return self._dialog
|
||||
|
||||
@staticmethod
|
||||
def set_colorbutton_color(colorbutton, value):
|
||||
try:
|
||||
color = gtk.gdk.color_parse(value)
|
||||
except ValueError:
|
||||
pass # Default color in config.ui used
|
||||
else:
|
||||
colorbutton.set_color(color)
|
||||
|
||||
def on_dialog_config_response(self, dialog, response_id):
|
||||
self._dialog.destroy()
|
||||
|
||||
def on_dialog_config_destroy(self, dialog):
|
||||
self._dialog = None
|
||||
self._ui = None
|
||||
|
||||
def on_colorbutton_command_color_set(self, colorbutton):
|
||||
self.config.color_command = colorbutton.get_color().to_string()
|
||||
|
||||
def on_colorbutton_error_color_set(self, colorbutton):
|
||||
self.config.color_error = colorbutton.get_color().to_string()
|
||||
|
||||
# ex:et:ts=4:
|
107
plugins/pythonconsole/pythonconsole/config.ui
Executable file
107
plugins/pythonconsole/pythonconsole/config.ui
Executable file
@@ -0,0 +1,107 @@
|
||||
<?xml version="1.0"?>
|
||||
<interface>
|
||||
<requires lib="gtk+" version="2.14"/>
|
||||
<!-- interface-naming-policy toplevel-contextual -->
|
||||
<object class="GtkDialog" id="dialog-config">
|
||||
<property name="window_position">center-on-parent</property>
|
||||
<property name="destroy_with_parent">True</property>
|
||||
<property name="type_hint">dialog</property>
|
||||
<property name="has_separator">False</property>
|
||||
<signal name="destroy" handler="on_dialog_config_destroy"/>
|
||||
<signal name="response" handler="on_dialog_config_response"/>
|
||||
<child internal-child="vbox">
|
||||
<object class="GtkVBox" id="dialog-vbox1">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<object class="GtkTable" id="table2">
|
||||
<property name="visible">True</property>
|
||||
<property name="border_width">6</property>
|
||||
<property name="n_rows">2</property>
|
||||
<property name="n_columns">2</property>
|
||||
<property name="column_spacing">6</property>
|
||||
<property name="row_spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label-command">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">C_ommand color:</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="mnemonic_widget">colorbutton-command</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label-error">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">_Error color:</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="mnemonic_widget">colorbutton-error</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="bottom_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkColorButton" id="colorbutton-command">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="color">#31314e4e6c6c</property>
|
||||
<signal name="color_set" handler="on_colorbutton_command_color_set"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkColorButton" id="colorbutton-error">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="color">#999900000000</property>
|
||||
<signal name="color_set" handler="on_colorbutton_error_color_set"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="bottom_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child internal-child="action_area">
|
||||
<object class="GtkHButtonBox" id="dialog-action_area1">
|
||||
<property name="visible">True</property>
|
||||
<property name="layout_style">end</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="button1">
|
||||
<property name="label">gtk-close</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="use_stock">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="pack_type">end</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<action-widgets>
|
||||
<action-widget response="-7">button1</action-widget>
|
||||
</action-widgets>
|
||||
</object>
|
||||
</interface>
|
370
plugins/pythonconsole/pythonconsole/console.py
Executable file
370
plugins/pythonconsole/pythonconsole/console.py
Executable file
@@ -0,0 +1,370 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# pythonconsole.py -- Console widget
|
||||
#
|
||||
# Copyright (C) 2006 - Steve Frécinaux
|
||||
#
|
||||
# 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.
|
||||
|
||||
# Parts from "Interactive Python-GTK Console" (stolen from epiphany's console.py)
|
||||
# Copyright (C), 1998 James Henstridge <james@daa.com.au>
|
||||
# Copyright (C), 2005 Adam Hooper <adamh@densi.com>
|
||||
# Bits from gedit Python Console Plugin
|
||||
# Copyrignt (C), 2005 Raphaël Slinckx
|
||||
|
||||
import string
|
||||
import sys
|
||||
import re
|
||||
import traceback
|
||||
import gobject
|
||||
import gtk
|
||||
import pango
|
||||
|
||||
from config import PythonConsoleConfig
|
||||
|
||||
__all__ = ('PythonConsole', 'OutFile')
|
||||
|
||||
class PythonConsole(gtk.ScrolledWindow):
|
||||
|
||||
__gsignals__ = {
|
||||
'grab-focus' : 'override',
|
||||
}
|
||||
|
||||
def __init__(self, namespace = {}):
|
||||
gtk.ScrolledWindow.__init__(self)
|
||||
|
||||
self.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
|
||||
self.set_shadow_type(gtk.SHADOW_IN)
|
||||
self.view = gtk.TextView()
|
||||
self.view.modify_font(pango.FontDescription('Monospace'))
|
||||
self.view.set_editable(True)
|
||||
self.view.set_wrap_mode(gtk.WRAP_WORD_CHAR)
|
||||
self.add(self.view)
|
||||
self.view.show()
|
||||
|
||||
buffer = self.view.get_buffer()
|
||||
self.normal = buffer.create_tag("normal")
|
||||
self.error = buffer.create_tag("error")
|
||||
self.command = buffer.create_tag("command")
|
||||
|
||||
PythonConsoleConfig.add_handler(self.apply_preferences)
|
||||
self.apply_preferences()
|
||||
|
||||
self.__spaces_pattern = re.compile(r'^\s+')
|
||||
self.namespace = namespace
|
||||
|
||||
self.block_command = False
|
||||
|
||||
# Init first line
|
||||
buffer.create_mark("input-line", buffer.get_end_iter(), True)
|
||||
buffer.insert(buffer.get_end_iter(), ">>> ")
|
||||
buffer.create_mark("input", buffer.get_end_iter(), True)
|
||||
|
||||
# Init history
|
||||
self.history = ['']
|
||||
self.history_pos = 0
|
||||
self.current_command = ''
|
||||
self.namespace['__history__'] = self.history
|
||||
|
||||
# Set up hooks for standard output.
|
||||
self.stdout = OutFile(self, sys.stdout.fileno(), self.normal)
|
||||
self.stderr = OutFile(self, sys.stderr.fileno(), self.error)
|
||||
|
||||
# Signals
|
||||
self.view.connect("key-press-event", self.__key_press_event_cb)
|
||||
buffer.connect("mark-set", self.__mark_set_cb)
|
||||
|
||||
def do_grab_focus(self):
|
||||
self.view.grab_focus()
|
||||
|
||||
def apply_preferences(self, *args):
|
||||
config = PythonConsoleConfig()
|
||||
self.error.set_property("foreground", config.color_error)
|
||||
self.command.set_property("foreground", config.color_command)
|
||||
|
||||
def stop(self):
|
||||
self.namespace = None
|
||||
|
||||
def __key_press_event_cb(self, view, event):
|
||||
modifier_mask = gtk.accelerator_get_default_mod_mask()
|
||||
event_state = event.state & modifier_mask
|
||||
|
||||
if event.keyval == gtk.keysyms.d and event_state == gtk.gdk.CONTROL_MASK:
|
||||
self.destroy()
|
||||
|
||||
elif event.keyval == gtk.keysyms.Return and event_state == gtk.gdk.CONTROL_MASK:
|
||||
# Get the command
|
||||
buffer = view.get_buffer()
|
||||
inp_mark = buffer.get_mark("input")
|
||||
inp = buffer.get_iter_at_mark(inp_mark)
|
||||
cur = buffer.get_end_iter()
|
||||
line = buffer.get_text(inp, cur)
|
||||
self.current_command = self.current_command + line + "\n"
|
||||
self.history_add(line)
|
||||
|
||||
# Prepare the new line
|
||||
cur = buffer.get_end_iter()
|
||||
buffer.insert(cur, "\n... ")
|
||||
cur = buffer.get_end_iter()
|
||||
buffer.move_mark(inp_mark, cur)
|
||||
|
||||
# Keep indentation of precendent line
|
||||
spaces = re.match(self.__spaces_pattern, line)
|
||||
if spaces is not None:
|
||||
buffer.insert(cur, line[spaces.start() : spaces.end()])
|
||||
cur = buffer.get_end_iter()
|
||||
|
||||
buffer.place_cursor(cur)
|
||||
gobject.idle_add(self.scroll_to_end)
|
||||
return True
|
||||
|
||||
elif event.keyval == gtk.keysyms.Return:
|
||||
# Get the marks
|
||||
buffer = view.get_buffer()
|
||||
lin_mark = buffer.get_mark("input-line")
|
||||
inp_mark = buffer.get_mark("input")
|
||||
|
||||
# Get the command line
|
||||
inp = buffer.get_iter_at_mark(inp_mark)
|
||||
cur = buffer.get_end_iter()
|
||||
line = buffer.get_text(inp, cur)
|
||||
self.current_command = self.current_command + line + "\n"
|
||||
self.history_add(line)
|
||||
|
||||
# Make the line blue
|
||||
lin = buffer.get_iter_at_mark(lin_mark)
|
||||
buffer.apply_tag(self.command, lin, cur)
|
||||
buffer.insert(cur, "\n")
|
||||
|
||||
cur_strip = self.current_command.rstrip()
|
||||
|
||||
if cur_strip.endswith(":") \
|
||||
or (self.current_command[-2:] != "\n\n" and self.block_command):
|
||||
# Unfinished block command
|
||||
self.block_command = True
|
||||
com_mark = "... "
|
||||
elif cur_strip.endswith("\\"):
|
||||
com_mark = "... "
|
||||
else:
|
||||
# Eval the command
|
||||
self.__run(self.current_command)
|
||||
self.current_command = ''
|
||||
self.block_command = False
|
||||
com_mark = ">>> "
|
||||
|
||||
# Prepare the new line
|
||||
cur = buffer.get_end_iter()
|
||||
buffer.move_mark(lin_mark, cur)
|
||||
buffer.insert(cur, com_mark)
|
||||
cur = buffer.get_end_iter()
|
||||
buffer.move_mark(inp_mark, cur)
|
||||
buffer.place_cursor(cur)
|
||||
gobject.idle_add(self.scroll_to_end)
|
||||
return True
|
||||
|
||||
elif event.keyval == gtk.keysyms.KP_Down or event.keyval == gtk.keysyms.Down:
|
||||
# Next entry from history
|
||||
view.emit_stop_by_name("key_press_event")
|
||||
self.history_down()
|
||||
gobject.idle_add(self.scroll_to_end)
|
||||
return True
|
||||
|
||||
elif event.keyval == gtk.keysyms.KP_Up or event.keyval == gtk.keysyms.Up:
|
||||
# Previous entry from history
|
||||
view.emit_stop_by_name("key_press_event")
|
||||
self.history_up()
|
||||
gobject.idle_add(self.scroll_to_end)
|
||||
return True
|
||||
|
||||
elif event.keyval == gtk.keysyms.KP_Left or event.keyval == gtk.keysyms.Left or \
|
||||
event.keyval == gtk.keysyms.BackSpace:
|
||||
buffer = view.get_buffer()
|
||||
inp = buffer.get_iter_at_mark(buffer.get_mark("input"))
|
||||
cur = buffer.get_iter_at_mark(buffer.get_insert())
|
||||
if inp.compare(cur) == 0:
|
||||
if not event_state:
|
||||
buffer.place_cursor(inp)
|
||||
return True
|
||||
return False
|
||||
|
||||
# For the console we enable smart/home end behavior incoditionally
|
||||
# since it is useful when editing python
|
||||
|
||||
elif (event.keyval == gtk.keysyms.KP_Home or event.keyval == gtk.keysyms.Home) and \
|
||||
event_state == event_state & (gtk.gdk.SHIFT_MASK|gtk.gdk.CONTROL_MASK):
|
||||
# Go to the begin of the command instead of the begin of the line
|
||||
buffer = view.get_buffer()
|
||||
iter = buffer.get_iter_at_mark(buffer.get_mark("input"))
|
||||
ins = buffer.get_iter_at_mark(buffer.get_insert())
|
||||
|
||||
while iter.get_char().isspace():
|
||||
iter.forward_char()
|
||||
|
||||
if iter.equal(ins):
|
||||
iter = buffer.get_iter_at_mark(buffer.get_mark("input"))
|
||||
|
||||
if event_state & gtk.gdk.SHIFT_MASK:
|
||||
buffer.move_mark_by_name("insert", iter)
|
||||
else:
|
||||
buffer.place_cursor(iter)
|
||||
return True
|
||||
|
||||
elif (event.keyval == gtk.keysyms.KP_End or event.keyval == gtk.keysyms.End) and \
|
||||
event_state == event_state & (gtk.gdk.SHIFT_MASK|gtk.gdk.CONTROL_MASK):
|
||||
|
||||
buffer = view.get_buffer()
|
||||
iter = buffer.get_end_iter()
|
||||
ins = buffer.get_iter_at_mark(buffer.get_insert())
|
||||
|
||||
iter.backward_char()
|
||||
|
||||
while iter.get_char().isspace():
|
||||
iter.backward_char()
|
||||
|
||||
iter.forward_char()
|
||||
|
||||
if iter.equal(ins):
|
||||
iter = buffer.get_end_iter()
|
||||
|
||||
if event_state & gtk.gdk.SHIFT_MASK:
|
||||
buffer.move_mark_by_name("insert", iter)
|
||||
else:
|
||||
buffer.place_cursor(iter)
|
||||
return True
|
||||
|
||||
def __mark_set_cb(self, buffer, iter, name):
|
||||
input = buffer.get_iter_at_mark(buffer.get_mark("input"))
|
||||
pos = buffer.get_iter_at_mark(buffer.get_insert())
|
||||
self.view.set_editable(pos.compare(input) != -1)
|
||||
|
||||
def get_command_line(self):
|
||||
buffer = self.view.get_buffer()
|
||||
inp = buffer.get_iter_at_mark(buffer.get_mark("input"))
|
||||
cur = buffer.get_end_iter()
|
||||
return buffer.get_text(inp, cur)
|
||||
|
||||
def set_command_line(self, command):
|
||||
buffer = self.view.get_buffer()
|
||||
mark = buffer.get_mark("input")
|
||||
inp = buffer.get_iter_at_mark(mark)
|
||||
cur = buffer.get_end_iter()
|
||||
buffer.delete(inp, cur)
|
||||
buffer.insert(inp, command)
|
||||
self.view.grab_focus()
|
||||
|
||||
def history_add(self, line):
|
||||
if line.strip() != '':
|
||||
self.history_pos = len(self.history)
|
||||
self.history[self.history_pos - 1] = line
|
||||
self.history.append('')
|
||||
|
||||
def history_up(self):
|
||||
if self.history_pos > 0:
|
||||
self.history[self.history_pos] = self.get_command_line()
|
||||
self.history_pos = self.history_pos - 1
|
||||
self.set_command_line(self.history[self.history_pos])
|
||||
|
||||
def history_down(self):
|
||||
if self.history_pos < len(self.history) - 1:
|
||||
self.history[self.history_pos] = self.get_command_line()
|
||||
self.history_pos = self.history_pos + 1
|
||||
self.set_command_line(self.history[self.history_pos])
|
||||
|
||||
def scroll_to_end(self):
|
||||
iter = self.view.get_buffer().get_end_iter()
|
||||
self.view.scroll_to_iter(iter, 0.0)
|
||||
return False
|
||||
|
||||
def write(self, text, tag = None):
|
||||
buffer = self.view.get_buffer()
|
||||
if tag is None:
|
||||
buffer.insert(buffer.get_end_iter(), text)
|
||||
else:
|
||||
buffer.insert_with_tags(buffer.get_end_iter(), text, tag)
|
||||
gobject.idle_add(self.scroll_to_end)
|
||||
|
||||
def eval(self, command, display_command = False):
|
||||
buffer = self.view.get_buffer()
|
||||
lin = buffer.get_mark("input-line")
|
||||
buffer.delete(buffer.get_iter_at_mark(lin),
|
||||
buffer.get_end_iter())
|
||||
|
||||
if isinstance(command, list) or isinstance(command, tuple):
|
||||
for c in command:
|
||||
if display_command:
|
||||
self.write(">>> " + c + "\n", self.command)
|
||||
self.__run(c)
|
||||
else:
|
||||
if display_command:
|
||||
self.write(">>> " + c + "\n", self.command)
|
||||
self.__run(command)
|
||||
|
||||
cur = buffer.get_end_iter()
|
||||
buffer.move_mark_by_name("input-line", cur)
|
||||
buffer.insert(cur, ">>> ")
|
||||
cur = buffer.get_end_iter()
|
||||
buffer.move_mark_by_name("input", cur)
|
||||
self.view.scroll_to_iter(buffer.get_end_iter(), 0.0)
|
||||
|
||||
def __run(self, command):
|
||||
sys.stdout, self.stdout = self.stdout, sys.stdout
|
||||
sys.stderr, self.stderr = self.stderr, sys.stderr
|
||||
|
||||
# eval and exec are broken in how they deal with utf8-encoded
|
||||
# strings so we have to explicitly decode the command before
|
||||
# passing it along
|
||||
command = command.decode('utf8')
|
||||
|
||||
try:
|
||||
try:
|
||||
r = eval(command, self.namespace, self.namespace)
|
||||
if r is not None:
|
||||
print `r`
|
||||
except SyntaxError:
|
||||
exec command in self.namespace
|
||||
except:
|
||||
if hasattr(sys, 'last_type') and sys.last_type == SystemExit:
|
||||
self.destroy()
|
||||
else:
|
||||
traceback.print_exc()
|
||||
|
||||
sys.stdout, self.stdout = self.stdout, sys.stdout
|
||||
sys.stderr, self.stderr = self.stderr, sys.stderr
|
||||
|
||||
def destroy(self):
|
||||
pass
|
||||
#gtk.ScrolledWindow.destroy(self)
|
||||
|
||||
class OutFile:
|
||||
"""A fake output file object. It sends output to a TK test widget,
|
||||
and if asked for a file number, returns one set on instance creation"""
|
||||
def __init__(self, console, fn, tag):
|
||||
self.fn = fn
|
||||
self.console = console
|
||||
self.tag = tag
|
||||
def close(self): pass
|
||||
def flush(self): pass
|
||||
def fileno(self): return self.fn
|
||||
def isatty(self): return 0
|
||||
def read(self, a): return ''
|
||||
def readline(self): return ''
|
||||
def readlines(self): return []
|
||||
def write(self, s): self.console.write(s, self.tag)
|
||||
def writelines(self, l): self.console.write(l, self.tag)
|
||||
def seek(self, a): raise IOError, (29, 'Illegal seek')
|
||||
def tell(self): raise IOError, (29, 'Illegal seek')
|
||||
truncate = tell
|
||||
|
||||
# ex:et:ts=4:
|
15
plugins/quickopen/Makefile.am
Executable file
15
plugins/quickopen/Makefile.am
Executable file
@@ -0,0 +1,15 @@
|
||||
# Quick Open Plugin
|
||||
SUBDIRS = quickopen
|
||||
plugindir = $(GEDIT_PLUGINS_LIBS_DIR)
|
||||
|
||||
plugin_in_files = quickopen.gedit-plugin.desktop.in
|
||||
%.gedit-plugin: %.gedit-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:.gedit-plugin.desktop.in=.gedit-plugin)
|
||||
|
||||
EXTRA_DIST = $(plugin_in_files)
|
||||
|
||||
CLEANFILES = $(plugin_DATA)
|
||||
DISTCLEANFILES = $(plugin_DATA)
|
||||
|
||||
-include $(top_srcdir)/git.mk
|
10
plugins/quickopen/quickopen.gedit-plugin.desktop.in
Executable file
10
plugins/quickopen/quickopen.gedit-plugin.desktop.in
Executable file
@@ -0,0 +1,10 @@
|
||||
[Gedit Plugin]
|
||||
Loader=python
|
||||
Module=quickopen
|
||||
IAge=2
|
||||
_Name=Quick Open
|
||||
_Description=Quickly open files
|
||||
Icon=gtk-open
|
||||
Authors=Jesse van den Kieboom <jessevdk@gnome.org>
|
||||
Copyright=Copyright © 2009 Jesse van den Kieboom
|
||||
Website=http://www.gedit.org
|
13
plugins/quickopen/quickopen/Makefile.am
Executable file
13
plugins/quickopen/quickopen/Makefile.am
Executable file
@@ -0,0 +1,13 @@
|
||||
# Quick Open Plugin
|
||||
|
||||
plugindir = $(GEDIT_PLUGINS_LIBS_DIR)/quickopen
|
||||
plugin_PYTHON = \
|
||||
__init__.py \
|
||||
popup.py \
|
||||
virtualdirs.py \
|
||||
windowhelper.py
|
||||
|
||||
CLEANFILES =
|
||||
DISTCLEANFILES =
|
||||
|
||||
-include $(top_srcdir)/git.mk
|
46
plugins/quickopen/quickopen/__init__.py
Executable file
46
plugins/quickopen/quickopen/__init__.py
Executable file
@@ -0,0 +1,46 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright (C) 2009 - Jesse van den Kieboom
|
||||
#
|
||||
# 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 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, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
# Boston, MA 02111-1307, USA.
|
||||
|
||||
import gedit
|
||||
from windowhelper import WindowHelper
|
||||
|
||||
class QuickOpenPlugin(gedit.Plugin):
|
||||
def __init__(self):
|
||||
gedit.Plugin.__init__(self)
|
||||
|
||||
self._popup_size = (450, 300)
|
||||
self._helpers = {}
|
||||
|
||||
def activate(self, window):
|
||||
self._helpers[window] = WindowHelper(window, self)
|
||||
|
||||
def deactivate(self, window):
|
||||
self._helpers[window].deactivate()
|
||||
del self._helpers[window]
|
||||
|
||||
def update_ui(self, window):
|
||||
self._helpers[window].update_ui()
|
||||
|
||||
def get_popup_size(self):
|
||||
return self._popup_size
|
||||
|
||||
def set_popup_size(self, size):
|
||||
self._popup_size = size
|
||||
|
||||
# ex:ts=8:et:
|
534
plugins/quickopen/quickopen/popup.py
Executable file
534
plugins/quickopen/quickopen/popup.py
Executable file
@@ -0,0 +1,534 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright (C) 2009 - Jesse van den Kieboom
|
||||
#
|
||||
# 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 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, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
# Boston, MA 02111-1307, USA.
|
||||
|
||||
import gtk
|
||||
import gtk.gdk
|
||||
import gobject
|
||||
import os
|
||||
import gio
|
||||
import pango
|
||||
import glib
|
||||
import fnmatch
|
||||
import gedit
|
||||
import xml.sax.saxutils
|
||||
from virtualdirs import VirtualDirectory
|
||||
|
||||
class Popup(gtk.Dialog):
|
||||
def __init__(self, window, paths, handler):
|
||||
gtk.Dialog.__init__(self,
|
||||
title=_('Quick Open'),
|
||||
parent=window,
|
||||
flags=gtk.DIALOG_DESTROY_WITH_PARENT | gtk.DIALOG_NO_SEPARATOR | gtk.DIALOG_MODAL)
|
||||
|
||||
self.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
|
||||
self._open_button = self.add_button(gtk.STOCK_OPEN, gtk.RESPONSE_ACCEPT)
|
||||
|
||||
self._handler = handler
|
||||
self._build_ui()
|
||||
|
||||
self._dirs = []
|
||||
self._cache = {}
|
||||
self._theme = None
|
||||
self._cursor = None
|
||||
self._shift_start = None
|
||||
|
||||
accel_group = gtk.AccelGroup()
|
||||
accel_group.connect_group(gtk.keysyms.l, gtk.gdk.CONTROL_MASK, 0, self.on_focus_entry)
|
||||
|
||||
self.add_accel_group(accel_group)
|
||||
|
||||
unique = []
|
||||
|
||||
for path in paths:
|
||||
if not path.get_uri() in unique:
|
||||
self._dirs.append(path)
|
||||
unique.append(path.get_uri())
|
||||
|
||||
def _build_ui(self):
|
||||
vbox = self.get_content_area()
|
||||
vbox.set_spacing(3)
|
||||
|
||||
self._entry = gtk.Entry()
|
||||
|
||||
self._entry.connect('changed', self.on_changed)
|
||||
self._entry.connect('key-press-event', self.on_key_press_event)
|
||||
|
||||
sw = gtk.ScrolledWindow(None, None)
|
||||
sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
|
||||
sw.set_shadow_type(gtk.SHADOW_OUT)
|
||||
|
||||
tv = gtk.TreeView()
|
||||
tv.set_headers_visible(False)
|
||||
|
||||
self._store = gtk.ListStore(gio.Icon, str, object, int)
|
||||
tv.set_model(self._store)
|
||||
|
||||
self._treeview = tv
|
||||
tv.connect('row-activated', self.on_row_activated)
|
||||
|
||||
renderer = gtk.CellRendererPixbuf()
|
||||
column = gtk.TreeViewColumn()
|
||||
column.pack_start(renderer, False)
|
||||
column.set_attributes(renderer, gicon=0)
|
||||
|
||||
renderer = gtk.CellRendererText()
|
||||
column.pack_start(renderer, True)
|
||||
column.set_attributes(renderer, markup=1)
|
||||
|
||||
column.set_cell_data_func(renderer, self.on_cell_data_cb)
|
||||
|
||||
tv.append_column(column)
|
||||
sw.add(tv)
|
||||
|
||||
selection = tv.get_selection()
|
||||
selection.connect('changed', self.on_selection_changed)
|
||||
selection.set_mode(gtk.SELECTION_MULTIPLE)
|
||||
|
||||
vbox.pack_start(self._entry, False, False, 0)
|
||||
vbox.pack_start(sw, True, True, 0)
|
||||
|
||||
lbl = gtk.Label()
|
||||
lbl.set_alignment(0, 0.5)
|
||||
lbl.set_ellipsize(pango.ELLIPSIZE_MIDDLE)
|
||||
self._info_label = lbl
|
||||
|
||||
vbox.pack_start(lbl, False, False, 0)
|
||||
|
||||
# Initial selection
|
||||
self.on_selection_changed(tv.get_selection())
|
||||
vbox.show_all()
|
||||
|
||||
def on_cell_data_cb(self, column, cell, model, piter):
|
||||
path = model.get_path(piter)
|
||||
|
||||
if self._cursor and path == self._cursor.get_path():
|
||||
style = self._treeview.get_style()
|
||||
bg = style.bg[gtk.STATE_PRELIGHT]
|
||||
|
||||
cell.set_property('cell-background-gdk', bg)
|
||||
cell.set_property('style', pango.STYLE_ITALIC)
|
||||
else:
|
||||
cell.set_property('cell-background-set', False)
|
||||
cell.set_property('style-set', False)
|
||||
|
||||
def _icon_from_stock(self, stock):
|
||||
theme = gtk.icon_theme_get_default()
|
||||
size = gtk.icon_size_lookup(gtk.ICON_SIZE_MENU)
|
||||
pixbuf = theme.load_icon(stock, size[0], gtk.ICON_LOOKUP_USE_BUILTIN)
|
||||
|
||||
return pixbuf
|
||||
|
||||
def _list_dir(self, gfile):
|
||||
entries = []
|
||||
|
||||
try:
|
||||
entries = gfile.enumerate_children("standard::*")
|
||||
except glib.GError:
|
||||
pass
|
||||
|
||||
children = []
|
||||
|
||||
for entry in entries:
|
||||
if isinstance(gfile, VirtualDirectory):
|
||||
child, entry = entry
|
||||
else:
|
||||
child = gfile.get_child(entry.get_name())
|
||||
|
||||
children.append((child, entry.get_name(), entry.get_file_type(), entry.get_icon()))
|
||||
|
||||
return children
|
||||
|
||||
def _compare_entries(self, a, b, lpart):
|
||||
if lpart in a:
|
||||
if lpart in b:
|
||||
return cmp(a.index(lpart), b.index(lpart))
|
||||
else:
|
||||
return -1
|
||||
elif lpart in b:
|
||||
return 1
|
||||
else:
|
||||
return 0
|
||||
|
||||
def _match_glob(self, s, glob):
|
||||
if glob:
|
||||
glob += '*'
|
||||
|
||||
return fnmatch.fnmatch(s, glob)
|
||||
|
||||
def do_search_dir(self, parts, d):
|
||||
if not parts or not d:
|
||||
return []
|
||||
|
||||
if not d in self._cache:
|
||||
entries = self._list_dir(d)
|
||||
entries.sort(lambda x, y: cmp(x[1].lower(), y[1].lower()))
|
||||
|
||||
self._cache[d] = entries
|
||||
else:
|
||||
entries = self._cache[d]
|
||||
|
||||
found = []
|
||||
newdirs = []
|
||||
|
||||
lpart = parts[0].lower()
|
||||
|
||||
for entry in entries:
|
||||
if not entry:
|
||||
continue
|
||||
|
||||
lentry = entry[1].lower()
|
||||
|
||||
if not lpart or lpart in lentry or self._match_glob(lentry, lpart):
|
||||
if entry[2] == gio.FILE_TYPE_DIRECTORY:
|
||||
if len(parts) > 1:
|
||||
newdirs.append(entry[0])
|
||||
else:
|
||||
found.append(entry)
|
||||
elif entry[2] == gio.FILE_TYPE_REGULAR and \
|
||||
(not lpart or len(parts) == 1):
|
||||
found.append(entry)
|
||||
|
||||
found.sort(lambda a, b: self._compare_entries(a[1].lower(), b[1].lower(), lpart))
|
||||
|
||||
if lpart == '..':
|
||||
newdirs.append(d.get_parent())
|
||||
|
||||
for dd in newdirs:
|
||||
found.extend(self.do_search_dir(parts[1:], dd))
|
||||
|
||||
return found
|
||||
|
||||
def _replace_insensitive(self, s, find, rep):
|
||||
out = ''
|
||||
l = s.lower()
|
||||
find = find.lower()
|
||||
last = 0
|
||||
|
||||
if len(find) == 0:
|
||||
return xml.sax.saxutils.escape(s)
|
||||
|
||||
while True:
|
||||
m = l.find(find, last)
|
||||
|
||||
if m == -1:
|
||||
break
|
||||
else:
|
||||
out += xml.sax.saxutils.escape(s[last:m]) + rep % (xml.sax.saxutils.escape(s[m:m + len(find)]),)
|
||||
last = m + len(find)
|
||||
|
||||
return out + xml.sax.saxutils.escape(s[last:])
|
||||
|
||||
|
||||
def make_markup(self, parts, path):
|
||||
out = []
|
||||
|
||||
for i in range(0, len(parts)):
|
||||
out.append(self._replace_insensitive(path[i], parts[i], "<b>%s</b>"))
|
||||
|
||||
return os.sep.join(out)
|
||||
|
||||
def _get_icon(self, f):
|
||||
query = f.query_info(gio.FILE_ATTRIBUTE_STANDARD_ICON)
|
||||
|
||||
if not query:
|
||||
return None
|
||||
else:
|
||||
return query.get_icon()
|
||||
|
||||
def _make_parts(self, parent, child, pp):
|
||||
parts = []
|
||||
|
||||
# We went from parent, to child, using pp
|
||||
idx = len(pp) - 1
|
||||
|
||||
while idx >= 0:
|
||||
if pp[idx] == '..':
|
||||
parts.insert(0, '..')
|
||||
else:
|
||||
parts.insert(0, child.get_basename())
|
||||
child = child.get_parent()
|
||||
|
||||
idx -= 1
|
||||
|
||||
return parts
|
||||
|
||||
def normalize_relative(self, parts):
|
||||
if not parts:
|
||||
return []
|
||||
|
||||
out = self.normalize_relative(parts[:-1])
|
||||
|
||||
if parts[-1] == '..':
|
||||
if not out or (out[-1] == '..') or len(out) == 1:
|
||||
out.append('..')
|
||||
else:
|
||||
del out[-1]
|
||||
else:
|
||||
out.append(parts[-1])
|
||||
|
||||
return out
|
||||
|
||||
def _append_to_store(self, item):
|
||||
if not item in self._stored_items:
|
||||
self._store.append(item)
|
||||
self._stored_items[item] = True
|
||||
|
||||
def _clear_store(self):
|
||||
self._store.clear()
|
||||
self._stored_items = {}
|
||||
|
||||
def _show_virtuals(self):
|
||||
for d in self._dirs:
|
||||
if isinstance(d, VirtualDirectory):
|
||||
for entry in d.enumerate_children("standard::*"):
|
||||
self._append_to_store((entry[1].get_icon(), xml.sax.saxutils.escape(entry[1].get_name()), entry[0], entry[1].get_file_type()))
|
||||
|
||||
def _remove_cursor(self):
|
||||
if self._cursor:
|
||||
path = self._cursor.get_path()
|
||||
self._cursor = None
|
||||
|
||||
self._store.row_changed(path, self._store.get_iter(path))
|
||||
|
||||
def do_search(self):
|
||||
self.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH))
|
||||
self._remove_cursor()
|
||||
|
||||
text = self._entry.get_text().strip()
|
||||
self._clear_store()
|
||||
|
||||
if text == '':
|
||||
self._show_virtuals()
|
||||
else:
|
||||
parts = self.normalize_relative(text.split(os.sep))
|
||||
files = []
|
||||
|
||||
for d in self._dirs:
|
||||
for entry in self.do_search_dir(parts, d):
|
||||
pathparts = self._make_parts(d, entry[0], parts)
|
||||
self._append_to_store((entry[3], self.make_markup(parts, pathparts), entry[0], entry[2]))
|
||||
|
||||
piter = self._store.get_iter_first()
|
||||
|
||||
if piter:
|
||||
self._treeview.get_selection().select_path(self._store.get_path(piter))
|
||||
|
||||
self.window.set_cursor(None)
|
||||
|
||||
def do_show(self):
|
||||
gtk.Window.do_show(self)
|
||||
|
||||
self._entry.grab_focus()
|
||||
self._entry.set_text("")
|
||||
|
||||
self.do_search()
|
||||
|
||||
def on_changed(self, editable):
|
||||
self.do_search()
|
||||
self.on_selection_changed(self._treeview.get_selection())
|
||||
|
||||
def _shift_extend(self, towhere):
|
||||
selection = self._treeview.get_selection()
|
||||
|
||||
if not self._shift_start:
|
||||
model, rows = selection.get_selected_rows()
|
||||
start = rows[0]
|
||||
|
||||
self._shift_start = gtk.TreeRowReference(self._store, start)
|
||||
else:
|
||||
start = self._shift_start.get_path()
|
||||
|
||||
selection.unselect_all()
|
||||
selection.select_range(start, towhere)
|
||||
|
||||
def _select_index(self, idx, hasctrl, hasshift):
|
||||
path = (idx,)
|
||||
|
||||
if not (hasctrl or hasshift):
|
||||
self._treeview.get_selection().unselect_all()
|
||||
|
||||
if hasshift:
|
||||
self._shift_extend(path)
|
||||
else:
|
||||
self._shift_start = None
|
||||
|
||||
if not hasctrl:
|
||||
self._treeview.get_selection().select_path(path)
|
||||
|
||||
self._treeview.scroll_to_cell(path, None, True, 0.5, 0)
|
||||
self._remove_cursor()
|
||||
|
||||
if hasctrl or hasshift:
|
||||
self._cursor = gtk.TreeRowReference(self._store, path)
|
||||
|
||||
piter = self._store.get_iter(path)
|
||||
self._store.row_changed(path, piter)
|
||||
|
||||
def _move_selection(self, howmany, hasctrl, hasshift):
|
||||
num = self._store.iter_n_children(None)
|
||||
|
||||
if num == 0:
|
||||
return True
|
||||
|
||||
# Test for cursor
|
||||
path = None
|
||||
|
||||
if self._cursor:
|
||||
path = self._cursor.get_path()
|
||||
else:
|
||||
model, rows = self._treeview.get_selection().get_selected_rows()
|
||||
|
||||
if len(rows) == 1:
|
||||
path = rows[0]
|
||||
|
||||
if not path:
|
||||
if howmany > 0:
|
||||
self._select_index(0, hasctrl, hasshift)
|
||||
else:
|
||||
self._select_index(num - 1, hasctrl, hasshift)
|
||||
else:
|
||||
idx = path[0]
|
||||
|
||||
if idx + howmany < 0:
|
||||
self._select_index(0, hasctrl, hasshift)
|
||||
elif idx + howmany >= num:
|
||||
self._select_index(num - 1, hasctrl, hasshift)
|
||||
else:
|
||||
self._select_index(idx + howmany, hasctrl, hasshift)
|
||||
|
||||
return True
|
||||
|
||||
def _direct_file(self):
|
||||
uri = self._entry.get_text()
|
||||
gfile = None
|
||||
|
||||
if gedit.utils.uri_is_valid(uri):
|
||||
gfile = gio.File(uri)
|
||||
elif os.path.isabs(uri):
|
||||
f = gio.File(uri)
|
||||
|
||||
if f.query_exists():
|
||||
gfile = f
|
||||
|
||||
return gfile
|
||||
|
||||
def _activate(self):
|
||||
model, rows = self._treeview.get_selection().get_selected_rows()
|
||||
ret = True
|
||||
|
||||
for row in rows:
|
||||
s = model.get_iter(row)
|
||||
info = model.get(s, 2, 3)
|
||||
|
||||
if info[1] != gio.FILE_TYPE_DIRECTORY:
|
||||
ret = ret and self._handler(info[0])
|
||||
else:
|
||||
text = self._entry.get_text()
|
||||
|
||||
for i in range(len(text) - 1, -1, -1):
|
||||
if text[i] == os.sep:
|
||||
break
|
||||
|
||||
self._entry.set_text(os.path.join(text[:i], os.path.basename(info[0].get_uri())) + os.sep)
|
||||
self._entry.set_position(-1)
|
||||
self._entry.grab_focus()
|
||||
return True
|
||||
|
||||
if rows and ret:
|
||||
self.destroy()
|
||||
|
||||
if not rows:
|
||||
gfile = self._direct_file()
|
||||
|
||||
if gfile and self._handler(gfile):
|
||||
self.destroy()
|
||||
else:
|
||||
ret = False
|
||||
else:
|
||||
ret = False
|
||||
|
||||
return ret
|
||||
|
||||
def toggle_cursor(self):
|
||||
if not self._cursor:
|
||||
return
|
||||
|
||||
path = self._cursor.get_path()
|
||||
selection = self._treeview.get_selection()
|
||||
|
||||
if selection.path_is_selected(path):
|
||||
selection.unselect_path(path)
|
||||
else:
|
||||
selection.select_path(path)
|
||||
|
||||
def on_key_press_event(self, widget, event):
|
||||
move_mapping = {
|
||||
gtk.keysyms.Down: 1,
|
||||
gtk.keysyms.Up: -1,
|
||||
gtk.keysyms.Page_Down: 5,
|
||||
gtk.keysyms.Page_Up: -5
|
||||
}
|
||||
|
||||
if event.keyval == gtk.keysyms.Escape:
|
||||
self.destroy()
|
||||
return True
|
||||
elif event.keyval in move_mapping:
|
||||
return self._move_selection(move_mapping[event.keyval], event.state & gtk.gdk.CONTROL_MASK, event.state & gtk.gdk.SHIFT_MASK)
|
||||
elif event.keyval in [gtk.keysyms.Return, gtk.keysyms.KP_Enter, gtk.keysyms.Tab, gtk.keysyms.ISO_Left_Tab]:
|
||||
return self._activate()
|
||||
elif event.keyval == gtk.keysyms.space and event.state & gtk.gdk.CONTROL_MASK:
|
||||
self.toggle_cursor()
|
||||
|
||||
return False
|
||||
|
||||
def on_row_activated(self, view, path, column):
|
||||
self._activate()
|
||||
|
||||
def do_response(self, response):
|
||||
if response != gtk.RESPONSE_ACCEPT or not self._activate():
|
||||
self.destroy()
|
||||
|
||||
def on_selection_changed(self, selection):
|
||||
model, rows = selection.get_selected_rows()
|
||||
|
||||
gfile = None
|
||||
fname = None
|
||||
|
||||
if not rows:
|
||||
gfile = self._direct_file()
|
||||
elif len(rows) == 1:
|
||||
gfile = model.get(model.get_iter(rows[0]), 2)[0]
|
||||
else:
|
||||
fname = ''
|
||||
|
||||
if gfile:
|
||||
if gfile.is_native():
|
||||
fname = xml.sax.saxutils.escape(gfile.get_path())
|
||||
else:
|
||||
fname = xml.sax.saxutils.escape(gfile.get_uri())
|
||||
|
||||
self._open_button.set_sensitive(fname != None)
|
||||
self._info_label.set_markup(fname or '')
|
||||
|
||||
def on_focus_entry(self, group, accel, keyval, modifier):
|
||||
self._entry.grab_focus()
|
||||
|
||||
gobject.type_register(Popup)
|
||||
|
||||
# ex:ts=8:et:
|
87
plugins/quickopen/quickopen/virtualdirs.py
Executable file
87
plugins/quickopen/quickopen/virtualdirs.py
Executable file
@@ -0,0 +1,87 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright (C) 2009 - Jesse van den Kieboom
|
||||
#
|
||||
# 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 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, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
# Boston, MA 02111-1307, USA.
|
||||
|
||||
import gtk
|
||||
import gio
|
||||
|
||||
class VirtualDirectory:
|
||||
def __init__(self, name):
|
||||
self._name = name
|
||||
self._children = []
|
||||
|
||||
def get_uri(self):
|
||||
return 'virtual://' + self._name
|
||||
|
||||
def get_parent(self):
|
||||
return None
|
||||
|
||||
def enumerate_children(self, attr):
|
||||
return self._children
|
||||
|
||||
def append(self, child):
|
||||
if not child.is_native():
|
||||
return
|
||||
|
||||
try:
|
||||
info = child.query_info("standard::*")
|
||||
|
||||
if info:
|
||||
self._children.append((child, info))
|
||||
except:
|
||||
pass
|
||||
|
||||
class RecentDocumentsDirectory(VirtualDirectory):
|
||||
def __init__(self, maxitems=10, screen=None):
|
||||
VirtualDirectory.__init__(self, 'recent')
|
||||
|
||||
self._maxitems = maxitems
|
||||
self.fill(screen)
|
||||
|
||||
def fill(self, screen):
|
||||
if screen:
|
||||
manager = gtk.recent_manager_get_for_screen(screen)
|
||||
else:
|
||||
manager = gtk.recent_manager_get_default()
|
||||
|
||||
items = manager.get_items()
|
||||
items.sort(lambda a, b: cmp(b.get_visited(), a.get_visited()))
|
||||
|
||||
added = 0
|
||||
|
||||
for item in items:
|
||||
if item.has_group('gedit'):
|
||||
self.append(gio.File(item.get_uri()))
|
||||
added += 1
|
||||
|
||||
if added >= self._maxitems:
|
||||
break
|
||||
|
||||
class CurrentDocumentsDirectory(VirtualDirectory):
|
||||
def __init__(self, window):
|
||||
VirtualDirectory.__init__(self, 'documents')
|
||||
|
||||
self.fill(window)
|
||||
|
||||
def fill(self, window):
|
||||
for doc in window.get_documents():
|
||||
location = doc.get_location()
|
||||
if location:
|
||||
self.append(location)
|
||||
|
||||
# ex:ts=8:et:
|
198
plugins/quickopen/quickopen/windowhelper.py
Executable file
198
plugins/quickopen/quickopen/windowhelper.py
Executable file
@@ -0,0 +1,198 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright (C) 2009 - Jesse van den Kieboom
|
||||
#
|
||||
# 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 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, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
# Boston, MA 02111-1307, USA.
|
||||
|
||||
import gedit
|
||||
import gtk
|
||||
from popup import Popup
|
||||
import os
|
||||
import gedit.commands
|
||||
import gio
|
||||
import glib
|
||||
from virtualdirs import RecentDocumentsDirectory
|
||||
from virtualdirs import CurrentDocumentsDirectory
|
||||
|
||||
ui_str = """<ui>
|
||||
<menubar name="MenuBar">
|
||||
<menu name="FileMenu" action="File">
|
||||
<placeholder name="FileOps_2">
|
||||
<menuitem name="QuickOpen" action="QuickOpen"/>
|
||||
</placeholder>
|
||||
</menu>
|
||||
</menubar>
|
||||
</ui>
|
||||
"""
|
||||
|
||||
class WindowHelper:
|
||||
def __init__(self, window, plugin):
|
||||
self._window = window
|
||||
self._plugin = plugin
|
||||
|
||||
self._popup = None
|
||||
self._install_menu()
|
||||
|
||||
def deactivate(self):
|
||||
self._uninstall_menu()
|
||||
self._window = None
|
||||
self._plugin = None
|
||||
|
||||
def update_ui(self):
|
||||
pass
|
||||
|
||||
def _uninstall_menu(self):
|
||||
manager = self._window.get_ui_manager()
|
||||
|
||||
manager.remove_ui(self._ui_id)
|
||||
manager.remove_action_group(self._action_group)
|
||||
|
||||
manager.ensure_update()
|
||||
|
||||
def _install_menu(self):
|
||||
manager = self._window.get_ui_manager()
|
||||
self._action_group = gtk.ActionGroup("GeditQuickOpenPluginActions")
|
||||
self._action_group.add_actions([
|
||||
("QuickOpen", gtk.STOCK_OPEN, _("Quick open"),
|
||||
'<Ctrl><Alt>O', _("Quickly open documents"),
|
||||
self.on_quick_open_activate)
|
||||
])
|
||||
|
||||
manager.insert_action_group(self._action_group, -1)
|
||||
self._ui_id = manager.add_ui_from_string(ui_str)
|
||||
|
||||
def _create_popup(self):
|
||||
paths = []
|
||||
|
||||
# Open documents
|
||||
paths.append(CurrentDocumentsDirectory(self._window))
|
||||
|
||||
doc = self._window.get_active_document()
|
||||
|
||||
# Current document directory
|
||||
if doc and doc.is_local():
|
||||
gfile = doc.get_location()
|
||||
paths.append(gfile.get_parent())
|
||||
|
||||
# File browser root directory
|
||||
if gedit.version[0] > 2 or (gedit.version[0] == 2 and (gedit.version[1] > 26 or (gedit.version[1] == 26 and gedit.version[2] >= 2))):
|
||||
bus = self._window.get_message_bus()
|
||||
|
||||
try:
|
||||
msg = bus.send_sync('/plugins/filebrowser', 'get_root')
|
||||
|
||||
if msg:
|
||||
uri = msg.get_value('uri')
|
||||
|
||||
if uri:
|
||||
gfile = gio.File(uri)
|
||||
|
||||
if gfile.is_native():
|
||||
paths.append(gfile)
|
||||
|
||||
except StandardError:
|
||||
pass
|
||||
|
||||
# Recent documents
|
||||
paths.append(RecentDocumentsDirectory(screen=self._window.get_screen()))
|
||||
|
||||
# Local bookmarks
|
||||
for path in self._local_bookmarks():
|
||||
paths.append(path)
|
||||
|
||||
# Desktop directory
|
||||
desktopdir = self._desktop_dir()
|
||||
|
||||
if desktopdir:
|
||||
paths.append(gio.File(desktopdir))
|
||||
|
||||
# Home directory
|
||||
paths.append(gio.File(os.path.expanduser('~')))
|
||||
|
||||
self._popup = Popup(self._window, paths, self.on_activated)
|
||||
|
||||
self._popup.set_default_size(*self._plugin.get_popup_size())
|
||||
self._popup.set_transient_for(self._window)
|
||||
self._popup.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
|
||||
|
||||
self._window.get_group().add_window(self._popup)
|
||||
|
||||
self._popup.connect('destroy', self.on_popup_destroy)
|
||||
|
||||
def _local_bookmarks(self):
|
||||
filename = os.path.expanduser('~/.gtk-bookmarks')
|
||||
|
||||
if not os.path.isfile(filename):
|
||||
return []
|
||||
|
||||
paths = []
|
||||
|
||||
for line in file(filename, 'r').xreadlines():
|
||||
uri = line.strip().split(" ")[0]
|
||||
f = gio.File(uri)
|
||||
|
||||
if f.is_native():
|
||||
try:
|
||||
info = f.query_info("standard::type")
|
||||
|
||||
if info and info.get_file_type() == gio.FILE_TYPE_DIRECTORY:
|
||||
paths.append(f)
|
||||
except glib.GError:
|
||||
pass
|
||||
|
||||
return paths
|
||||
|
||||
def _desktop_dir(self):
|
||||
config = os.getenv('XDG_CONFIG_HOME')
|
||||
|
||||
if not config:
|
||||
config = os.path.expanduser('~/.config')
|
||||
|
||||
config = os.path.join(config, 'user-dirs.dirs')
|
||||
desktopdir = None
|
||||
|
||||
if os.path.isfile(config):
|
||||
for line in file(config, 'r').xreadlines():
|
||||
line = line.strip()
|
||||
|
||||
if line.startswith('XDG_DESKTOP_DIR'):
|
||||
parts = line.split('=', 1)
|
||||
desktopdir = os.path.expandvars(parts[1].strip('"').strip("'"))
|
||||
break
|
||||
|
||||
if not desktopdir:
|
||||
desktopdir = os.path.expanduser('~/Desktop')
|
||||
|
||||
return desktopdir
|
||||
|
||||
# Callbacks
|
||||
def on_quick_open_activate(self, action):
|
||||
if not self._popup:
|
||||
self._create_popup()
|
||||
|
||||
self._popup.show()
|
||||
|
||||
def on_popup_destroy(self, popup):
|
||||
alloc = popup.get_allocation()
|
||||
self._plugin.set_popup_size((alloc.width, alloc.height))
|
||||
|
||||
self._popup = None
|
||||
|
||||
def on_activated(self, gfile):
|
||||
gedit.commands.load_uri(self._window, gfile.get_uri(), None, -1)
|
||||
return True
|
||||
|
||||
# ex:ts=8:et:
|
15
plugins/snippets/Makefile.am
Executable file
15
plugins/snippets/Makefile.am
Executable file
@@ -0,0 +1,15 @@
|
||||
# Python snippets plugin
|
||||
SUBDIRS = snippets data
|
||||
plugindir = $(GEDIT_PLUGINS_LIBS_DIR)
|
||||
|
||||
plugin_in_files = snippets.gedit-plugin.desktop.in
|
||||
%.gedit-plugin: %.gedit-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:.gedit-plugin.desktop.in=.gedit-plugin)
|
||||
|
||||
EXTRA_DIST = $(plugin_in_files)
|
||||
|
||||
CLEANFILES = $(plugin_DATA)
|
||||
DISTCLEANFILES = $(plugin_DATA)
|
||||
|
||||
-include $(top_srcdir)/git.mk
|
33
plugins/snippets/data/Makefile.am
Executable file
33
plugins/snippets/data/Makefile.am
Executable file
@@ -0,0 +1,33 @@
|
||||
# Python snippets plugin
|
||||
SUBDIRS = lang
|
||||
|
||||
snippets_DATA = \
|
||||
css.xml \
|
||||
c.xml \
|
||||
cpp.xml \
|
||||
chdr.xml \
|
||||
docbook.xml \
|
||||
fortran.xml \
|
||||
global.xml \
|
||||
haskell.xml \
|
||||
html.xml \
|
||||
idl.xml \
|
||||
javascript.xml \
|
||||
java.xml \
|
||||
latex.xml \
|
||||
mallard.xml \
|
||||
perl.xml \
|
||||
php.xml \
|
||||
python.xml \
|
||||
ruby.xml \
|
||||
sh.xml \
|
||||
snippets.xml \
|
||||
tcl.xml \
|
||||
xml.xml \
|
||||
xslt.xml
|
||||
|
||||
snippetsdir = $(GEDIT_PLUGINS_DATA_DIR)/snippets
|
||||
|
||||
EXTRA_DIST = $(snippets_DATA)
|
||||
|
||||
-include $(top_srcdir)/git.mk
|
283
plugins/snippets/data/c.xml
Executable file
283
plugins/snippets/data/c.xml
Executable file
@@ -0,0 +1,283 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<snippets language="C">
|
||||
<snippet id="gpl">
|
||||
<text><![CDATA[/*
|
||||
* ${1:[$GEDIT_CURRENT_DOCUMENT_NAME,<filename>]}
|
||||
* This file is part of ${2:<program name>}
|
||||
*
|
||||
* Copyright (C) $<3: import datetime; return str(datetime.date.today().year)> - $<4:
|
||||
import pwd, os
|
||||
try:
|
||||
return pwd.getpwuid(os.getuid()).pw_gecos.split(',')[0]
|
||||
except KeyError:
|
||||
return '<author\>' >
|
||||
*
|
||||
* ${2} 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* ${2} 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 ${2}; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
$0]]></text>
|
||||
<tag>gpl</tag>
|
||||
<description>GPL License</description>
|
||||
</snippet>
|
||||
<snippet id="lgpl">
|
||||
<text><![CDATA[/*
|
||||
* ${1:[$GEDIT_CURRENT_DOCUMENT_NAME,<filename>]}
|
||||
* This file is part of ${2:<library name>}
|
||||
*
|
||||
* Copyright (C) $<3: import datetime; return str(datetime.date.today().year)> - $<4:
|
||||
import pwd, os
|
||||
try:
|
||||
return pwd.getpwuid(os.getuid()).pw_gecos.split(',')[0]
|
||||
except KeyError:
|
||||
return '<author\>' >
|
||||
*
|
||||
* ${2} is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* ${2} 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
$0]]></text>
|
||||
<tag>lgpl</tag>
|
||||
<description>LGPL License</description>
|
||||
</snippet>
|
||||
<snippet id="do">
|
||||
<text><![CDATA[do
|
||||
{
|
||||
$0
|
||||
} while ($1);]]></text>
|
||||
<tag>do</tag>
|
||||
<description>do .. while</description>
|
||||
</snippet>
|
||||
<snippet id="for">
|
||||
<text><![CDATA[for (${1:i} = ${2:0}; ${1:i} < ${3:count}; ${1:i} += ${4:1})
|
||||
{
|
||||
$0
|
||||
}]]></text>
|
||||
<tag>for</tag>
|
||||
<description>for loop</description>
|
||||
</snippet>
|
||||
<snippet id="while">
|
||||
<text><![CDATA[while (${1:condition})
|
||||
{
|
||||
$0
|
||||
}]]></text>
|
||||
<tag>while</tag>
|
||||
<description>while loop</description>
|
||||
</snippet>
|
||||
<snippet id="if">
|
||||
<text><![CDATA[if (${1:condition})
|
||||
{
|
||||
$0
|
||||
}]]></text>
|
||||
<tag>if</tag>
|
||||
<description>if</description>
|
||||
</snippet>
|
||||
<snippet id="elif">
|
||||
<text><![CDATA[else if (${1:condition})
|
||||
{
|
||||
$0
|
||||
}]]></text>
|
||||
<tag>elif</tag>
|
||||
<description>else if</description>
|
||||
</snippet>
|
||||
<snippet id="else">
|
||||
<text><![CDATA[else
|
||||
{
|
||||
$0
|
||||
}]]></text>
|
||||
<tag>else</tag>
|
||||
<description>else</description>
|
||||
</snippet>
|
||||
<snippet id="Inc">
|
||||
<text><![CDATA[#include <${1:file}.h>
|
||||
$0]]></text>
|
||||
<tag>Inc</tag>
|
||||
<description>#include <..></description>
|
||||
</snippet>
|
||||
<snippet id="inc">
|
||||
<text><![CDATA[#include "${1:file}.h"
|
||||
$0]]></text>
|
||||
<tag>inc</tag>
|
||||
<description>#include ".."</description>
|
||||
</snippet>
|
||||
<snippet id="main">
|
||||
<text><![CDATA[int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
$0
|
||||
return 0;
|
||||
}]]></text>
|
||||
<tag>main</tag>
|
||||
<description>main</description>
|
||||
</snippet>
|
||||
<snippet id="struct">
|
||||
<text><![CDATA[struct ${1:name}
|
||||
{
|
||||
${0:/* data */}
|
||||
};]]></text>
|
||||
<tag>struct</tag>
|
||||
<description>struct</description>
|
||||
</snippet>
|
||||
<snippet id="endif">
|
||||
<text><![CDATA[#endif
|
||||
$0]]></text>
|
||||
<description>#endif</description>
|
||||
<accelerator><![CDATA[<Control><Alt>period]]></accelerator>
|
||||
</snippet>
|
||||
<snippet id="td">
|
||||
<text><![CDATA[typedef ${1:newtype} ${2:type};
|
||||
$0]]></text>
|
||||
<tag>td</tag>
|
||||
<description>typedef</description>
|
||||
</snippet>
|
||||
<snippet id="gobject">
|
||||
<text><![CDATA[#include "$1.h"
|
||||
$<
|
||||
global camel_str,low_str, type_str, is_str, up_str
|
||||
components = $1.split('-')
|
||||
low_str = '_'.join(components).lower()
|
||||
up_str = '_'.join(components).upper()
|
||||
type_str = '_'.join([components[0], 'TYPE'] + components[1:]).upper()
|
||||
is_str = '_'.join([components[0], 'IS'] + components[1:]).upper()
|
||||
camel_str = ''
|
||||
|
||||
for t in components:
|
||||
camel_str += t.capitalize()
|
||||
>
|
||||
|
||||
#define $<[1]: return up_str >_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), $<[1]: return type_str >, $<[1]: return camel_str >Private))
|
||||
|
||||
struct _$<[1]: return camel_str >Private
|
||||
{
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE ($<[1]: return camel_str >, $<[1]: return low_str >, ${2:G_TYPE_OBJECT})
|
||||
|
||||
static void
|
||||
$<[1]: return low_str>_finalize (GObject *object)
|
||||
{
|
||||
G_OBJECT_CLASS ($<[1]: return low_str >_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
$<[1]: return low_str >_class_init ($<[1]: return camel_str >Class *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->finalize = $<[1]: return low_str >_finalize;
|
||||
|
||||
g_type_class_add_private (object_class, sizeof ($<[1]: return camel_str >Private));
|
||||
}
|
||||
|
||||
static void
|
||||
$<[1]: return low_str >_init ($<[1]: return camel_str> *self)
|
||||
{
|
||||
self->priv = $<[1]: return up_str >_GET_PRIVATE (self);
|
||||
}
|
||||
|
||||
$<[1]: return camel_str > *
|
||||
$<[1]: return low_str >_new ()
|
||||
{
|
||||
return g_object_new ($<[1]: return type_str >, NULL);
|
||||
}]]></text>
|
||||
<tag>gobject</tag>
|
||||
<description>GObject template</description>
|
||||
</snippet>
|
||||
<snippet id="ginterface">
|
||||
<text><![CDATA[#include "$1.h"
|
||||
$<
|
||||
global camel_str,low_str,up_str
|
||||
components = $1.split('-')
|
||||
low_str = '_'.join(components).lower()
|
||||
up_str = '_'.join(components).upper()
|
||||
camel_str = ''
|
||||
|
||||
for t in components:
|
||||
camel_str += t.capitalize()
|
||||
>
|
||||
/* Default implementation */
|
||||
static const gchar *
|
||||
$<[1]: return low_str>_example_method_default ($<[1]: return camel_str > *self)
|
||||
{
|
||||
g_return_val_if_reached (NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
$<[1]: return low_str>_init ($<[1]: return camel_str >Iface *iface)
|
||||
{
|
||||
static gboolean initialized = FALSE;
|
||||
|
||||
iface->example_method = $<[1]: return low_str>_example_method_default;
|
||||
|
||||
if (!initialized)
|
||||
{
|
||||
initialized = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This is an method example for an interface
|
||||
*/
|
||||
const gchar *
|
||||
$<[1]: return low_str>_example_method ($<[1]: return camel_str > *self)
|
||||
{
|
||||
g_return_val_if_fail ($<[1]: return up_str> (self), NULL);
|
||||
return $<[1]: return up_str>_GET_INTERFACE (self)->example_method (self);
|
||||
}
|
||||
|
||||
GType
|
||||
$<[1]: return low_str>_get_type ()
|
||||
{
|
||||
static GType $<[1]: return low_str>_type_id = 0;
|
||||
|
||||
if (!$<[1]: return low_str>_type_id)
|
||||
{
|
||||
static const GTypeInfo g_define_type_info =
|
||||
{
|
||||
sizeof ($<[1]: return camel_str >Iface),
|
||||
(GBaseInitFunc) $<[1]: return low_str>_init,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
NULL
|
||||
};
|
||||
|
||||
$<[1]: return low_str>_type_id =
|
||||
g_type_register_static (G_TYPE_INTERFACE,
|
||||
"$<[1]: return camel_str>",
|
||||
&g_define_type_info,
|
||||
0);
|
||||
}
|
||||
|
||||
return $<[1]: return low_str>_type_id;
|
||||
}]]></text>
|
||||
<tag>ginterface</tag>
|
||||
<description>GObject interface</description>
|
||||
</snippet>
|
||||
</snippets>
|
241
plugins/snippets/data/chdr.xml
Executable file
241
plugins/snippets/data/chdr.xml
Executable file
@@ -0,0 +1,241 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<snippets language="chdr">
|
||||
<snippet id="once">
|
||||
<text><![CDATA[#ifndef __${1:NAME}_H__
|
||||
#define __$1_H__
|
||||
|
||||
$0
|
||||
|
||||
#endif /* __$1_H__ */
|
||||
]]></text>
|
||||
<description>Header Include-Guard</description>
|
||||
<tag>once</tag>
|
||||
</snippet>
|
||||
<snippet id="inc">
|
||||
<text><![CDATA[#include "${1:file}"
|
||||
$0]]></text>
|
||||
<description>#include ".."</description>
|
||||
<tag>inc</tag>
|
||||
</snippet>
|
||||
<snippet id="Inc">
|
||||
<text><![CDATA[#include <${1:file}>
|
||||
$0]]></text>
|
||||
<description>#include <..></description>
|
||||
<tag>Inc</tag>
|
||||
</snippet>
|
||||
<snippet id="namespace">
|
||||
<text><![CDATA[namespace ${1:ns}
|
||||
{
|
||||
$0
|
||||
};
|
||||
]]></text>
|
||||
<description>namespace ..</description>
|
||||
<tag>namespace</tag>
|
||||
</snippet>
|
||||
<snippet id="gpl">
|
||||
<text><![CDATA[/*
|
||||
* ${1:[$GEDIT_CURRENT_DOCUMENT_NAME,<filename>]}
|
||||
* This file is part of ${2:<program name>}
|
||||
*
|
||||
* Copyright (C) $<3: import datetime; return str(datetime.date.today().year)> - $<4:
|
||||
import pwd, os
|
||||
try:
|
||||
return pwd.getpwuid(os.getuid()).pw_gecos.split(',')[0]
|
||||
except KeyError:
|
||||
return '<author\>' >
|
||||
*
|
||||
* ${2} 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* ${2} 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 ${2}; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
$0]]></text>
|
||||
<tag>gpl</tag>
|
||||
<description>GPL License</description>
|
||||
</snippet>
|
||||
<snippet id="lgpl">
|
||||
<text><![CDATA[/*
|
||||
* ${1:[$GEDIT_CURRENT_DOCUMENT_NAME,<filename>]}
|
||||
* This file is part of ${2:<library name>}
|
||||
*
|
||||
* Copyright (C) $<3: import datetime; return str(datetime.date.today().year)> - $<4:
|
||||
import pwd, os
|
||||
try:
|
||||
return pwd.getpwuid(os.getuid()).pw_gecos.split(',')[0]
|
||||
except KeyError:
|
||||
return '<author\>' >
|
||||
*
|
||||
* ${2} is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* ${2} 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
$0]]></text>
|
||||
<tag>lgpl</tag>
|
||||
<description>LGPL License</description>
|
||||
</snippet>
|
||||
<snippet id="td">
|
||||
<text><![CDATA[typedef ${1:newtype} ${2:type};
|
||||
$0]]></text>
|
||||
<tag>td</tag>
|
||||
<description>typedef</description>
|
||||
</snippet>
|
||||
<snippet id="class">
|
||||
<text><![CDATA[class ${1:name}
|
||||
{
|
||||
public:
|
||||
${1:name} (${2:arguments});
|
||||
virtual ~${1:name} ();
|
||||
|
||||
private:
|
||||
${0:/* data */}
|
||||
};]]></text>
|
||||
<description>class ..</description>
|
||||
<tag>class</tag>
|
||||
</snippet>
|
||||
<snippet id="struct">
|
||||
<text><![CDATA[struct ${1:name}
|
||||
{
|
||||
${0:/* data */}
|
||||
};]]></text>
|
||||
<tag>struct</tag>
|
||||
<description>struct</description>
|
||||
</snippet>
|
||||
<snippet id="template">
|
||||
<text><![CDATA[template <typename ${1:_InputIter}>]]></text>
|
||||
<description>template <typename ..></description>
|
||||
<tag>template</tag>
|
||||
</snippet>
|
||||
<snippet id="gobject">
|
||||
<text><![CDATA[#ifndef __${1:NAME}_H__
|
||||
#define __$1_H__
|
||||
|
||||
#include <${2:glib-object.h}>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
$<
|
||||
global camel_str
|
||||
components = $1.split('_')
|
||||
type_str = '_'.join([components[0], 'TYPE'] + components[1:])
|
||||
is_str = '_'.join([components[0], 'IS'] + components[1:])
|
||||
camel_str = ''
|
||||
|
||||
for t in components:
|
||||
camel_str += t.capitalize()
|
||||
|
||||
items = [ \
|
||||
['#define ' + type_str, '(' + $1.lower() + '_get_type ())'], \
|
||||
['#define ' + $1 + '(obj)', '(G_TYPE_CHECK_INSTANCE_CAST ((obj), ' + type_str + ', ' + camel_str + '))'], \
|
||||
['#define ' + $1 + '_CONST(obj)', '(G_TYPE_CHECK_INSTANCE_CAST ((obj), ' + type_str + ', ' + camel_str + ' const))'], \
|
||||
['#define ' + $1 + '_CLASS(klass)', '(G_TYPE_CHECK_CLASS_CAST ((klass), ' + type_str + ', ' + camel_str + 'Class))'], \
|
||||
['#define ' + is_str + '(obj)', '(G_TYPE_CHECK_INSTANCE_TYPE ((obj), ' + type_str + '))'], \
|
||||
['#define ' + is_str + '_CLASS(klass)', '(G_TYPE_CHECK_CLASS_TYPE ((klass), ' + type_str + '))'], \
|
||||
['#define ' + $1 + '_GET_CLASS(obj)', '(G_TYPE_INSTANCE_GET_CLASS ((obj), ' + type_str + ', ' + camel_str + 'Class))']
|
||||
]
|
||||
|
||||
return align(items) >
|
||||
|
||||
$<[1]:
|
||||
items = [ \
|
||||
['typedef struct _' + camel_str, camel_str + ';'], \
|
||||
['typedef struct _' + camel_str + 'Class', camel_str + 'Class;'], \
|
||||
['typedef struct _' + camel_str + 'Private', camel_str + 'Private;'] \
|
||||
]
|
||||
|
||||
return align(items) >
|
||||
|
||||
struct _$<[1]: return camel_str > {
|
||||
${7:GObject} parent;
|
||||
|
||||
$<[1]: return camel_str >Private *priv;
|
||||
};
|
||||
|
||||
struct _$<[1]: return camel_str >Class {
|
||||
$7Class parent_class;
|
||||
};
|
||||
|
||||
GType $< return $1.lower() + '_get_type' > (void) G_GNUC_CONST;
|
||||
$<[1]: return camel_str > *$< return $1.lower()>_new (void);
|
||||
|
||||
$0
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __$1_H__ */]]></text>
|
||||
<tag>gobject</tag>
|
||||
<description>GObject template</description>
|
||||
</snippet>
|
||||
<snippet id="ginterface">
|
||||
<text><![CDATA[#ifndef __${1:NAME}_H__
|
||||
#define __$1_H__
|
||||
|
||||
#include <${2:glib-object.h}>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
$<
|
||||
global camel_str
|
||||
components = $1.split('_')
|
||||
type_str = '_'.join([components[0], 'TYPE'] + components[1:])
|
||||
is_str = '_'.join([components[0], 'IS'] + components[1:])
|
||||
camel_str = ''
|
||||
|
||||
for t in components:
|
||||
camel_str += t.capitalize()
|
||||
|
||||
items = [ \
|
||||
['#define ' + type_str, '(' + $1.lower() + '_get_type ())'], \
|
||||
['#define ' + $1 + '(obj)', '(G_TYPE_CHECK_INSTANCE_CAST ((obj), ' + type_str + ', ' + camel_str + '))'], \
|
||||
['#define ' + is_str + '(obj)', '(G_TYPE_CHECK_INSTANCE_TYPE ((obj), ' + type_str + '))'], \
|
||||
['#define ' + $1 + '_GET_INTERFACE(obj)', '(G_TYPE_INSTANCE_GET_INTERFACE ((obj), ' + type_str + ', ' + camel_str + 'Iface))']
|
||||
]
|
||||
|
||||
return align(items) >
|
||||
|
||||
$<[1]:
|
||||
items = [ \
|
||||
['typedef struct _' + camel_str, camel_str + ';'], \
|
||||
['typedef struct _' + camel_str + 'Iface', camel_str + 'Iface;'], \
|
||||
]
|
||||
|
||||
return align(items) >
|
||||
|
||||
struct _$<[1]: return camel_str >Iface
|
||||
{
|
||||
${7:GTypeInterface} parent;
|
||||
|
||||
const gchar * (*example_method) ($<[1]: return camel_str > *self);
|
||||
};
|
||||
|
||||
GType $< return $1.lower() + '_get_type' > (void) G_GNUC_CONST;
|
||||
|
||||
const gchar *$< return $1.lower()>_example_method ($<[1]: return camel_str > *self);
|
||||
$0
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __$1_H__ */]]></text>
|
||||
<tag>ginterface</tag>
|
||||
<description>GObject interface</description>
|
||||
</snippet>
|
||||
</snippets>
|
183
plugins/snippets/data/cpp.xml
Executable file
183
plugins/snippets/data/cpp.xml
Executable file
@@ -0,0 +1,183 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<snippets language="cpp">
|
||||
<snippet id="main">
|
||||
<text><![CDATA[int main (int argc, char const* argv[])
|
||||
{
|
||||
$0
|
||||
return 0;
|
||||
}]]></text>
|
||||
<description>main</description>
|
||||
<tag>main</tag>
|
||||
</snippet>
|
||||
<snippet id="for">
|
||||
<text><![CDATA[for (${1:unsigned int} ${2:i} = ${3:0}; ${2:i} < ${4:count}; ${2:i} += ${5:1})
|
||||
{
|
||||
$0
|
||||
}]]></text>
|
||||
<description>for loop</description>
|
||||
<tag>for</tag>
|
||||
</snippet>
|
||||
<snippet id="beginend">
|
||||
<text><![CDATA[${1:v}.begin(), ${1:v}.end()]]></text>
|
||||
<description>$1.begin</description>
|
||||
<tag>beginend</tag>
|
||||
</snippet>
|
||||
<snippet id="do">
|
||||
<text><![CDATA[do
|
||||
{
|
||||
$0
|
||||
} while ($1 );]]></text>
|
||||
<description>do .. while</description>
|
||||
<tag>do</tag>
|
||||
</snippet>
|
||||
<snippet id="endif">
|
||||
<text><![CDATA[#endif
|
||||
$0]]></text>
|
||||
<accelerator><![CDATA[<Control><Alt>period]]></accelerator>
|
||||
<description>#endif</description>
|
||||
</snippet>
|
||||
<snippet id="if">
|
||||
<text><![CDATA[if (${1:condition})
|
||||
{
|
||||
$0
|
||||
}]]></text>
|
||||
<description>if ..</description>
|
||||
<tag>if</tag>
|
||||
</snippet>
|
||||
<snippet id="inc">
|
||||
<text><![CDATA[#include "${1:file}"
|
||||
$0]]></text>
|
||||
<description>#include ".."</description>
|
||||
<tag>inc</tag>
|
||||
</snippet>
|
||||
<snippet id="Inc">
|
||||
<text><![CDATA[#include <${1:file}>
|
||||
$0]]></text>
|
||||
<description>#include <..></description>
|
||||
<tag>Inc</tag>
|
||||
</snippet>
|
||||
<snippet id="namespace">
|
||||
<text><![CDATA[namespace ${1:ns}
|
||||
{
|
||||
$0
|
||||
};
|
||||
]]></text>
|
||||
<description>namespace ..</description>
|
||||
<tag>namespace</tag>
|
||||
</snippet>
|
||||
<snippet id="readfile">
|
||||
<text><![CDATA[std::vector<uint8_t> v;
|
||||
if (FILE* fp = fopen (${1:"filename"}, "r"))
|
||||
{
|
||||
uint8_t buf[1024];
|
||||
while (size_t len = fread (buf, 1, sizeof (buf), fp))
|
||||
v.insert (v.end(), buf, buf + len);
|
||||
fclose(fp);
|
||||
}
|
||||
$0]]></text>
|
||||
<description>Read File Into Vector</description>
|
||||
<tag>readfile</tag>
|
||||
</snippet>
|
||||
<snippet id="map">
|
||||
<text><![CDATA[std::map<${1:key}, ${2:value}> ${3:map};
|
||||
$0]]></text>
|
||||
<description>std::map</description>
|
||||
<tag>map</tag>
|
||||
</snippet>
|
||||
<snippet id="vector">
|
||||
<text><![CDATA[std::vector<${1:char}> ${2:v};
|
||||
$0]]></text>
|
||||
<description>std::vector</description>
|
||||
<tag>vector</tag>
|
||||
</snippet>
|
||||
<snippet id="struct">
|
||||
<text><![CDATA[struct ${1:name}
|
||||
{
|
||||
${0:/* data */}
|
||||
};]]></text>
|
||||
<description>struct ..</description>
|
||||
<tag>struct</tag>
|
||||
</snippet>
|
||||
<snippet id="template">
|
||||
<text><![CDATA[template <typename ${1:_InputIter}>]]></text>
|
||||
<description>template <typename ..></description>
|
||||
<tag>template</tag>
|
||||
</snippet>
|
||||
<snippet id="gpl">
|
||||
<text><![CDATA[/*
|
||||
* ${1:[$GEDIT_CURRENT_DOCUMENT_NAME,<filename>]}
|
||||
* This file is part of ${2:<program name>}
|
||||
*
|
||||
* Copyright (C) $<3: import datetime; return str(datetime.date.today().year)> - $<4:
|
||||
import pwd, os
|
||||
try:
|
||||
return pwd.getpwuid(os.getuid()).pw_gecos.split(',')[0]
|
||||
except KeyError:
|
||||
return '<author\>' >
|
||||
*
|
||||
* ${2} 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* ${2} 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 ${2}; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
$0]]></text>
|
||||
<tag>gpl</tag>
|
||||
<description>GPL License</description>
|
||||
</snippet>
|
||||
<snippet id="lgpl">
|
||||
<text><![CDATA[/*
|
||||
* ${1:[$GEDIT_CURRENT_DOCUMENT_NAME,<filename>]}
|
||||
* This file is part of ${2:<library name>}
|
||||
*
|
||||
* Copyright (C) $<3: import datetime; return str(datetime.date.today().year)> - $<4:
|
||||
import pwd, os
|
||||
try:
|
||||
return pwd.getpwuid(os.getuid()).pw_gecos.split(',')[0]
|
||||
except KeyError:
|
||||
return '<author\>' >
|
||||
*
|
||||
* ${2} is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* ${2} 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
$0]]></text>
|
||||
<tag>lgpl</tag>
|
||||
<description>LGPL License</description>
|
||||
</snippet>
|
||||
<snippet id="td">
|
||||
<text><![CDATA[typedef ${1:newtype} ${2:type};
|
||||
$0]]></text>
|
||||
<tag>td</tag>
|
||||
<description>typedef</description>
|
||||
</snippet>
|
||||
<snippet id="while">
|
||||
<text><![CDATA[while ($1)
|
||||
{
|
||||
$0
|
||||
}]]></text>
|
||||
<tag>while</tag>
|
||||
<description>while</description>
|
||||
</snippet>
|
||||
</snippets>
|
557
plugins/snippets/data/css.xml
Executable file
557
plugins/snippets/data/css.xml
Executable file
@@ -0,0 +1,557 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<snippets language="CSS">
|
||||
<snippet id="background">
|
||||
<text><![CDATA[background-attachment: ${1:scroll/fixed};
|
||||
$0]]></text>
|
||||
<description>background-attachment: scroll/fixed</description>
|
||||
<tag>background</tag>
|
||||
</snippet>
|
||||
<snippet id="background-1">
|
||||
<text><![CDATA[background-color: #${1:DDD};
|
||||
$0]]></text>
|
||||
<description>background-color: color-hex</description>
|
||||
<tag>background</tag>
|
||||
</snippet>
|
||||
<snippet id="background-2">
|
||||
<text><![CDATA[background-color: ${1:red};
|
||||
$0]]></text>
|
||||
<description>background-color: color-name</description>
|
||||
<tag>background</tag>
|
||||
</snippet>
|
||||
<snippet id="background-3">
|
||||
<text><![CDATA[background-color: rgb(${1:255},${2:255},${3:255});
|
||||
$0]]></text>
|
||||
<description>background-color: color-rgb</description>
|
||||
<tag>background</tag>
|
||||
</snippet>
|
||||
<snippet id="background-4">
|
||||
<text><![CDATA[background: #${1:DDD} url($2) ${3:repeat/repeat-x/repeat-y/no-repeat} ${4:scroll/fixed} ${5:top letft/top center/top right/center left/center center/center right/bottom left/bottom center/bottom right/x-% y-%/x-pos y-pos};
|
||||
$0]]></text>
|
||||
<description>background: color image repeat attachment position</description>
|
||||
<tag>background</tag>
|
||||
</snippet>
|
||||
<snippet id="background-5">
|
||||
<text><![CDATA[background-color: transparent;
|
||||
$0]]></text>
|
||||
<description>background-color: transparent</description>
|
||||
<tag>background</tag>
|
||||
</snippet>
|
||||
<snippet id="background-6">
|
||||
<text><![CDATA[background-image: none;
|
||||
$0]]></text>
|
||||
<description>background-image: none</description>
|
||||
<tag>background</tag>
|
||||
</snippet>
|
||||
<snippet id="background-7">
|
||||
<text><![CDATA[background-image: url($1);
|
||||
$0]]></text>
|
||||
<description>background-image: url</description>
|
||||
<tag>background</tag>
|
||||
</snippet>
|
||||
<snippet id="background-8">
|
||||
<text><![CDATA[background-position: ${1:top letft/top center/top right/center left/center center/center right/bottom left/bottom center/bottom right/x-% y-%/x-pos y-pos};
|
||||
$0]]></text>
|
||||
<description>background-position: position</description>
|
||||
<tag>background</tag>
|
||||
</snippet>
|
||||
<snippet id="background-9">
|
||||
<text><![CDATA[background-repeat: ${1:repeat/repeat-x/repeat-y/no-repeat};
|
||||
$0]]></text>
|
||||
<description>background-repeat: r/r-x/r-y/n-r</description>
|
||||
<tag>background</tag>
|
||||
</snippet>
|
||||
<snippet id="border">
|
||||
<text><![CDATA[border-bottom-color: #${1:999};
|
||||
$0]]></text>
|
||||
<description>border-bottom-color: size style color</description>
|
||||
<tag>border</tag>
|
||||
</snippet>
|
||||
<snippet id="border-1">
|
||||
<text><![CDATA[border-bottom: ${1:1}px ${2:solid} #${3:999};
|
||||
$0]]></text>
|
||||
<description>border-bottom: size style color</description>
|
||||
<tag>border</tag>
|
||||
</snippet>
|
||||
<snippet id="border-2">
|
||||
<text><![CDATA[border-bottom-style: ${1:none/hidden/dotted/dashed/solid/double/groove/ridge/inset/outset};
|
||||
$0]]></text>
|
||||
<description>border-bottom-style: size style color</description>
|
||||
<tag>border</tag>
|
||||
</snippet>
|
||||
<snippet id="border-3">
|
||||
<text><![CDATA[border-bottom-width: ${1:1}px ${2:solid} #${3:999};
|
||||
$0]]></text>
|
||||
<description>border-bottom-width: size style color</description>
|
||||
<tag>border</tag>
|
||||
</snippet>
|
||||
<snippet id="border-4">
|
||||
<text><![CDATA[border-color: ${1:999};
|
||||
$0]]></text>
|
||||
<description>border-color: color</description>
|
||||
<tag>border</tag>
|
||||
</snippet>
|
||||
<snippet id="border-5">
|
||||
<text><![CDATA[border-right-color: #${1:999};
|
||||
$0]]></text>
|
||||
<description>border-left-color: color</description>
|
||||
<tag>border</tag>
|
||||
</snippet>
|
||||
<snippet id="border-6">
|
||||
<text><![CDATA[border-left: ${1:1}px ${2:solid} #${3:999};
|
||||
$0]]></text>
|
||||
<description>border-left: size style color</description>
|
||||
<tag>border</tag>
|
||||
</snippet>
|
||||
<snippet id="border-7">
|
||||
<text><![CDATA[border-left-style: ${1:none/hidden/dotted/dashed/solid/double/groove/ridge/inset/outset};
|
||||
$0]]></text>
|
||||
<description>border-left-style: style</description>
|
||||
<tag>border</tag>
|
||||
</snippet>
|
||||
<snippet id="border-8">
|
||||
<text><![CDATA[border-left-width: ${1:1}px ${2:solid} #${3:999};
|
||||
$0]]></text>
|
||||
<description>border-left-width: size</description>
|
||||
<tag>border</tag>
|
||||
</snippet>
|
||||
<snippet id="border-9">
|
||||
<text><![CDATA[border-right-color: #${1:999};
|
||||
$0]]></text>
|
||||
<description>border-right-color: color</description>
|
||||
<tag>border</tag>
|
||||
</snippet>
|
||||
<snippet id="border-10">
|
||||
<text><![CDATA[border-right: ${1:1}px ${2:solid} #${3:999};
|
||||
$0]]></text>
|
||||
<description>border-right: size style color</description>
|
||||
<tag>border</tag>
|
||||
</snippet>
|
||||
<snippet id="border-11">
|
||||
<text><![CDATA[border-right-style: ${1:none/hidden/dotted/dashed/solid/double/groove/ridge/inset/outset};
|
||||
$0]]></text>
|
||||
<description>border-right-style: style</description>
|
||||
<tag>border</tag>
|
||||
</snippet>
|
||||
<snippet id="border-12">
|
||||
<text><![CDATA[border-right-width: ${1:1}px ${2:solid} #${3:999};
|
||||
$0]]></text>
|
||||
<description>border-right-width: size</description>
|
||||
<tag>border</tag>
|
||||
</snippet>
|
||||
<snippet id="border-13">
|
||||
<text><![CDATA[border: ${1:1px} ${2:solid} #${3:999};
|
||||
$0]]></text>
|
||||
<description>border: size style color</description>
|
||||
<tag>border</tag>
|
||||
</snippet>
|
||||
<snippet id="border-14">
|
||||
<text><![CDATA[border-style: ${1:none/hidden/dotted/dashed/solid/double/groove/ridge/inset/outset};
|
||||
$0]]></text>
|
||||
<description>border-style: style</description>
|
||||
<tag>border</tag>
|
||||
</snippet>
|
||||
<snippet id="border-15">
|
||||
<text><![CDATA[border-top-color: #${1:999};
|
||||
$0]]></text>
|
||||
<description>border-top-color: color</description>
|
||||
<tag>border</tag>
|
||||
</snippet>
|
||||
<snippet id="border-16">
|
||||
<text><![CDATA[border-top: ${1:1}px ${2:solid} #${3:999};
|
||||
$0]]></text>
|
||||
<description>border-top: size style color</description>
|
||||
<tag>border</tag>
|
||||
</snippet>
|
||||
<snippet id="border-17">
|
||||
<text><![CDATA[border-top-style: ${1:none/hidden/dotted/dashed/solid/double/groove/ridge/inset/outset};
|
||||
$0]]></text>
|
||||
<description>border-top-style: style</description>
|
||||
<tag>border</tag>
|
||||
</snippet>
|
||||
<snippet id="border-18">
|
||||
<text><![CDATA[border-top-width: ${1:1}px ${2:solid} #${3:999};
|
||||
$0]]></text>
|
||||
<description>border-top-width: size</description>
|
||||
<tag>border</tag>
|
||||
</snippet>
|
||||
<snippet id="border-19">
|
||||
<text><![CDATA[border-color: ${1:1px};
|
||||
$0]]></text>
|
||||
<description>border-width: width</description>
|
||||
<tag>border</tag>
|
||||
</snippet>
|
||||
<snippet id="clear">
|
||||
<text><![CDATA[clear: ${1:left/right/both/none};
|
||||
$0]]></text>
|
||||
<description>clear: value</description>
|
||||
<tag>clear</tag>
|
||||
</snippet>
|
||||
<snippet id="color">
|
||||
<text><![CDATA[color: #${1:DDD};
|
||||
$0]]></text>
|
||||
<description>color: color-hex</description>
|
||||
<tag>color</tag>
|
||||
</snippet>
|
||||
<snippet id="color-1">
|
||||
<text><![CDATA[color: ${1:red};
|
||||
$0]]></text>
|
||||
<description>color: color-name</description>
|
||||
<tag>color</tag>
|
||||
</snippet>
|
||||
<snippet id="color-2">
|
||||
<text><![CDATA[color: rgb(${1:255},${2:255},${3:255});
|
||||
$0]]></text>
|
||||
<description>color: color-rgb</description>
|
||||
<tag>color</tag>
|
||||
</snippet>
|
||||
<snippet id="cursor">
|
||||
<text><![CDATA[cursor: {$1:default/auto/crosshair/pointer/move/*-resize/text/wait/help};
|
||||
$0]]></text>
|
||||
<description>cursor: type</description>
|
||||
<tag>cursor</tag>
|
||||
</snippet>
|
||||
<snippet id="clear-1">
|
||||
<text><![CDATA[cursor: url($1);
|
||||
$0]]></text>
|
||||
<description>cursor: url</description>
|
||||
<tag>clear</tag>
|
||||
</snippet>
|
||||
<snippet id="direction">
|
||||
<text><![CDATA[direction: ${1:ltr|rtl};
|
||||
$0]]></text>
|
||||
<description>direction: ltr|rtl</description>
|
||||
<tag>direction</tag>
|
||||
</snippet>
|
||||
<snippet id="display">
|
||||
<text><![CDATA[display: block;
|
||||
$0]]></text>
|
||||
<description>display: block</description>
|
||||
<tag>display</tag>
|
||||
</snippet>
|
||||
<snippet id="display-1">
|
||||
<text><![CDATA[display: ${1:none/inline/block/list-item/run-in/compact/marker};
|
||||
$0]]></text>
|
||||
<description>display: common-types</description>
|
||||
<tag>display</tag>
|
||||
</snippet>
|
||||
<snippet id="display-2">
|
||||
<text><![CDATA[display: inline;
|
||||
$0]]></text>
|
||||
<description>display: inline</description>
|
||||
<tag>display</tag>
|
||||
</snippet>
|
||||
<snippet id="display-3">
|
||||
<text><![CDATA[display: ${1:table/inline-table/table-row-group/table-header-group/table-footer-group/table-row/table-column-group/table-column/table-cell/table-caption};
|
||||
$0]]></text>
|
||||
<description>display: table-types</description>
|
||||
<tag>display</tag>
|
||||
</snippet>
|
||||
<snippet id="float">
|
||||
<text><![CDATA[float: ${1:left/right/none};
|
||||
$0]]></text>
|
||||
<description>float: left/right/none</description>
|
||||
<tag>float</tag>
|
||||
</snippet>
|
||||
<snippet id="font">
|
||||
<text><![CDATA[font-family: ${1:Arial, "MS Trebuchet"}, ${2:sans-}serif;
|
||||
$0]]></text>
|
||||
<description>font-family: family</description>
|
||||
<tag>font</tag>
|
||||
</snippet>
|
||||
<snippet id="font-1">
|
||||
<text><![CDATA[font: ${1:75%} ${2:"Lucida Grande", "Trebuchet MS", Verdana,} ${3:sans-}serif;
|
||||
$0]]></text>
|
||||
<description>font: size font</description>
|
||||
<tag>font</tag>
|
||||
</snippet>
|
||||
<snippet id="font-2">
|
||||
<text><![CDATA[font-size: ${1:100%};
|
||||
$0]]></text>
|
||||
<description>font-size: size</description>
|
||||
<tag>font</tag>
|
||||
</snippet>
|
||||
<snippet id="font-3">
|
||||
<text><![CDATA[font-style: ${1:normal/italic/oblique};
|
||||
$0]]></text>
|
||||
<description>font-style: normal/italic/oblique</description>
|
||||
<tag>font</tag>
|
||||
</snippet>
|
||||
<snippet id="font-4">
|
||||
<text><![CDATA[font: ${1:normal/italic/oblique} ${2:normal/small-caps} ${3:normal/bold} ${4:1em/1.5em} ${5:Arial}, ${6:sans-}serif;
|
||||
$0]]></text>
|
||||
<description>font: style variant weight size/line-height font-family</description>
|
||||
<tag>font</tag>
|
||||
</snippet>
|
||||
<snippet id="font-5">
|
||||
<text><![CDATA[font-variant: ${1:normal/small-caps};
|
||||
$0]]></text>
|
||||
<description>font-variant: normal/small-caps</description>
|
||||
<tag>font</tag>
|
||||
</snippet>
|
||||
<snippet id="font-6">
|
||||
<text><![CDATA[font-weight: ${1:normal/bold};
|
||||
$0]]></text>
|
||||
<description>font-weight: weight</description>
|
||||
<tag>font</tag>
|
||||
</snippet>
|
||||
<snippet id="letter">
|
||||
<text><![CDATA[letter-spacing: $1em;
|
||||
$0]]></text>
|
||||
<description>letter-spacing: length-em</description>
|
||||
<tag>letter</tag>
|
||||
</snippet>
|
||||
<snippet id="letter-1">
|
||||
<text><![CDATA[letter-spacing: $1px;
|
||||
$0]]></text>
|
||||
<description>letter-spacing: length-px</description>
|
||||
<tag>letter</tag>
|
||||
</snippet>
|
||||
<snippet id="list">
|
||||
<text><![CDATA[list-style-image: url($1);
|
||||
$0]]></text>
|
||||
<description>list-style-image: url</description>
|
||||
<tag>list</tag>
|
||||
</snippet>
|
||||
<snippet id="list-1">
|
||||
<text><![CDATA[list-style-position: ${1:inside/outside};
|
||||
$0]]></text>
|
||||
<description>list-style-position: pos</description>
|
||||
<tag>list</tag>
|
||||
</snippet>
|
||||
<snippet id="list-2">
|
||||
<text><![CDATA[list-style-type: ${1:cjk-ideographic/hiragana/katakana/hiragana-iroha/katakana-iroha};
|
||||
$0]]></text>
|
||||
<description>list-style-type: asian</description>
|
||||
<tag>list</tag>
|
||||
</snippet>
|
||||
<snippet id="list-3">
|
||||
<text><![CDATA[list-style-type: ${1:none/disc/circle/square};
|
||||
$0]]></text>
|
||||
<description>list-style-type: marker</description>
|
||||
<tag>list</tag>
|
||||
</snippet>
|
||||
<snippet id="list-4">
|
||||
<text><![CDATA[list-style-type: ${1:decimal/decimal-leading-zero/zero};
|
||||
$0]]></text>
|
||||
<description>list-style-type: numeric</description>
|
||||
<tag>list</tag>
|
||||
</snippet>
|
||||
<snippet id="list-5">
|
||||
<text><![CDATA[list-style-type: ${1:hebrew/armenian/georgian};
|
||||
$0]]></text>
|
||||
<description>list-style-type: other</description>
|
||||
<tag>list</tag>
|
||||
</snippet>
|
||||
<snippet id="list-6">
|
||||
<text><![CDATA[list-style: ${1:none/disc/circle/square/decimal/zero} ${2:inside/outside} url($3);
|
||||
$0]]></text>
|
||||
<description>list-style: type position image</description>
|
||||
<tag>list</tag>
|
||||
</snippet>
|
||||
<snippet id="list-7">
|
||||
<text><![CDATA[list-style-type: ${1:lower-roman/uppert-roman/lower-alpha/upper-alpha/lower-greek/lower-latin/upper-latin};
|
||||
$0]]></text>
|
||||
<description>list-style-type: roman-alpha-greek</description>
|
||||
<tag>list</tag>
|
||||
</snippet>
|
||||
<snippet id="margin">
|
||||
<text><![CDATA[margin: ${1:20px};
|
||||
$0]]></text>
|
||||
<description>margin: all</description>
|
||||
<tag>margin</tag>
|
||||
</snippet>
|
||||
<snippet id="margin-1">
|
||||
<text><![CDATA[margin-bottom: ${1:20px};
|
||||
$0]]></text>
|
||||
<description>margin-bottom: length</description>
|
||||
<tag>margin</tag>
|
||||
</snippet>
|
||||
<snippet id="margin-2">
|
||||
<text><![CDATA[margin-left: ${1:20px};
|
||||
$0]]></text>
|
||||
<description>margin-left: length</description>
|
||||
<tag>margin</tag>
|
||||
</snippet>
|
||||
<snippet id="margin-3">
|
||||
<text><![CDATA[margin-right: ${1:20px};
|
||||
$0]]></text>
|
||||
<description>margin-right: length</description>
|
||||
<tag>margin</tag>
|
||||
</snippet>
|
||||
<snippet id="margin-4">
|
||||
<text><![CDATA[margin-top: ${1:20px};
|
||||
$0]]></text>
|
||||
<description>margin-top: length</description>
|
||||
<tag>margin</tag>
|
||||
</snippet>
|
||||
<snippet id="margin-5">
|
||||
<text><![CDATA[margin: ${1:20px} ${2:0px} ${3:40px} ${4:0px};
|
||||
$0]]></text>
|
||||
<description>margin: T R B L</description>
|
||||
<tag>margin</tag>
|
||||
</snippet>
|
||||
<snippet id="margin-6">
|
||||
<text><![CDATA[margin: ${1:20px} ${2:0px};
|
||||
$0]]></text>
|
||||
<description>margin: V H</description>
|
||||
<tag>margin</tag>
|
||||
</snippet>
|
||||
<snippet id="marker">
|
||||
<text><![CDATA[marker-offset: auto;
|
||||
$0]]></text>
|
||||
<description>marker-offset: auto</description>
|
||||
<tag>marker</tag>
|
||||
</snippet>
|
||||
<snippet id="marker-1">
|
||||
<text><![CDATA[marker-offset: ${1:10px};
|
||||
$0]]></text>
|
||||
<description>marker-offset: length</description>
|
||||
<tag>marker</tag>
|
||||
</snippet>
|
||||
<snippet id="overflow">
|
||||
<text><![CDATA[overflow: ${1:visible/hidden/scroll/auto};
|
||||
$0]]></text>
|
||||
<description>overflow: type</description>
|
||||
<tag>overflow</tag>
|
||||
</snippet>
|
||||
<snippet id="padding">
|
||||
<text><![CDATA[padding: ${1:20px};
|
||||
$0]]></text>
|
||||
<description>padding: all</description>
|
||||
<tag>padding</tag>
|
||||
</snippet>
|
||||
<snippet id="margin-7">
|
||||
<text><![CDATA[padding-bottom: ${1:20px};
|
||||
$0]]></text>
|
||||
<description>padding-bottom: length</description>
|
||||
<tag>margin</tag>
|
||||
</snippet>
|
||||
<snippet id="margin-8">
|
||||
<text><![CDATA[padding-left: ${1:20px};
|
||||
$0]]></text>
|
||||
<description>padding-left: length</description>
|
||||
<tag>margin</tag>
|
||||
</snippet>
|
||||
<snippet id="margin-9">
|
||||
<text><![CDATA[padding-right: ${1:20px};
|
||||
$0]]></text>
|
||||
<description>padding-right: length</description>
|
||||
<tag>margin</tag>
|
||||
</snippet>
|
||||
<snippet id="margin-10">
|
||||
<text><![CDATA[padding-top: ${1:20px};
|
||||
$0]]></text>
|
||||
<description>padding-top: length</description>
|
||||
<tag>margin</tag>
|
||||
</snippet>
|
||||
<snippet id="padding-1">
|
||||
<text><![CDATA[padding: ${1:20px} ${2:0px} ${3:40px} ${4:0px};
|
||||
$0]]></text>
|
||||
<description>padding: T R B L</description>
|
||||
<tag>padding</tag>
|
||||
</snippet>
|
||||
<snippet id="padding-2">
|
||||
<text><![CDATA[padding: ${1:20px} ${2:0px};
|
||||
$0]]></text>
|
||||
<description>padding: V H</description>
|
||||
<tag>padding</tag>
|
||||
</snippet>
|
||||
<snippet id="position">
|
||||
<text><![CDATA[position: ${1:static/relative/absolute/fixed};
|
||||
$0]]></text>
|
||||
<description>position: type</description>
|
||||
<tag>position</tag>
|
||||
</snippet>
|
||||
<snippet id="{">
|
||||
<text><![CDATA[{
|
||||
/* $1 */
|
||||
$0
|
||||
]]></text>
|
||||
<description>properties { }</description>
|
||||
<tag>{</tag>
|
||||
</snippet>
|
||||
<snippet id="text">
|
||||
<text><![CDATA[text-align: ${1:left/right/center/justify};
|
||||
$0]]></text>
|
||||
<description>text-align: left/center/right</description>
|
||||
<tag>text</tag>
|
||||
</snippet>
|
||||
<snippet id="text-1">
|
||||
<text><![CDATA[text-decoration: ${1:none/underline/overline/line-through/blink};
|
||||
$0]]></text>
|
||||
<description>text-decoration: none/underline/overline/line-through/blink</description>
|
||||
<tag>text</tag>
|
||||
</snippet>
|
||||
<snippet id="text-2">
|
||||
<text><![CDATA[text-indent: ${1:10p}x;
|
||||
$0]]></text>
|
||||
<description>text-indent: length</description>
|
||||
<tag>text</tag>
|
||||
</snippet>
|
||||
<snippet id="text-3">
|
||||
<text><![CDATA[text-shadow: #${1:DDD} ${2:10px} ${3:10px} ${4:2px};
|
||||
$0]]></text>
|
||||
<description>text-shadow: color-hex x y blur</description>
|
||||
<tag>text</tag>
|
||||
</snippet>
|
||||
<snippet id="text-4">
|
||||
<text><![CDATA[text-shadow: rgb(${1:255},${2:255},${3:255}) ${4:10px} ${5:10px} ${6:2px};
|
||||
$0]]></text>
|
||||
<description>text-shadow: color-rgb x y blur</description>
|
||||
<tag>text</tag>
|
||||
</snippet>
|
||||
<snippet id="text-5">
|
||||
<text><![CDATA[text-shadow: none;
|
||||
$0]]></text>
|
||||
<description>text-shadow: none</description>
|
||||
<tag>text</tag>
|
||||
</snippet>
|
||||
<snippet id="text-6">
|
||||
<text><![CDATA[text-transform: ${1:capitalize/uppercase/lowercase};
|
||||
$0]]></text>
|
||||
<description>text-transform: capitalize/upper/lower</description>
|
||||
<tag>text</tag>
|
||||
</snippet>
|
||||
<snippet id="text-7">
|
||||
<text><![CDATA[text-transform: none;
|
||||
$0]]></text>
|
||||
<description>text-transform: none</description>
|
||||
<tag>text</tag>
|
||||
</snippet>
|
||||
<snippet id="vertical">
|
||||
<text><![CDATA[vertical-align: ${1:baseline/sub/super/top/text-top/middle/bottom/text-bottom/length/%};
|
||||
$0]]></text>
|
||||
<description>vertical-align: type</description>
|
||||
<tag>vertical</tag>
|
||||
</snippet>
|
||||
<snippet id="visibility">
|
||||
<text><![CDATA[visibility: ${1:visible/hidden/collapse};
|
||||
$0]]></text>
|
||||
<description>visibility: type</description>
|
||||
<tag>visibility</tag>
|
||||
</snippet>
|
||||
<snippet id="white">
|
||||
<text><![CDATA[white-space: ${1:normal/pre/nowrap};
|
||||
$0]]></text>
|
||||
<description>white-space: normal/pre/nowrap</description>
|
||||
<tag>white</tag>
|
||||
</snippet>
|
||||
<snippet id="word">
|
||||
<text><![CDATA[word-spacing: ${1:10px};
|
||||
$0]]></text>
|
||||
<description>word-spacing: length</description>
|
||||
<tag>word</tag>
|
||||
</snippet>
|
||||
<snippet id="word-1">
|
||||
<text><![CDATA[word-spacing: normal;
|
||||
$0]]></text>
|
||||
<description>word-spacing: normal</description>
|
||||
<tag>word</tag>
|
||||
</snippet>
|
||||
<snippet id="z">
|
||||
<text><![CDATA[z-index: $1;
|
||||
$0]]></text>
|
||||
<description>z-index: index</description>
|
||||
<tag>z</tag>
|
||||
</snippet>
|
||||
</snippets>
|
118
plugins/snippets/data/docbook.xml
Executable file
118
plugins/snippets/data/docbook.xml
Executable file
@@ -0,0 +1,118 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<snippets language="docbook">
|
||||
<!-- useful snippets from xml set -->
|
||||
<snippet id="<">
|
||||
<text><![CDATA[<${1}>$0</${1}>]]></text>
|
||||
<description>XML tag</description>
|
||||
<tag><</tag>
|
||||
</snippet>
|
||||
<snippet id="menuchoice">
|
||||
<text><![CDATA[<menuchoice><guimenu>$1</guimenu><guimenuitem>$2</guimenuitem></menuchoice>
|
||||
]]></text>
|
||||
<tag>menu</tag>
|
||||
<description>menuchoice</description>
|
||||
<accelerator />
|
||||
</snippet>
|
||||
<snippet id="keycombo">
|
||||
<text><![CDATA[<keycombo><keycap>${1:Ctrl}</keycap><keycap>${2}</keycap></keycombo>]]></text>
|
||||
<tag>key</tag>
|
||||
<description>keycombo</description>
|
||||
<accelerator/>
|
||||
</snippet>
|
||||
<snippet id="sect">
|
||||
<text><![CDATA[<sect${1} id="${2}">
|
||||
<title>${3}</title>
|
||||
</sect${1}>]]></text>
|
||||
<tag>sect</tag>
|
||||
<description>sect*</description>
|
||||
<accelerator/>
|
||||
</snippet>
|
||||
<snippet id="app">
|
||||
<text><![CDATA[<application>&app;</application>]]></text>
|
||||
<tag>app</tag>
|
||||
<description>app entity</description>
|
||||
<accelerator/>
|
||||
</snippet>
|
||||
<snippet id="appwrap">
|
||||
<text><![CDATA[<application>$GEDIT_SELECTED_TEXT</application>]]></text>
|
||||
<tag>application</tag>
|
||||
<description>application tag</description>
|
||||
<accelerator/>
|
||||
</snippet>
|
||||
<snippet id="enclose">
|
||||
<text><![CDATA[<${1}>$GEDIT_SELECTED_TEXT</${1}>]]></text>
|
||||
<tag>enclose</tag>
|
||||
<description>enclose selected text</description>
|
||||
<accelerator/>
|
||||
</snippet>
|
||||
<snippet id="itemizedlist">
|
||||
<text><![CDATA[<itemizedlist>
|
||||
<listitem>
|
||||
<para>${1}</para>
|
||||
</listitem>
|
||||
</itemizedlist>]]></text>
|
||||
<tag>ul</tag>
|
||||
<description>itemized list</description>
|
||||
<accelerator/>
|
||||
</snippet>
|
||||
<snippet id="orderedlist">
|
||||
<text><![CDATA[<orderedlist>
|
||||
<listitem>
|
||||
<para>${1}</para>
|
||||
</listitem>
|
||||
</orderedlist>]]></text>
|
||||
<tag>ol</tag>
|
||||
<description>ordered list</description>
|
||||
<accelerator/>
|
||||
</snippet>
|
||||
<snippet id="listitem">
|
||||
<text><![CDATA[<listitem>
|
||||
<para>${1}</para>
|
||||
</listitem>]]></text>
|
||||
<tag>li</tag>
|
||||
<description>list item</description>
|
||||
<accelerator/>
|
||||
</snippet>
|
||||
<snippet id="variablelist">
|
||||
<text><![CDATA[<variablelist>
|
||||
$1
|
||||
</variablelist>]]></text>
|
||||
<tag>vl</tag>
|
||||
<description>variablelist</description>
|
||||
<accelerator/>
|
||||
</snippet>
|
||||
<snippet id="varlistentry">
|
||||
<text><![CDATA[<varlistentry><term>${1}</term>
|
||||
<listitem>
|
||||
<para>${2}</para>
|
||||
</listitem>
|
||||
</varlistentry>]]></text>
|
||||
<tag>vli</tag>
|
||||
<description>variablelist entry</description>
|
||||
<accelerator/>
|
||||
</snippet>
|
||||
<snippet id="closepara">
|
||||
<text><![CDATA[</para>]]></text>
|
||||
<tag>/</tag>
|
||||
<description>para close</description>
|
||||
<accelerator/>
|
||||
</snippet>
|
||||
<snippet id="openpara">
|
||||
<text><![CDATA[<para>]]></text>
|
||||
<tag>p</tag>
|
||||
<description>para open</description>
|
||||
<accelerator/>
|
||||
</snippet>
|
||||
<snippet id="http">
|
||||
<text><![CDATA[<ulink type="http" url="$1">$2</ulink>]]></text>
|
||||
<tag>http</tag>
|
||||
<description>ulink http</description>
|
||||
<accelerator/>
|
||||
</snippet>
|
||||
<snippet id="yelp">
|
||||
<text><![CDATA[<ulink type="help" url="$1">$2</ulink>]]></text>
|
||||
<tag>help</tag>
|
||||
<description>ulink mate help</description>
|
||||
<accelerator/>
|
||||
</snippet>
|
||||
</snippets>
|
164
plugins/snippets/data/fortran.xml
Executable file
164
plugins/snippets/data/fortran.xml
Executable file
@@ -0,0 +1,164 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<snippets language="fortran">
|
||||
<snippet id="c">
|
||||
<text><![CDATA[character(len=${1:10}) :: $0]]></text>
|
||||
<tag>c</tag>
|
||||
<description>character</description>
|
||||
</snippet>
|
||||
<snippet id="cl">
|
||||
<text><![CDATA[close(${1:unit}, status='${2:keep}')]]></text>
|
||||
<tag>cl</tag>
|
||||
<description>close</description>
|
||||
</snippet>
|
||||
<snippet id="do">
|
||||
<text><![CDATA[do ${1:i}=$2, $3, ${4:1}
|
||||
${0:source}
|
||||
end do]]></text>
|
||||
<tag>do</tag>
|
||||
<description>do ... end do</description>
|
||||
</snippet>
|
||||
<snippet id="func">
|
||||
<text><![CDATA[function ${1:name}( ${2:parameter} )
|
||||
${3:integer/real ::} $1
|
||||
${4:integer/real ::} $2
|
||||
|
||||
${0:source}
|
||||
|
||||
$1 = !result
|
||||
end function]]></text>
|
||||
<tag>func</tag>
|
||||
<description>function</description>
|
||||
</snippet>
|
||||
<snippet id="ifel">
|
||||
<text><![CDATA[if( $1 ) then
|
||||
${2:source}
|
||||
else
|
||||
${0:source}
|
||||
end if]]></text>
|
||||
<tag>ifel</tag>
|
||||
<description>if ... else ... end if</description>
|
||||
</snippet>
|
||||
<snippet id="if">
|
||||
<text><![CDATA[if( $1 ) then
|
||||
${0:source}
|
||||
end if]]></text>
|
||||
<tag>if</tag>
|
||||
<description>if ... end if</description>
|
||||
</snippet>
|
||||
<snippet id="i">
|
||||
<text><![CDATA[integer(kind=${1:4}) :: $0]]></text>
|
||||
<tag>i</tag>
|
||||
<description>integer</description>
|
||||
</snippet>
|
||||
<snippet id="ida">
|
||||
<text><![CDATA[integer(kind=${1:4}), dimension(${2::}), allocatable :: $0]]></text>
|
||||
<tag>ida</tag>
|
||||
<description>integerdimalloc</description>
|
||||
</snippet>
|
||||
<snippet id="id">
|
||||
<text><![CDATA[integer(kind=${1:4}), dimension(${2::}) :: $0]]></text>
|
||||
<tag>id</tag>
|
||||
<description>integerdim</description>
|
||||
</snippet>
|
||||
<snippet id="l">
|
||||
<text><![CDATA[logical(kind=${1:1}) :: $0]]></text>
|
||||
<tag>l</tag>
|
||||
<description>logical</description>
|
||||
</snippet>
|
||||
<snippet id="mod">
|
||||
<text><![CDATA[module ${1:name}
|
||||
implicit none
|
||||
${2:integer/real ::} $3
|
||||
|
||||
${4:contains}
|
||||
|
||||
${0:source}
|
||||
end module]]></text>
|
||||
<tag>mod</tag>
|
||||
<description>module</description>
|
||||
</snippet>
|
||||
<snippet id="op">
|
||||
<text><![CDATA[open(${1:unit}, file='${2:name}', status='${3:new}')]]></text>
|
||||
<tag>op</tag>
|
||||
<description>open</description>
|
||||
</snippet>
|
||||
<snippet id="prog">
|
||||
<text><![CDATA[program ${1:name}
|
||||
implicit none
|
||||
|
||||
${0:source}
|
||||
end program]]></text>
|
||||
<tag>prog</tag>
|
||||
<description>program</description>
|
||||
</snippet>
|
||||
<snippet id="re">
|
||||
<text><![CDATA[read(unit=${1:*},fmt=${2:*}) $0]]></text>
|
||||
<tag>re</tag>
|
||||
<description>read</description>
|
||||
</snippet>
|
||||
<snippet id="r">
|
||||
<text><![CDATA[real(kind=${1:8}) :: $0]]></text>
|
||||
<tag>r</tag>
|
||||
<description>real</description>
|
||||
</snippet>
|
||||
<snippet id="rda">
|
||||
<text><![CDATA[real(kind=${1:8}), dimension(${2::}), allocatable :: $0]]></text>
|
||||
<tag>rda</tag>
|
||||
<description>realdimalloc</description>
|
||||
</snippet>
|
||||
<snippet id="rd">
|
||||
<text><![CDATA[real(kind=${1:8}), dimension(${2::}) :: $0]]></text>
|
||||
<tag>rd</tag>
|
||||
<description>realdim</description>
|
||||
</snippet>
|
||||
<snippet id="rec">
|
||||
<text><![CDATA[recursive function ${1:name}( ${2:parameter} ) result( ${3:res} )
|
||||
${4:integer/real ::} $3
|
||||
${5:integer/real ::} $2
|
||||
|
||||
${0:source}
|
||||
|
||||
$3 = !result
|
||||
end function]]></text>
|
||||
<tag>rec</tag>
|
||||
<description>recursivfunc</description>
|
||||
</snippet>
|
||||
<snippet id="sel">
|
||||
<text><![CDATA[select case( $1 )
|
||||
case( $2 )
|
||||
${3:source}
|
||||
case default
|
||||
${0:source}
|
||||
end select]]></text>
|
||||
<tag>sel</tag>
|
||||
<description>select</description>
|
||||
</snippet>
|
||||
<snippet id="sub">
|
||||
<text><![CDATA[subroutine ${1:name}( ${2:parameter} )
|
||||
${3:integer/real ::} $2
|
||||
|
||||
${0:source}
|
||||
end subroutine]]></text>
|
||||
<tag>sub</tag>
|
||||
<description>subroutine</description>
|
||||
</snippet>
|
||||
<snippet id="t">
|
||||
<text><![CDATA[type :: ${1:name}
|
||||
${2:integer/real ::} $0
|
||||
end type $1]]></text>
|
||||
<tag>t</tag>
|
||||
<description>type</description>
|
||||
</snippet>
|
||||
<snippet id="dow">
|
||||
<text><![CDATA[do while( ${1} )
|
||||
${0:source}
|
||||
end do]]></text>
|
||||
<tag>dow</tag>
|
||||
<description>while</description>
|
||||
</snippet>
|
||||
<snippet id="wr">
|
||||
<text><![CDATA[write(unit=${1:*},fmt=${2:*}) "$3", $0]]></text>
|
||||
<tag>wr</tag>
|
||||
<description>write</description>
|
||||
</snippet>
|
||||
</snippets>
|
2
plugins/snippets/data/global.xml
Executable file
2
plugins/snippets/data/global.xml
Executable file
@@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<snippets/>
|
14
plugins/snippets/data/haskell.xml
Executable file
14
plugins/snippets/data/haskell.xml
Executable file
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<snippets language="Haskell">
|
||||
<snippet id="mod">
|
||||
<text><![CDATA[module ${1:Main} where
|
||||
$0]]></text>
|
||||
<description>module</description>
|
||||
<tag>mod</tag>
|
||||
</snippet>
|
||||
<snippet id="\">
|
||||
<text><![CDATA[\\${1:t} -> ${1:t}]]></text>
|
||||
<description>\t -> t</description>
|
||||
<tag>\</tag>
|
||||
</snippet>
|
||||
</snippets>
|
246
plugins/snippets/data/html.xml
Executable file
246
plugins/snippets/data/html.xml
Executable file
@@ -0,0 +1,246 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<snippets language="HTML">
|
||||
<snippet id="doctype">
|
||||
<text><![CDATA[<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
|
||||
"http://www.w3.org/TR/html4/strict.dtd">
|
||||
]]></text>
|
||||
<description>HTML — 4.01 Strict</description>
|
||||
<tag>doctype</tag>
|
||||
</snippet>
|
||||
<snippet id="doctype-1">
|
||||
<text><![CDATA[<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
|
||||
]]></text>
|
||||
<description>XHTML — 1.0 Frameset</description>
|
||||
<tag>doctype</tag>
|
||||
</snippet>
|
||||
<snippet id="doctype-2">
|
||||
<text><![CDATA[<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
]]></text>
|
||||
<description>XHTML — 1.0 Strict</description>
|
||||
<tag>doctype</tag>
|
||||
</snippet>
|
||||
<snippet id="doctype-3">
|
||||
<text><![CDATA[<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
]]></text>
|
||||
<description>XHTML — 1.0 Transitional</description>
|
||||
<tag>doctype</tag>
|
||||
</snippet>
|
||||
<snippet id="doctype-4">
|
||||
<text><![CDATA[<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
|
||||
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
||||
]]></text>
|
||||
<description>XHTML — 1.1</description>
|
||||
<tag>doctype</tag>
|
||||
</snippet>
|
||||
<snippet id="doctype-5">
|
||||
<text><![CDATA[<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
||||
]]></text>
|
||||
<description>HTML — 4.0 Transitional</description>
|
||||
<tag>doctype</tag>
|
||||
</snippet>
|
||||
<snippet id="author">
|
||||
<text><![CDATA[<meta name="author" content="${1:author}" />
|
||||
$0]]></text>
|
||||
<tag>author</tag>
|
||||
<description>Author</description>
|
||||
</snippet>
|
||||
<snippet id="date">
|
||||
<text><![CDATA[<meta name="date" content="$<1: import time; return time.strftime("%Y-%m-%d") >" />
|
||||
$0]]></text>
|
||||
<tag>date</tag>
|
||||
<description>Date</description>
|
||||
</snippet>
|
||||
<snippet id="ref">
|
||||
<text><![CDATA[<a href="${1:http://somesite.com/}">${2:$GEDIT_SELECTED_TEXT}</a>
|
||||
]]></text>
|
||||
<accelerator><![CDATA[<Shift><Alt>l]]></accelerator>
|
||||
<description>Wrap Selection as Link</description>
|
||||
<tag>ref</tag>
|
||||
</snippet>
|
||||
<snippet id="open/close">
|
||||
<text><![CDATA[<${1:p}>$GEDIT_SELECTED_TEXT</${1}>]]></text>
|
||||
<accelerator><![CDATA[<Shift><Alt>w]]></accelerator>
|
||||
<description>Wrap Selection in Open/Close Tag</description>
|
||||
</snippet>
|
||||
<snippet id="mailto">
|
||||
<text><![CDATA[<a href="mailto:${1:joe@example.com}?subject=${2:feedback}">${3:email me}</a> $0]]></text>
|
||||
<description>Mail Anchor</description>
|
||||
<tag>mailto</tag>
|
||||
</snippet>
|
||||
<snippet id="base">
|
||||
<text><![CDATA[<base href="$1" ${2}/>$0]]></text>
|
||||
<description>Base</description>
|
||||
<tag>base</tag>
|
||||
</snippet>
|
||||
<snippet id="body">
|
||||
<text><![CDATA[<body id="${1:ID} " onload="$2"}>
|
||||
$0
|
||||
</body>]]></text>
|
||||
<description>Body</description>
|
||||
<tag>body</tag>
|
||||
</snippet>
|
||||
<snippet id="br">
|
||||
<text><![CDATA[<br />
|
||||
$0]]></text>
|
||||
<accelerator><![CDATA[<Shift><Control>space]]></accelerator>
|
||||
<description>Br</description>
|
||||
</snippet>
|
||||
<snippet id="button">
|
||||
<text><![CDATA[<button type="button" name="${1:name}" value="${2:caption}" onclick="$3" />$4
|
||||
]]></text>
|
||||
<tag>button</tag>
|
||||
<description>Button</description>
|
||||
</snippet>
|
||||
<snippet id="div">
|
||||
<text><![CDATA[<div ${1}>
|
||||
${0:$GEDIT_SELECTED_TEXT}
|
||||
</div>]]></text>
|
||||
<description>Div</description>
|
||||
<tag>div</tag>
|
||||
</snippet>
|
||||
<snippet id="file">
|
||||
<text><![CDATA[<input type="file" name="${1:name}" size="$2" accept="$3" />$0
|
||||
]]></text>
|
||||
<tag>file</tag>
|
||||
<description>File</description>
|
||||
</snippet>
|
||||
<snippet id="form">
|
||||
<text><![CDATA[<form action="${1}" method="${2:get}">
|
||||
$0
|
||||
|
||||
<p><input type="submit" value="${3:Continue →}" /></p>
|
||||
</form>]]></text>
|
||||
<description>Form</description>
|
||||
<tag>form</tag>
|
||||
</snippet>
|
||||
<snippet id="h">
|
||||
<text><![CDATA[<h${1:1} id="${2}">${3:$GEDIT_SELECTED_TEXT}</h${1}>
|
||||
$0]]></text>
|
||||
<description>Heading</description>
|
||||
<tag>h</tag>
|
||||
</snippet>
|
||||
<snippet id="head">
|
||||
<text><![CDATA[<head>
|
||||
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
|
||||
<title>${1:Page Title}</title>
|
||||
$0
|
||||
</head>]]></text>
|
||||
<description>Head</description>
|
||||
<tag>head</tag>
|
||||
</snippet>
|
||||
<snippet id="image">
|
||||
<text><![CDATA[<img src="${1:path/to/file}" alt="${2:description}" title="${3:description}" width="$4" height="$5" />$0]]></text>
|
||||
<tag>img</tag>
|
||||
<description>Image</description>
|
||||
</snippet>
|
||||
<snippet id="input">
|
||||
<text><![CDATA[<input type="${1:[button,checkbox,file,hidden,image,password,radio,reset,submit,text]}" name="${2:some_name}" value="$3" id="${5}" />]]></text>
|
||||
<description>Input</description>
|
||||
<tag>input</tag>
|
||||
</snippet>
|
||||
<snippet id="li">
|
||||
<text><![CDATA[<li>$1</li>$0]]></text>
|
||||
<tag>li</tag>
|
||||
<description>List Element</description>
|
||||
</snippet>
|
||||
<snippet id="link">
|
||||
<text><![CDATA[<link rel="${1:stylesheet}" href="${2:/css/master.css}" type="text/css" media="${3:screen}" title="${4:no title}" charset="${5:utf-8}" />]]></text>
|
||||
<description>Link</description>
|
||||
<tag>link</tag>
|
||||
</snippet>
|
||||
<snippet id="meta">
|
||||
<text><![CDATA[<meta name="${1:name}" content="${2:content}" />]]></text>
|
||||
<description>Meta</description>
|
||||
<tag>meta</tag>
|
||||
</snippet>
|
||||
<snippet id="nbsp">
|
||||
<text><![CDATA[ ]]></text>
|
||||
<accelerator><![CDATA[<Control><Alt>space]]></accelerator>
|
||||
<description>Non-Breaking Space</description>
|
||||
</snippet>
|
||||
<snippet id="noscript">
|
||||
<text><![CDATA[<noscript>$1</noscript>$0]]></text>
|
||||
<tag>noscript</tag>
|
||||
<description>Noscript</description>
|
||||
</snippet>
|
||||
<snippet id="option">
|
||||
<text><![CDATA[<option value="${1:value}">$2</option>$0]]></text>
|
||||
<tag>option</tag>
|
||||
<description>Option</description>
|
||||
</snippet>
|
||||
<snippet id="script">
|
||||
<text><![CDATA[<script type="text/javascript" language="javascript" charset="utf-8">
|
||||
// <![CDATA[
|
||||
$0
|
||||
// ]]]]><![CDATA[>
|
||||
</script>]]></text>
|
||||
<description>Script</description>
|
||||
<tag>script</tag>
|
||||
</snippet>
|
||||
<snippet id="scriptsrc">
|
||||
<text><![CDATA[<script src="$1" type="text/javascript" language="${2:javascript}" charset="${3:utf-8}" />]]></text>
|
||||
<description>Script With External Source</description>
|
||||
<tag>scriptsrc</tag>
|
||||
</snippet>
|
||||
<snippet id="select">
|
||||
<text><![CDATA[<select name="${1:name}">
|
||||
<option value="${2:value}">$3</option>
|
||||
$4
|
||||
</select>$0
|
||||
]]></text>
|
||||
<tag>select</tag>
|
||||
<description>Select</description>
|
||||
</snippet>
|
||||
<snippet id="span">
|
||||
<text><![CDATA[<span ${1}>$2</span>$0]]></text>
|
||||
<tag>span</tag>
|
||||
<description>Span</description>
|
||||
</snippet>
|
||||
<snippet id="style">
|
||||
<text><![CDATA[<style type="text/css" media="screen">
|
||||
/* <![CDATA[ */
|
||||
$0
|
||||
/* ]]]]><![CDATA[> */
|
||||
</style>
|
||||
]]></text>
|
||||
<description>Style</description>
|
||||
<tag>style</tag>
|
||||
</snippet>
|
||||
<snippet id="table">
|
||||
<text><![CDATA[<table border="${1:0}" cellspacing="${2:0}" cellpadding="${3:0}">
|
||||
<tr><th>${4:Header}</th></tr>
|
||||
<tr><td>${5:Data}</td></tr>
|
||||
$0
|
||||
</table>]]></text>
|
||||
<description>Table</description>
|
||||
<tag>table</tag>
|
||||
</snippet>
|
||||
<snippet id="textarea">
|
||||
<text><![CDATA[<textarea name="${1:Name}" rows="${2:8}" cols="${3:40}">$0</textarea>]]></text>
|
||||
<description>Text Area</description>
|
||||
<tag>textarea</tag>
|
||||
</snippet>
|
||||
<snippet id="title">
|
||||
<text><![CDATA[<title>${1:Page Title}</title>]]></text>
|
||||
<description>Title</description>
|
||||
<tag>title</tag>
|
||||
</snippet>
|
||||
<snippet id="tr">
|
||||
<text><![CDATA[<tr><td>$1</td></tr>
|
||||
$0]]></text>
|
||||
<tag>tr</tag>
|
||||
<description>Table Row</description>
|
||||
</snippet>
|
||||
<snippet id="ul">
|
||||
<text><![CDATA[<ul>
|
||||
<li>$1</li>
|
||||
$2
|
||||
</ul>
|
||||
$0]]></text>
|
||||
<tag>ul</tag>
|
||||
<description>Unordered List</description>
|
||||
</snippet>
|
||||
</snippets>
|
49
plugins/snippets/data/idl.xml
Executable file
49
plugins/snippets/data/idl.xml
Executable file
@@ -0,0 +1,49 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<snippets language="IDL">
|
||||
<snippet id="mod">
|
||||
<text><![CDATA[module ${1:name}
|
||||
{
|
||||
$0
|
||||
};
|
||||
]]></text>
|
||||
<tag>mod</tag>
|
||||
<description>Module</description>
|
||||
</snippet>
|
||||
<snippet id="if">
|
||||
<text><![CDATA[interface ${1:name}
|
||||
{
|
||||
$0
|
||||
};
|
||||
]]></text>
|
||||
<tag>if</tag>
|
||||
<description>Interface</description>
|
||||
</snippet>
|
||||
<snippet id="str">
|
||||
<text><![CDATA[struct ${1:name}
|
||||
{
|
||||
$0
|
||||
};
|
||||
]]></text>
|
||||
<tag>str</tag>
|
||||
<description>Struct</description>
|
||||
</snippet>
|
||||
<snippet id="exc">
|
||||
<text><![CDATA[exception ${1:name}
|
||||
{
|
||||
$0
|
||||
};
|
||||
]]></text>
|
||||
<tag>exc</tag>
|
||||
<description>Exception</description>
|
||||
</snippet>
|
||||
<snippet id="seq">
|
||||
<text><![CDATA[sequence<${1:type}> ]]></text>
|
||||
<tag>seq</tag>
|
||||
<description>Sequence</description>
|
||||
</snippet>
|
||||
<snippet id="tseq">
|
||||
<text><![CDATA[typedef sequence<${1:type}> ${0:newtype};]]></text>
|
||||
<tag>tseq</tag>
|
||||
<description>Typedef Sequence</description>
|
||||
</snippet>
|
||||
</snippets>
|
91
plugins/snippets/data/java.xml
Executable file
91
plugins/snippets/data/java.xml
Executable file
@@ -0,0 +1,91 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<snippets language="Java">
|
||||
<snippet id="cd">
|
||||
<text><![CDATA[private static final ${1:String} ${2:var} = "$0";]]></text>
|
||||
<description>const def</description>
|
||||
<tag>cd</tag>
|
||||
</snippet>
|
||||
<snippet id="ife">
|
||||
<text><![CDATA[if ($1) { // $2
|
||||
|
||||
$0
|
||||
|
||||
} else { // $3
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
]]></text>
|
||||
<description>if .. else</description>
|
||||
<tag>ife</tag>
|
||||
</snippet>
|
||||
<snippet id="if">
|
||||
<text><![CDATA[if ($1) { // $2
|
||||
$0
|
||||
}]]></text>
|
||||
<description>if</description>
|
||||
<tag>if</tag>
|
||||
</snippet>
|
||||
<snippet id="log">
|
||||
<text><![CDATA[/** Logger for this class and subclasses. */
|
||||
protected final Log log = LogFactory.getLog(getClass());
|
||||
]]></text>
|
||||
<description>logger</description>
|
||||
<tag>log</tag>
|
||||
</snippet>
|
||||
<snippet id="tcf">
|
||||
<text><![CDATA[try {
|
||||
$2
|
||||
} catch (${1:Exception} e) {
|
||||
$3
|
||||
} finally {
|
||||
$4
|
||||
}
|
||||
$0]]></text>
|
||||
<description>try .. catch .. finally</description>
|
||||
<tag>tcf</tag>
|
||||
</snippet>
|
||||
<snippet id="while">
|
||||
<text><![CDATA[while ($1) { // $2
|
||||
$0
|
||||
}]]></text>
|
||||
<description>while statement</description>
|
||||
<tag>while</tag>
|
||||
</snippet>
|
||||
<snippet id="main">
|
||||
<text><![CDATA[public static void main(String[] args) {
|
||||
${1:System.exit(0)};
|
||||
}]]></text>
|
||||
<description>main</description>
|
||||
<tag>main</tag>
|
||||
</snippet>
|
||||
<snippet id="sout">
|
||||
<text><![CDATA[System.out.println("${1}");
|
||||
$0
|
||||
]]></text>
|
||||
<description>System.out.println</description>
|
||||
<tag>sout</tag>
|
||||
</snippet>
|
||||
<snippet id="try/catch">
|
||||
<text><![CDATA[try {
|
||||
$GEDIT_SELECTED_TEXT
|
||||
}
|
||||
catch (Exception e) {
|
||||
${1:e.printStackTrace();}
|
||||
}
|
||||
$0]]></text>
|
||||
<accelerator><![CDATA[<Shift><Alt>t]]></accelerator>
|
||||
<description>Wrap Selection in Try/Catch</description>
|
||||
</snippet>
|
||||
<snippet id="tc">
|
||||
<text><![CDATA[try {
|
||||
$2
|
||||
} catch (${1:Exception} e) {
|
||||
$3
|
||||
}
|
||||
$0]]></text>
|
||||
<tag>tc</tag>
|
||||
<description>try .. catch</description>
|
||||
</snippet>
|
||||
</snippets>
|
11
plugins/snippets/data/javascript.xml
Executable file
11
plugins/snippets/data/javascript.xml
Executable file
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<snippets language="JavaScript">
|
||||
<snippet id="fun">
|
||||
<text><![CDATA[function ${1:function_name} (${2:first_argument})
|
||||
{
|
||||
${0:# body...}
|
||||
}]]></text>
|
||||
<description>function</description>
|
||||
<tag>fun</tag>
|
||||
</snippet>
|
||||
</snippets>
|
9
plugins/snippets/data/lang/Makefile.am
Executable file
9
plugins/snippets/data/lang/Makefile.am
Executable file
@@ -0,0 +1,9 @@
|
||||
# Python snippets plugin
|
||||
lang_DATA = \
|
||||
snippets.lang
|
||||
|
||||
langdir = $(GEDIT_PLUGINS_DATA_DIR)/snippets/lang
|
||||
|
||||
EXTRA_DIST = $(lang_DATA)
|
||||
|
||||
-include $(top_srcdir)/git.mk
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user