summaryrefslogtreecommitdiffstats
path: root/plugins/sort
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/sort')
-rw-r--r--plugins/sort/gedit-sort-plugin.c418
-rw-r--r--plugins/sort/gedit-sort-plugin.h59
-rw-r--r--plugins/sort/meson.build34
-rw-r--r--plugins/sort/resources/gedit-sort.gresource.xml6
-rw-r--r--plugins/sort/resources/meson.build8
-rw-r--r--plugins/sort/resources/ui/gedit-sort-plugin.ui160
-rw-r--r--plugins/sort/sort.plugin.desktop.in11
7 files changed, 696 insertions, 0 deletions
diff --git a/plugins/sort/gedit-sort-plugin.c b/plugins/sort/gedit-sort-plugin.c
new file mode 100644
index 0000000..41774fc
--- /dev/null
+++ b/plugins/sort/gedit-sort-plugin.c
@@ -0,0 +1,418 @@
+/*
+ * gedit-sort-plugin.c
+ *
+ * Original author: Carlo Borreo <borreo@softhome.net>
+ * Ported to Gedit2 by Lee Mallabone <gnome@fonicmonkey.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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include "gedit-sort-plugin.h"
+
+#include <string.h>
+#include <glib/gi18n.h>
+
+#include <gedit/gedit-debug.h>
+#include <gedit/gedit-utils.h>
+#include <gedit/gedit-app.h>
+#include <gedit/gedit-window.h>
+#include <gedit/gedit-app-activatable.h>
+#include <gedit/gedit-window-activatable.h>
+
+static void gedit_app_activatable_iface_init (GeditAppActivatableInterface *iface);
+static void gedit_window_activatable_iface_init (GeditWindowActivatableInterface *iface);
+
+struct _GeditSortPluginPrivate
+{
+ GeditWindow *window;
+
+ GSimpleAction *action;
+ GtkWidget *dialog;
+ GtkWidget *col_num_spinbutton;
+ GtkWidget *reverse_order_checkbutton;
+ GtkWidget *case_checkbutton;
+ GtkWidget *remove_dups_checkbutton;
+
+ GeditApp *app;
+ GeditMenuExtension *menu_ext;
+
+ GtkTextIter start, end; /* selection */
+};
+
+enum
+{
+ PROP_0,
+ PROP_WINDOW,
+ PROP_APP
+};
+
+G_DEFINE_DYNAMIC_TYPE_EXTENDED (GeditSortPlugin,
+ gedit_sort_plugin,
+ PEAS_TYPE_EXTENSION_BASE,
+ 0,
+ G_IMPLEMENT_INTERFACE_DYNAMIC (GEDIT_TYPE_APP_ACTIVATABLE,
+ gedit_app_activatable_iface_init)
+ G_IMPLEMENT_INTERFACE_DYNAMIC (GEDIT_TYPE_WINDOW_ACTIVATABLE,
+ gedit_window_activatable_iface_init)
+ G_ADD_PRIVATE_DYNAMIC (GeditSortPlugin))
+
+static void
+do_sort (GeditSortPlugin *plugin)
+{
+ GeditSortPluginPrivate *priv;
+ GeditDocument *doc;
+ GtkSourceSortFlags sort_flags = 0;
+ gint starting_column;
+
+ gedit_debug (DEBUG_PLUGINS);
+
+ priv = plugin->priv;
+
+ doc = gedit_window_get_active_document (priv->window);
+ g_return_if_fail (doc != NULL);
+
+ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->case_checkbutton)))
+ {
+ sort_flags |= GTK_SOURCE_SORT_FLAGS_CASE_SENSITIVE;
+ }
+
+ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->reverse_order_checkbutton)))
+ {
+ sort_flags |= GTK_SOURCE_SORT_FLAGS_REVERSE_ORDER;
+ }
+
+ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->remove_dups_checkbutton)))
+ {
+ sort_flags |= GTK_SOURCE_SORT_FLAGS_REMOVE_DUPLICATES;
+ }
+
+ starting_column = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (priv->col_num_spinbutton)) - 1;
+
+ gtk_source_buffer_sort_lines (GTK_SOURCE_BUFFER (doc),
+ &priv->start,
+ &priv->end,
+ sort_flags,
+ starting_column);
+
+ gedit_debug_message (DEBUG_PLUGINS, "Done.");
+}
+
+static void
+sort_dialog_response_handler (GtkDialog *dlg,
+ gint response,
+ GeditSortPlugin *plugin)
+{
+ gedit_debug (DEBUG_PLUGINS);
+
+ if (response == GTK_RESPONSE_OK)
+ {
+ do_sort (plugin);
+ }
+
+ gtk_widget_destroy (GTK_WIDGET (dlg));
+}
+
+/* NOTE: we store the current selection in the dialog since focusing
+ * the text field (like the combo box) looses the documnent selection.
+ * Storing the selection ONLY works because the dialog is modal */
+static void
+get_current_selection (GeditSortPlugin *plugin)
+{
+ GeditSortPluginPrivate *priv;
+ GeditDocument *doc;
+
+ gedit_debug (DEBUG_PLUGINS);
+
+ priv = plugin->priv;
+
+ doc = gedit_window_get_active_document (priv->window);
+
+ if (!gtk_text_buffer_get_selection_bounds (GTK_TEXT_BUFFER (doc),
+ &priv->start,
+ &priv->end))
+ {
+ /* No selection, get the whole document. */
+ gtk_text_buffer_get_bounds (GTK_TEXT_BUFFER (doc),
+ &priv->start,
+ &priv->end);
+ }
+}
+
+static void
+create_sort_dialog (GeditSortPlugin *plugin)
+{
+ GeditSortPluginPrivate *priv;
+ GtkBuilder *builder;
+
+ gedit_debug (DEBUG_PLUGINS);
+
+ priv = plugin->priv;
+
+ builder = gtk_builder_new ();
+ gtk_builder_add_from_resource (builder, "/org/gnome/gedit/plugins/sort/ui/gedit-sort-plugin.ui", NULL);
+ priv->dialog = GTK_WIDGET (gtk_builder_get_object (builder, "sort_dialog"));
+ priv->reverse_order_checkbutton = GTK_WIDGET (gtk_builder_get_object (builder, "reverse_order_checkbutton"));
+ priv->col_num_spinbutton = GTK_WIDGET (gtk_builder_get_object (builder, "col_num_spinbutton"));
+ priv->case_checkbutton = GTK_WIDGET (gtk_builder_get_object (builder, "case_checkbutton"));
+ priv->remove_dups_checkbutton = GTK_WIDGET (gtk_builder_get_object (builder, "remove_dups_checkbutton"));
+ g_object_unref (builder);
+
+ gtk_dialog_set_default_response (GTK_DIALOG (priv->dialog),
+ GTK_RESPONSE_OK);
+
+ g_signal_connect (priv->dialog,
+ "destroy",
+ G_CALLBACK (gtk_widget_destroyed),
+ &priv->dialog);
+
+ g_signal_connect (priv->dialog,
+ "response",
+ G_CALLBACK (sort_dialog_response_handler),
+ plugin);
+
+ get_current_selection (plugin);
+}
+
+static void
+sort_cb (GAction *action,
+ GVariant *parameter,
+ GeditSortPlugin *plugin)
+{
+ GeditSortPluginPrivate *priv;
+ GtkWindowGroup *wg;
+
+ gedit_debug (DEBUG_PLUGINS);
+
+ priv = plugin->priv;
+
+ create_sort_dialog (plugin);
+
+ wg = gedit_window_get_group (priv->window);
+ gtk_window_group_add_window (wg,
+ GTK_WINDOW (priv->dialog));
+
+ gtk_window_set_transient_for (GTK_WINDOW (priv->dialog),
+ GTK_WINDOW (priv->window));
+
+ gtk_window_set_modal (GTK_WINDOW (priv->dialog),
+ TRUE);
+
+ gtk_widget_show (GTK_WIDGET (priv->dialog));
+}
+
+static void
+update_ui (GeditSortPlugin *plugin)
+{
+ GeditView *view;
+
+ gedit_debug (DEBUG_PLUGINS);
+
+ view = gedit_window_get_active_view (plugin->priv->window);
+
+ g_simple_action_set_enabled (plugin->priv->action,
+ (view != NULL) &&
+ gtk_text_view_get_editable (GTK_TEXT_VIEW (view)));
+}
+
+static void
+gedit_sort_plugin_app_activate (GeditAppActivatable *activatable)
+{
+ GeditSortPluginPrivate *priv;
+ GMenuItem *item;
+
+ gedit_debug (DEBUG_PLUGINS);
+
+ priv = GEDIT_SORT_PLUGIN (activatable)->priv;
+
+ priv->menu_ext = gedit_app_activatable_extend_menu (activatable, "tools-section");
+ item = g_menu_item_new (_("S_ort…"), "win.sort");
+ gedit_menu_extension_append_menu_item (priv->menu_ext, item);
+ g_object_unref (item);
+}
+
+static void
+gedit_sort_plugin_app_deactivate (GeditAppActivatable *activatable)
+{
+ GeditSortPluginPrivate *priv;
+
+ gedit_debug (DEBUG_PLUGINS);
+
+ priv = GEDIT_SORT_PLUGIN (activatable)->priv;
+
+ g_clear_object (&priv->menu_ext);
+}
+
+static void
+gedit_sort_plugin_window_activate (GeditWindowActivatable *activatable)
+{
+ GeditSortPluginPrivate *priv;
+
+ gedit_debug (DEBUG_PLUGINS);
+
+ priv = GEDIT_SORT_PLUGIN (activatable)->priv;
+
+ priv->action = g_simple_action_new ("sort", NULL);
+ g_signal_connect (priv->action, "activate",
+ G_CALLBACK (sort_cb), activatable);
+ g_action_map_add_action (G_ACTION_MAP (priv->window),
+ G_ACTION (priv->action));
+
+ update_ui (GEDIT_SORT_PLUGIN (activatable));
+}
+
+static void
+gedit_sort_plugin_window_deactivate (GeditWindowActivatable *activatable)
+{
+ GeditSortPluginPrivate *priv;
+
+ gedit_debug (DEBUG_PLUGINS);
+
+ priv = GEDIT_SORT_PLUGIN (activatable)->priv;
+ g_action_map_remove_action (G_ACTION_MAP (priv->window), "sort");
+}
+
+static void
+gedit_sort_plugin_window_update_state (GeditWindowActivatable *activatable)
+{
+ gedit_debug (DEBUG_PLUGINS);
+
+ update_ui (GEDIT_SORT_PLUGIN (activatable));
+}
+
+static void
+gedit_sort_plugin_init (GeditSortPlugin *plugin)
+{
+ gedit_debug_message (DEBUG_PLUGINS, "GeditSortPlugin initializing");
+
+ plugin->priv = gedit_sort_plugin_get_instance_private (plugin);
+}
+
+static void
+gedit_sort_plugin_dispose (GObject *object)
+{
+ GeditSortPlugin *plugin = GEDIT_SORT_PLUGIN (object);
+
+ gedit_debug_message (DEBUG_PLUGINS, "GeditSortPlugin disposing");
+
+ g_clear_object (&plugin->priv->action);
+ g_clear_object (&plugin->priv->window);
+ g_clear_object (&plugin->priv->menu_ext);
+ g_clear_object (&plugin->priv->app);
+
+ G_OBJECT_CLASS (gedit_sort_plugin_parent_class)->dispose (object);
+}
+
+
+static void
+gedit_sort_plugin_finalize (GObject *object)
+{
+ gedit_debug_message (DEBUG_PLUGINS, "GeditSortPlugin finalizing");
+
+ G_OBJECT_CLASS (gedit_sort_plugin_parent_class)->finalize (object);
+}
+
+static void
+gedit_sort_plugin_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GeditSortPlugin *plugin = GEDIT_SORT_PLUGIN (object);
+
+ switch (prop_id)
+ {
+ case PROP_WINDOW:
+ plugin->priv->window = GEDIT_WINDOW (g_value_dup_object (value));
+ break;
+ case PROP_APP:
+ plugin->priv->app = GEDIT_APP (g_value_dup_object (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gedit_sort_plugin_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GeditSortPlugin *plugin = GEDIT_SORT_PLUGIN (object);
+
+ switch (prop_id)
+ {
+ case PROP_WINDOW:
+ g_value_set_object (value, plugin->priv->window);
+ break;
+ case PROP_APP:
+ g_value_set_object (value, plugin->priv->app);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gedit_sort_plugin_class_init (GeditSortPluginClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->dispose = gedit_sort_plugin_dispose;
+ object_class->finalize = gedit_sort_plugin_finalize;
+ object_class->set_property = gedit_sort_plugin_set_property;
+ object_class->get_property = gedit_sort_plugin_get_property;
+
+ g_object_class_override_property (object_class, PROP_WINDOW, "window");
+ g_object_class_override_property (object_class, PROP_APP, "app");
+}
+
+static void
+gedit_sort_plugin_class_finalize (GeditSortPluginClass *klass)
+{
+}
+
+static void
+gedit_app_activatable_iface_init (GeditAppActivatableInterface *iface)
+{
+ iface->activate = gedit_sort_plugin_app_activate;
+ iface->deactivate = gedit_sort_plugin_app_deactivate;
+}
+
+static void
+gedit_window_activatable_iface_init (GeditWindowActivatableInterface *iface)
+{
+ iface->activate = gedit_sort_plugin_window_activate;
+ iface->deactivate = gedit_sort_plugin_window_deactivate;
+ iface->update_state = gedit_sort_plugin_window_update_state;
+}
+
+G_MODULE_EXPORT void
+peas_register_types (PeasObjectModule *module)
+{
+ gedit_sort_plugin_register_type (G_TYPE_MODULE (module));
+
+ peas_object_module_register_extension_type (module,
+ GEDIT_TYPE_APP_ACTIVATABLE,
+ GEDIT_TYPE_SORT_PLUGIN);
+ peas_object_module_register_extension_type (module,
+ GEDIT_TYPE_WINDOW_ACTIVATABLE,
+ GEDIT_TYPE_SORT_PLUGIN);
+}
+
+/* ex:set ts=8 noet: */
diff --git a/plugins/sort/gedit-sort-plugin.h b/plugins/sort/gedit-sort-plugin.h
new file mode 100644
index 0000000..e8739e0
--- /dev/null
+++ b/plugins/sort/gedit-sort-plugin.h
@@ -0,0 +1,59 @@
+/*
+ * gedit-sort-plugin.h
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GEDIT_SORT_PLUGIN_H
+#define GEDIT_SORT_PLUGIN_H
+
+#include <glib.h>
+#include <glib-object.h>
+#include <libpeas/peas-extension-base.h>
+#include <libpeas/peas-object-module.h>
+
+G_BEGIN_DECLS
+
+#define GEDIT_TYPE_SORT_PLUGIN (gedit_sort_plugin_get_type ())
+#define GEDIT_SORT_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GEDIT_TYPE_SORT_PLUGIN, GeditSortPlugin))
+#define GEDIT_SORT_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GEDIT_TYPE_SORT_PLUGIN, GeditSortPluginClass))
+#define GEDIT_IS_SORT_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GEDIT_TYPE_SORT_PLUGIN))
+#define GEDIT_IS_SORT_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GEDIT_TYPE_SORT_PLUGIN))
+#define GEDIT_SORT_PLUGIN_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GEDIT_TYPE_SORT_PLUGIN, GeditSortPluginClass))
+
+typedef struct _GeditSortPlugin GeditSortPlugin;
+typedef struct _GeditSortPluginPrivate GeditSortPluginPrivate;
+typedef struct _GeditSortPluginClass GeditSortPluginClass;
+
+struct _GeditSortPlugin
+{
+ PeasExtensionBase parent;
+
+ /*< private >*/
+ GeditSortPluginPrivate *priv;
+};
+
+struct _GeditSortPluginClass
+{
+ PeasExtensionBaseClass parent_class;
+};
+
+GType gedit_sort_plugin_get_type (void) G_GNUC_CONST;
+
+G_MODULE_EXPORT void peas_register_types (PeasObjectModule *module);
+
+G_END_DECLS
+
+#endif /* GEDIT_SORT_PLUGIN_H */
+/* ex:set ts=8 noet: */
diff --git a/plugins/sort/meson.build b/plugins/sort/meson.build
new file mode 100644
index 0000000..7f91440
--- /dev/null
+++ b/plugins/sort/meson.build
@@ -0,0 +1,34 @@
+libsort_sources = files(
+ 'gedit-sort-plugin.c',
+)
+
+libsort_deps = [
+ libgedit_dep,
+]
+
+subdir('resources')
+
+libsort_sha = shared_module(
+ 'sort',
+ sources: libsort_sources,
+ include_directories: root_include_dir,
+ dependencies: libsort_deps,
+ install: true,
+ install_dir: join_paths(
+ pkglibdir,
+ 'plugins',
+ ),
+ name_suffix: module_suffix,
+)
+
+custom_target(
+ 'sort.plugin',
+ input: 'sort.plugin.desktop.in',
+ output: 'sort.plugin',
+ command: msgfmt_plugin_cmd,
+ install: true,
+ install_dir: join_paths(
+ pkglibdir,
+ 'plugins',
+ )
+)
diff --git a/plugins/sort/resources/gedit-sort.gresource.xml b/plugins/sort/resources/gedit-sort.gresource.xml
new file mode 100644
index 0000000..3855c8f
--- /dev/null
+++ b/plugins/sort/resources/gedit-sort.gresource.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<gresources>
+ <gresource prefix="/org/gnome/gedit/plugins/sort">
+ <file preprocess="xml-stripblanks">ui/gedit-sort-plugin.ui</file>
+ </gresource>
+</gresources>
diff --git a/plugins/sort/resources/meson.build b/plugins/sort/resources/meson.build
new file mode 100644
index 0000000..7178761
--- /dev/null
+++ b/plugins/sort/resources/meson.build
@@ -0,0 +1,8 @@
+libsort_res = gnome.compile_resources(
+ 'gedit-sort-resources',
+ 'gedit-sort.gresource.xml',
+)
+
+libsort_sources += [
+ libsort_res.get(0),
+]
diff --git a/plugins/sort/resources/ui/gedit-sort-plugin.ui b/plugins/sort/resources/ui/gedit-sort-plugin.ui
new file mode 100644
index 0000000..95a0e17
--- /dev/null
+++ b/plugins/sort/resources/ui/gedit-sort-plugin.ui
@@ -0,0 +1,160 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <!-- interface-requires gtk+ 2.12 -->
+ <object class="GtkAdjustment" id="adjustment1">
+ <property name="lower">1</property>
+ <property name="upper">100</property>
+ <property name="value">1</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkDialog" id="sort_dialog">
+ <property name="can_focus">False</property>
+ <property name="title" translatable="yes">Sort</property>
+ <property name="resizable">False</property>
+ <property name="destroy_with_parent">True</property>
+ <property name="type_hint">dialog</property>
+ <property name="use-header-bar">1</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkBox" id="vbox1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="border_width">10</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">18</property>
+ <child>
+ <object class="GtkBox" id="vbox5">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkCheckButton" id="reverse_order_checkbutton">
+ <property name="label" translatable="yes">_Reverse order</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_action_appearance">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="remove_dups_checkbutton">
+ <property name="label" translatable="yes">R_emove duplicates</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_action_appearance">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="case_checkbutton">
+ <property name="label" translatable="yes">C_ase sensitive</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_action_appearance">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="hbox13">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="label18">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">S_tart at column:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">col_num_spinbutton</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="col_num_spinbutton">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="adjustment">adjustment1</property>
+ <property name="climb_rate">1</property>
+ <property name="numeric">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="action">
+ <object class="GtkButton" id="cancel">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Cancel</property>
+ <property name="use_underline">True</property>
+ </object>
+ </child>
+ <child type="action">
+ <object class="GtkButton" id="sort">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Sort</property>
+ <property name="can-default">True</property>
+ <property name="use_underline">True</property>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-6">cancel</action-widget>
+ <action-widget response="-5">sort</action-widget>
+ </action-widgets>
+ </object>
+</interface>
diff --git a/plugins/sort/sort.plugin.desktop.in b/plugins/sort/sort.plugin.desktop.in
new file mode 100644
index 0000000..f2e2c78
--- /dev/null
+++ b/plugins/sort/sort.plugin.desktop.in
@@ -0,0 +1,11 @@
+[Plugin]
+Module=sort
+IAge=3
+Name=Sort
+Description=Sorts a document or selected text.
+# TRANSLATORS: Do NOT translate or transliterate this text!
+# This is an icon file name.
+Icon=view-sort-ascending
+Authors=Carlo Borreo <borreo@softhome.net>;Lee Mallabone <gnome@fonicmonkey.net>;Paolo Maggi <paolo.maggi@polito.it>;Jorge Alberto Torres H. <jorge@deadoak.com>
+Copyright=Copyright © 2001 Carlo Borreo;Copyright © 2002-2003 Lee Mallabone, Paolo Maggi;Copyright © 2004-2005 Paolo Maggi
+Website=http://www.gedit.org