[Xfce4-commits] <mousepad:master> * mousepad/mousepad-{document, window, statusbar}: You can now click the OVR text in the statusbar to toggle the overwrite mode. * mousepad/mousepad-{document, window, undo}: Initial version of an undo manager. This is not finished yet, but it's a start. * mousepad/Makefile.am, mousepad/mousepad-csource.pl: Remove my perl script because it has some problems. Use exo-csource instead. * Remove some empty object functions.
Nick Schermer
noreply at xfce.org
Sat May 5 21:30:18 CEST 2012
Updating branch refs/heads/master
to ec1234c58d36457576ea554ac2fd5885da962fd7 (commit)
from fe666120450ea8df11059d60c0bcdb806d3d5426 (commit)
commit ec1234c58d36457576ea554ac2fd5885da962fd7
Author: Nick Schermer <nick at xfce.org>
Date: Wed Apr 11 08:22:46 2007 +0000
* mousepad/mousepad-{document,window,statusbar}: You can now click the OVR
text in the statusbar to toggle the overwrite mode.
* mousepad/mousepad-{document,window,undo}: Initial version of an undo
manager. This is not finished yet, but it's a start.
* mousepad/Makefile.am, mousepad/mousepad-csource.pl: Remove my perl script
because it has some problems. Use exo-csource instead.
* Remove some empty object functions.
(Old svn revision: 25514)
ChangeLog | 10 +
configure.in.in | 11 +
mousepad/Makefile.am | 17 +-
mousepad/mousepad-csource.pl | 90 ------
mousepad/mousepad-document.c | 138 +++++++++-
mousepad/mousepad-document.h | 11 +
mousepad/mousepad-private.h | 1 +
mousepad/mousepad-search-bar.c | 9 +-
mousepad/mousepad-statusbar.c | 72 ++++-
mousepad/mousepad-undo.c | 592 +++++++++++++++++++++++++++++++++++++++
mousepad/mousepad-undo.h | 57 ++++
mousepad/mousepad-view.c | 24 +--
mousepad/mousepad-window-ui.xml | 2 +
mousepad/mousepad-window.c | 92 ++++++-
14 files changed, 984 insertions(+), 142 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index f4f4ef9..2e8dbf5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2007-04-xx Nick Schermer <nick at xfce.org>
+ * mousepad/mousepad-{document,window,statusbar}: You can now click the OVR
+ text in the statusbar to toggle the overwrite mode.
+ * mousepad/mousepad-{document,window,undo}: Initial version of an undo
+ manager. This is not finished yet, but it's a start.
+ * mousepad/Makefile.am, mousepad/mousepad-csource.pl: Remove my perl script
+ because it has some problems. Use exo-csource instead.
+ * Remove some empty object functions.
+
+
2007-04-06 Nick Schermer <nick at xfce.org>
* mousepad/mousepad-document.c: Fix segfault from previous commit.
* mousepad/mousepad-document.c: Fix bug in searching backwards, we have to
diff --git a/configure.in.in b/configure.in.in
index 272e528..4ae2f42 100644
--- a/configure.in.in
+++ b/configure.in.in
@@ -110,6 +110,12 @@ XDT_CHECK_OPTIONAL_PACKAGE([LIBSTARTUP_NOTIFICATION],
[0.4], [startup-notification],
[startup notification library])
+dnl *******************************************************
+dnl *** Optional support for unix print support in GTK+ ***
+dnl *******************************************************
+XDT_CHECK_OPTIONAL_PACKAGE([GTK_UNIX_PRINT], [gtk+-unix-print-2.0],
+ [2.10.0], [gtk_unix_print], [GTK+ Unix print support])
+
dnl *************************
dnl *** Check for gtk-doc ***
dnl *************************
@@ -234,4 +240,9 @@ echo "* Startup Notification: yes"
else
echo "* Startup Notification: no"
fi
+if test x"$GTK_UNIX_PRINT_FOUND" = x"yes"; then
+echo "* GTK+ Unix Print Support: yes"
+else
+echo "* GTK+ Unix Print Support: no"
+fi
echo
diff --git a/mousepad/Makefile.am b/mousepad/Makefile.am
index 429aa9f..9ec9015 100644
--- a/mousepad/Makefile.am
+++ b/mousepad/Makefile.am
@@ -46,13 +46,15 @@ mousepad_SOURCES = \
mousepad-statusbar.h \
mousepad-view.c \
mousepad-view.h \
+ mousepad-undo.c \
+ mousepad-undo.h \
mousepad-window.c \
mousepad-window.h \
mousepad-window-ui.h
mousepad_CFLAGS = \
$(GTK_CFLAGS) \
- $(LIBXFCE4UTIL_CFLAGS) \
+ $(LIBXFCE4UTIL_CFLAGS) \
$(GMODULE_CFLAGS) \
$(GTHREAD_CFLAGS) \
$(PLATFORM_CFLAGS)
@@ -63,7 +65,7 @@ mousepad_LDFLAGS = \
mousepad_LDADD = \
$(GTK_LIBS) \
- $(LIBXFCE4UTIL_LIBS) \
+ $(LIBXFCE4UTIL_LIBS) \
$(GMODULE_LIBS) \
$(GTHREAD_LIBS)
@@ -83,6 +85,14 @@ mousepad_LDADD += \
$(DBUS_LIBS)
endif
+if HAVE_GTK_UNIX_PRINT
+mousepad_CFLAGS += \
+ $(GTK_UNIX_PRINT_CFLAGS)
+
+mousepad_LDADD += \
+ $(GTK_UNIX_PRINT_LIBS)
+endif
+
if MAINTAINER_MODE
CLEANFILES = \
xgen-mmc \
@@ -106,7 +116,7 @@ mousepad-dbus-infos.h: $(srcdir)/mousepad-dbus-infos.xml Makefile
endif
mousepad-window-ui.h: Makefile $(srcdir)/mousepad-window-ui.xml
- $(PERL) $(srcdir)/mousepad-csource.pl mousepad_window_ui < $(srcdir)/mousepad-window-ui.xml > mousepad-window-ui.h
+ exo-csource --static --name=mousepad_window_ui $(srcdir)/mousepad-window-ui.xml > mousepad-window-ui.h
mousepad-enum-types.h: stamp-mousepad-enum-types.h
@true
@@ -150,7 +160,6 @@ mousepad-marshal.c: mousepad-marshal.list Makefile
endif
EXTRA_DIST = \
- mousepad-csource.pl \
mousepad-dbus-infos.xml \
mousepad-marshal.list \
mousepad-window-ui.xml
diff --git a/mousepad/mousepad-csource.pl b/mousepad/mousepad-csource.pl
deleted file mode 100755
index 71bd2f9..0000000
--- a/mousepad/mousepad-csource.pl
+++ /dev/null
@@ -1,90 +0,0 @@
-#!/usr/bin/env perl -w
-#
-# $Id$
-#
-# Copyright (c) 2007 Nick Schermer <nick at xfce.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 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
-#
-
-if ($#ARGV < 0)
- {
- print ("No variable name defined. Exiting...");
- exit;
- }
-
-# get the variable name
-my $varname = $ARGV[0];
-shift;
-
-# init
-my $max_column = 70;
-my $result;
-my $line ;
-
-# walk though the lines, strip when and append the result
-while (<>)
- {
- # ignore empty lines
- next if /^\s*$/;
-
- # skip comments
- if ($_ =~ '<!--')
- {
- $in_comment = 1;
- }
-
- if ($in_comment)
- {
- if ($_ =~ '-->')
- {
- $in_comment = 0;
- }
- next;
- }
-
- $line = $_;
-
- # strip the code before and after the xml block
- $line =~ s/.*</</g;
- $line =~ s/>.*\n/>/g;
-
- # append the striped line to the result
- $result .= $line;
- }
-
-# start of the file
-print "static const unsigned int ". $varname ."_length = ". length ($result) .";\n\n".
- "#ifdef __SUNPRO_C\n".
- "#pragma align 4 (". $varname .")\n".
- "#endif\n".
- "#ifdef __GNUC__\n".
- "static const char ". $varname ."[] __attribute__ ((__aligned__ (4))) =\n".
- "#else\n".
- "static const char ". $varname ."[] =\n".
- "#endif\n".
- "{\n";
-
-# escape the comments
-$result =~ s/\"/\\"/g;
-
-# print the content of the xml file
-for ($i = 0; $i < length ($result); $i = $i + $max_column)
- {
- print " \"" . substr ($result, $i, $max_column) . "\"\n";
- }
-
-# close
-print "};\n\n";
diff --git a/mousepad/mousepad-document.c b/mousepad/mousepad-document.c
index 5802f1c..035db81 100644
--- a/mousepad/mousepad-document.c
+++ b/mousepad/mousepad-document.c
@@ -40,17 +40,20 @@
#include <mousepad/mousepad-file.h>
#include <mousepad/mousepad-marshal.h>
#include <mousepad/mousepad-view.h>
+#include <mousepad/mousepad-undo.h>
#include <mousepad/mousepad-window.h>
-#define DEFAULT_SEARCH_FLAGS (GTK_TEXT_SEARCH_VISIBLE_ONLY | GTK_TEXT_SEARCH_TEXT_ONLY)
-
-
-
static void mousepad_document_class_init (MousepadDocumentClass *klass);
static void mousepad_document_init (MousepadDocument *document);
static void mousepad_document_finalize (GObject *object);
+static void mousepad_document_emit_can_undo (MousepadUndo *undo,
+ gboolean can_undo,
+ MousepadDocument *document);
+static void mousepad_document_emit_can_redo (MousepadUndo *undo,
+ gboolean can_redo,
+ MousepadDocument *document);
static void mousepad_document_modified_changed (GtkTextBuffer *buffer,
MousepadDocument *document);
static void mousepad_document_notify_has_selection (GtkTextBuffer *buffer,
@@ -74,7 +77,6 @@ static void mousepad_document_tab_button_clicked (GtkWidget
MousepadDocument *document);
-
enum
{
CLOSE_TAB,
@@ -82,6 +84,8 @@ enum
MODIFIED_CHANGED,
CURSOR_CHANGED,
OVERWRITE_CHANGED,
+ CAN_UNDO,
+ CAN_REDO,
LAST_SIGNAL,
};
@@ -98,6 +102,9 @@ struct _MousepadDocument
GtkTextView *textview;
GtkTextBuffer *buffer;
+ /* the undo manager */
+ MousepadUndo *undo;
+
/* the highlight tag */
GtkTextTag *tag;
@@ -205,6 +212,22 @@ mousepad_document_class_init (MousepadDocumentClass *klass)
0, NULL, NULL,
g_cclosure_marshal_VOID__BOOLEAN,
G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
+
+ document_signals[CAN_UNDO] =
+ g_signal_new (I_("can-undo"),
+ G_TYPE_FROM_CLASS (gobject_class),
+ G_SIGNAL_RUN_LAST,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__BOOLEAN,
+ G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
+
+ document_signals[CAN_REDO] =
+ g_signal_new (I_("can-redo"),
+ G_TYPE_FROM_CLASS (gobject_class),
+ G_SIGNAL_RUN_LAST,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__BOOLEAN,
+ G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
}
@@ -226,6 +249,15 @@ mousepad_document_init (MousepadDocument *document)
/* create a textbuffer */
document->buffer = gtk_text_buffer_new (NULL);
+ /* initialize the undo manager */
+ document->undo = mousepad_undo_new (document->buffer);
+
+ /* connect signals to the undo manager */
+ g_signal_connect (G_OBJECT (document->undo), "can-undo",
+ G_CALLBACK (mousepad_document_emit_can_undo), document);
+ g_signal_connect (G_OBJECT (document->undo), "can-redo",
+ G_CALLBACK (mousepad_document_emit_can_redo), document);
+
/* create the highlight tag */
document->tag = gtk_text_buffer_create_tag (document->buffer, NULL, "background", "#ffff78", NULL);
@@ -243,6 +275,8 @@ mousepad_document_init (MousepadDocument *document)
G_CALLBACK (mousepad_document_notify_cursor_position), document);
g_signal_connect (G_OBJECT (document->textview), "notify::overwrite",
G_CALLBACK (mousepad_document_toggle_overwrite), document);
+ g_signal_connect (G_OBJECT (document->textview), "populate-popup",
+ G_CALLBACK (mousepad_undo_populate_popup), document->undo);
}
@@ -256,6 +290,9 @@ mousepad_document_finalize (GObject *object)
g_free (document->filename);
g_free (document->display_name);
+ /* release the undo manager */
+ g_object_unref (G_OBJECT (document->undo));
+
/* release our reference from the buffer */
g_object_unref (G_OBJECT (document->buffer));
@@ -265,6 +302,32 @@ mousepad_document_finalize (GObject *object)
static void
+mousepad_document_emit_can_undo (MousepadUndo *undo,
+ gboolean can_undo,
+ MousepadDocument *document)
+{
+ _mousepad_return_if_fail (MOUSEPAD_IS_DOCUMENT (document));
+
+ /* emit the signal */
+ g_signal_emit (G_OBJECT (document), document_signals[CAN_UNDO], 0, can_undo);
+}
+
+
+
+static void
+mousepad_document_emit_can_redo (MousepadUndo *undo,
+ gboolean can_redo,
+ MousepadDocument *document)
+{
+ _mousepad_return_if_fail (MOUSEPAD_IS_DOCUMENT (document));
+
+ /* emit the signal */
+ g_signal_emit (G_OBJECT (document), document_signals[CAN_REDO], 0, can_redo);
+}
+
+
+
+static void
mousepad_document_modified_changed (GtkTextBuffer *buffer,
MousepadDocument *document)
{
@@ -507,6 +570,17 @@ mousepad_document_set_line_numbers (MousepadDocument *document,
void
+mousepad_document_set_overwrite (MousepadDocument *document,
+ gboolean overwrite)
+{
+ _mousepad_return_if_fail (MOUSEPAD_IS_DOCUMENT (document));
+
+ gtk_text_view_set_overwrite (document->textview, overwrite);
+}
+
+
+
+void
mousepad_document_set_word_wrap (MousepadDocument *document,
gboolean word_wrap)
{
@@ -557,6 +631,9 @@ mousepad_document_open_file (MousepadDocument *document,
/* we're going to add the file content */
gtk_text_buffer_begin_user_action (document->buffer);
+ /* lock the undo manager */
+ mousepad_undo_lock (document->undo);
+
/* insert the file content */
if (mousepad_file_read_to_buffer (filename,
document->buffer,
@@ -583,6 +660,9 @@ mousepad_document_open_file (MousepadDocument *document,
succeed = TRUE;
}
+ /* unlock the undo manager */
+ mousepad_undo_unlock (document->undo);
+
/* and we're done */
gtk_text_buffer_end_user_action (document->buffer);
@@ -973,6 +1053,26 @@ mousepad_document_get_externally_modified (MousepadDocument *document)
+gboolean
+mousepad_document_get_can_undo (MousepadDocument *document)
+{
+ _mousepad_return_val_if_fail (MOUSEPAD_IS_DOCUMENT (document), FALSE);
+
+ return mousepad_undo_can_undo (document->undo);
+}
+
+
+
+gboolean
+mousepad_document_get_can_redo (MousepadDocument *document)
+{
+ _mousepad_return_val_if_fail (MOUSEPAD_IS_DOCUMENT (document), FALSE);
+
+ return mousepad_undo_can_redo (document->undo);
+}
+
+
+
const gchar *
mousepad_document_get_filename (MousepadDocument *document)
{
@@ -1145,3 +1245,31 @@ mousepad_document_get_auto_indent (MousepadDocument *document)
return document->auto_indent;
}
+
+
+
+void
+mousepad_document_undo (MousepadDocument *document)
+{
+ _mousepad_return_if_fail (MOUSEPAD_IS_DOCUMENT (document));
+
+ /* undo */
+ mousepad_undo_do_undo (document->undo);
+
+ /* scroll to visible area */
+ mousepad_document_scroll_to_visible_area (document);
+}
+
+
+
+void
+mousepad_document_redo (MousepadDocument *document)
+{
+ _mousepad_return_if_fail (MOUSEPAD_IS_DOCUMENT (document));
+
+ /* redo */
+ mousepad_undo_do_redo (document->undo);
+
+ /* scroll to visible area */
+ mousepad_document_scroll_to_visible_area (document);
+}
diff --git a/mousepad/mousepad-document.h b/mousepad/mousepad-document.h
index c390a91..fe4ba64 100644
--- a/mousepad/mousepad-document.h
+++ b/mousepad/mousepad-document.h
@@ -57,6 +57,9 @@ void mousepad_document_set_auto_indent (MousepadDocument
void mousepad_document_set_line_numbers (MousepadDocument *document,
gboolean line_numbers);
+void mousepad_document_set_overwrite (MousepadDocument *document,
+ gboolean overwrite);
+
void mousepad_document_set_word_wrap (MousepadDocument *document,
gboolean word_wrap);
@@ -97,6 +100,10 @@ void mousepad_document_line_numbers (MousepadDocument
gboolean mousepad_document_get_externally_modified (MousepadDocument *document);
+gboolean mousepad_document_get_can_undo (MousepadDocument *document);
+
+gboolean mousepad_document_get_can_redo (MousepadDocument *document);
+
const gchar *mousepad_document_get_filename (MousepadDocument *document);
gboolean mousepad_document_get_has_selection (MousepadDocument *document);
@@ -116,6 +123,10 @@ gboolean mousepad_document_get_line_numbers (MousepadDocument
gboolean mousepad_document_get_auto_indent (MousepadDocument *document);
+void mousepad_document_undo (MousepadDocument *document);
+
+void mousepad_document_redo (MousepadDocument *document);
+
G_END_DECLS
#endif /* !__MOUSEPAD_DOCUMENT_H__ */
diff --git a/mousepad/mousepad-private.h b/mousepad/mousepad-private.h
index e0455b4..b70e0de 100644
--- a/mousepad/mousepad-private.h
+++ b/mousepad/mousepad-private.h
@@ -21,6 +21,7 @@
#ifndef __MOUSEPAD_PRIVATE_H__
#define __MOUSEPAD_PRIVATE_H__
+#include <glib-object.h>
#include <gtk/gtk.h>
#include <libxfce4util/libxfce4util.h>
diff --git a/mousepad/mousepad-search-bar.c b/mousepad/mousepad-search-bar.c
index 46e197c..a0dc8e2 100644
--- a/mousepad/mousepad-search-bar.c
+++ b/mousepad/mousepad-search-bar.c
@@ -445,9 +445,12 @@ mousepad_search_bar_match_case_toggled (GtkWidget *button,
/* save the setting */
g_object_set (G_OBJECT (search_bar->preferences), "last-match-case", active, NULL);
- /* invoke the highlight function to update the buffer */
- search_bar->highlight_id = g_idle_add_full (G_PRIORITY_LOW, mousepad_search_bar_highlight_timeout,
- search_bar, mousepad_search_bar_highlight_timeout_destroy);
+ if (search_bar->highlight_all)
+ {
+ /* invoke the highlight function to update the buffer */
+ search_bar->highlight_id = g_idle_add_full (G_PRIORITY_LOW, mousepad_search_bar_highlight_timeout,
+ search_bar, mousepad_search_bar_highlight_timeout_destroy);
+ }
}
diff --git a/mousepad/mousepad-statusbar.c b/mousepad/mousepad-statusbar.c
index 43a879a..e75b0b1 100644
--- a/mousepad/mousepad-statusbar.c
+++ b/mousepad/mousepad-statusbar.c
@@ -24,9 +24,21 @@
#include <mousepad/mousepad-private.h>
#include <mousepad/mousepad-statusbar.h>
+
+
static void mousepad_statusbar_class_init (MousepadStatusbarClass *klass);
static void mousepad_statusbar_init (MousepadStatusbar *statusbar);
-static void mousepad_statusbar_finalize (GObject *object);
+static gboolean mousepad_statusbar_overwrite_clicked (GtkWidget *widget,
+ GdkEventButton *event,
+ MousepadStatusbar *statusbar);
+
+
+
+enum
+{
+ ENABLE_OVERWRITE,
+ LAST_SIGNAL,
+};
struct _MousepadStatusbarClass
{
@@ -37,6 +49,9 @@ struct _MousepadStatusbar
{
GtkHBox __parent__;
+ /* whether overwrite is enabled */
+ guint overwrite_enabled : 1;
+
/* the three statusbar labels */
GtkWidget *label;
GtkWidget *position;
@@ -45,7 +60,7 @@ struct _MousepadStatusbar
-static GObjectClass *mousepad_statusbar_parent_class;
+static guint statusbar_signals[LAST_SIGNAL];
@@ -83,10 +98,15 @@ mousepad_statusbar_class_init (MousepadStatusbarClass *klass)
{
GObjectClass *gobject_class;
- mousepad_statusbar_parent_class = g_type_class_peek_parent (klass);
-
gobject_class = G_OBJECT_CLASS (klass);
- gobject_class->finalize = mousepad_statusbar_finalize;
+
+ statusbar_signals[ENABLE_OVERWRITE] =
+ g_signal_new (I_("enable-overwrite"),
+ G_TYPE_FROM_CLASS (gobject_class),
+ G_SIGNAL_RUN_LAST,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__BOOLEAN,
+ G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
}
@@ -94,7 +114,7 @@ mousepad_statusbar_class_init (MousepadStatusbarClass *klass)
static void
mousepad_statusbar_init (MousepadStatusbar *statusbar)
{
- GtkWidget *frame;
+ GtkWidget *frame, *ebox;
/* spacing between the 3 frames */
gtk_box_set_spacing (GTK_BOX (statusbar), 3);
@@ -108,7 +128,7 @@ mousepad_statusbar_init (MousepadStatusbar *statusbar)
statusbar->label = gtk_label_new (NULL);
gtk_label_set_single_line_mode (GTK_LABEL (statusbar->label), TRUE);
gtk_misc_set_alignment (GTK_MISC (statusbar->label), 0.0, 0.5);
- gtk_misc_set_padding (GTK_MISC (statusbar->label), 2, 2);
+ gtk_misc_set_padding (GTK_MISC (statusbar->label), 4, 2);
gtk_label_set_ellipsize (GTK_LABEL (statusbar->label), PANGO_ELLIPSIZE_END);
gtk_container_add (GTK_CONTAINER (frame), statusbar->label);
gtk_widget_show (statusbar->label);
@@ -121,7 +141,7 @@ mousepad_statusbar_init (MousepadStatusbar *statusbar)
statusbar->position = gtk_label_new (NULL);
gtk_container_add (GTK_CONTAINER (frame), statusbar->position);
- gtk_misc_set_padding (GTK_MISC (statusbar->position), 2, 2);
+ gtk_misc_set_padding (GTK_MISC (statusbar->position), 4, 2);
gtk_widget_show (statusbar->position);
/* overwrite */
@@ -130,18 +150,38 @@ mousepad_statusbar_init (MousepadStatusbar *statusbar)
gtk_box_pack_start (GTK_BOX (statusbar), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);
- statusbar->overwrite = gtk_label_new (NULL);
- gtk_container_add (GTK_CONTAINER (frame), statusbar->overwrite);
- gtk_misc_set_padding (GTK_MISC (statusbar->overwrite), 2, 2);
+ ebox = gtk_event_box_new ();
+ gtk_container_add (GTK_CONTAINER (frame), ebox);
+ gtk_widget_show (ebox);
+ g_signal_connect (G_OBJECT (ebox), "button-press-event",
+ G_CALLBACK (mousepad_statusbar_overwrite_clicked), statusbar);
+
+ statusbar->overwrite = gtk_label_new (_("OVR"));
+ gtk_container_add (GTK_CONTAINER (ebox), statusbar->overwrite);
+ gtk_misc_set_padding (GTK_MISC (statusbar->overwrite), 4, 2);
gtk_widget_show (statusbar->overwrite);
}
-static void
-mousepad_statusbar_finalize (GObject *object)
+static gboolean
+mousepad_statusbar_overwrite_clicked (GtkWidget *widget,
+ GdkEventButton *event,
+ MousepadStatusbar *statusbar)
{
- (*G_OBJECT_CLASS (mousepad_statusbar_parent_class)->finalize) (object);
+ _mousepad_return_val_if_fail (MOUSEPAD_IS_STATUSBAR (statusbar), FALSE);
+
+ /* only respond on the left button click */
+ if (event->type != GDK_BUTTON_PRESS || event->button != 1)
+ return FALSE;
+
+ /* swap the startusbar state */
+ statusbar->overwrite_enabled = !statusbar->overwrite_enabled;
+
+ /* send the signal */
+ g_signal_emit (G_OBJECT (statusbar), statusbar_signals[ENABLE_OVERWRITE], 0, statusbar->overwrite_enabled);
+
+ return TRUE;
}
@@ -180,5 +220,7 @@ mousepad_statusbar_set_overwrite (MousepadStatusbar *statusbar,
{
_mousepad_return_if_fail (MOUSEPAD_IS_STATUSBAR (statusbar));
- gtk_label_set_text (GTK_LABEL (statusbar->overwrite), overwrite ? _("OVR") : _("INS"));
+ gtk_widget_set_sensitive (statusbar->overwrite, overwrite);
+
+ statusbar->overwrite_enabled = overwrite;
}
diff --git a/mousepad/mousepad-undo.c b/mousepad/mousepad-undo.c
new file mode 100644
index 0000000..874538f
--- /dev/null
+++ b/mousepad/mousepad-undo.c
@@ -0,0 +1,592 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2007 Nick Schermer <nick at xfce.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 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
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <mousepad/mousepad-private.h>
+#include <mousepad/mousepad-undo.h>
+
+
+
+/* maximum number of steps in the undo manager */
+#define MAX_UNDO_STEPS 50
+
+
+
+typedef struct _MousepadUndoInfo MousepadUndoInfo;
+typedef enum _MousepadUndoAction MousepadUndoAction;
+
+enum
+{
+ CAN_UNDO,
+ CAN_REDO,
+ LAST_SIGNAL
+};
+
+enum _MousepadUndoAction
+{
+ INSERT,
+ DELETE,
+};
+
+struct _MousepadUndoClass
+{
+ GObjectClass __parent__;
+};
+
+struct _MousepadUndo
+{
+ GObject __parent__;
+
+ /* the text buffer we're monitoring */
+ GtkTextBuffer *buffer;
+
+ /* whether the undo monitor is locked */
+ guint locked;
+
+ /* list of undo steps */
+ GSList *steps;
+
+ /* position in the steps list */
+ gint steps_position;
+
+ /* the buffer of the active step */
+ GString *step_buffer;
+
+ /* the info of the active step */
+ MousepadUndoAction step_action;
+ gint step_start;
+ gint step_end;
+
+ /* whether we can undo and redo */
+ guint can_undo : 1;
+ guint can_redo : 1;
+};
+
+struct _MousepadUndoInfo
+{
+ /* the action of the undo step */
+ MousepadUndoAction action;
+
+ /* the deleted or inserted string */
+ gchar *string;
+
+ /* the start and end position in the buffer */
+ gint start;
+ gint end;
+};
+
+
+
+static void mousepad_undo_class_init (MousepadUndoClass *klass);
+static void mousepad_undo_init (MousepadUndo *undo);
+static void mousepad_undo_finalize (GObject *object);
+static void mousepad_undo_free_step (MousepadUndoInfo *info);
+static void mousepad_undo_preform_step (MousepadUndo *undo,
+ gboolean undo_step);
+static void mousepad_undo_new_step (MousepadUndo *undo);
+static void mousepad_undo_insert_text (GtkTextBuffer *buffer,
+ GtkTextIter *pos,
+ const gchar *text,
+ gint length,
+ MousepadUndo *undo);
+static void mousepad_undo_delete_range (GtkTextBuffer *buffer,
+ GtkTextIter *start_iter,
+ GtkTextIter *end_iter,
+ MousepadUndo *undo);
+
+
+
+static GObjectClass *mousepad_undo_parent_class;
+static guint undo_signals[LAST_SIGNAL];
+
+
+
+GType
+mousepad_undo_get_type (void)
+{
+ static GType type = G_TYPE_INVALID;
+
+ if (G_UNLIKELY (type == G_TYPE_INVALID))
+ {
+ type = g_type_register_static_simple (G_TYPE_OBJECT,
+ I_("MousepadUndo"),
+ sizeof (MousepadUndoClass),
+ (GClassInitFunc) mousepad_undo_class_init,
+ sizeof (MousepadUndo),
+ (GInstanceInitFunc) mousepad_undo_init,
+ 0);
+ }
+
+ return type;
+}
+
+
+
+static void
+mousepad_undo_class_init (MousepadUndoClass *klass)
+{
+ GObjectClass *gobject_class;
+
+ mousepad_undo_parent_class = g_type_class_peek_parent (klass);
+
+ gobject_class = G_OBJECT_CLASS (klass);
+ gobject_class->finalize = mousepad_undo_finalize;
+
+ undo_signals[CAN_UNDO] =
+ g_signal_new (I_("can-undo"),
+ G_TYPE_FROM_CLASS (gobject_class),
+ G_SIGNAL_RUN_LAST,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__BOOLEAN,
+ G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
+
+ undo_signals[CAN_REDO] =
+ g_signal_new (I_("can-redo"),
+ G_TYPE_FROM_CLASS (gobject_class),
+ G_SIGNAL_RUN_LAST,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__BOOLEAN,
+ G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
+}
+
+
+
+static void
+mousepad_undo_init (MousepadUndo *undo)
+{
+ /* reset some variabled */
+ undo->locked = 0;
+ undo->steps = NULL;
+ undo->steps_position = 0;
+
+ /* we can't undo or redo */
+ undo->can_undo = FALSE;
+ undo->can_redo = FALSE;
+
+ /* allocate the string buffer (we prealloc 15 characters to avoid mulitple reallocations ) */
+ undo->step_buffer = g_string_sized_new (15);
+}
+
+
+
+static void
+mousepad_undo_finalize (GObject *object)
+{
+ MousepadUndo *undo = MOUSEPAD_UNDO (object);
+ GSList *li;
+
+ /* cleanup the undo steps */
+ for (li = undo->steps; li != NULL; li = li->next)
+ mousepad_undo_free_step (li->data);
+
+ /* free the list */
+ g_slist_free (undo->steps);
+
+ /* cleanup the monitor step */
+ g_string_free (undo->step_buffer, TRUE);
+
+ /* release the undo reference from the buffer */
+ g_object_unref (G_OBJECT (undo->buffer));
+
+ (*G_OBJECT_CLASS (mousepad_undo_parent_class)->finalize) (object);
+}
+
+
+
+static void
+mousepad_undo_free_step (MousepadUndoInfo *info)
+{
+ /* free the string */
+ g_free (info->string);
+
+ /* free the slice */
+ g_slice_free (MousepadUndoInfo, info);
+}
+
+
+
+static void
+mousepad_undo_preform_step (MousepadUndo *undo,
+ gboolean undo_step)
+{
+ MousepadUndoInfo *info;
+ MousepadUndoAction action;
+ GtkTextIter start_iter, end_iter;
+
+ _mousepad_return_if_fail (MOUSEPAD_IS_UNDO (undo));
+
+ /* prevent undo updates */
+ mousepad_undo_lock (undo);
+
+ /* flush the undo buffer */
+ mousepad_undo_new_step (undo);
+ undo->step_start = undo->step_end = 0;
+
+ /* decrease the position counter if we're going to undo */
+ if (undo_step)
+ undo->steps_position--;
+
+ /* get the step we're going to undo */
+ info = g_slist_nth_data (undo->steps, undo->steps_position);
+
+ if (G_LIKELY (info))
+ {
+ /* get the action */
+ action = info->action;
+
+ /* swap the action if we're going to undo */
+ if (!undo_step)
+ action = (action == INSERT ? DELETE : INSERT);
+
+ /* get the start iter position */
+ gtk_text_buffer_get_iter_at_offset (undo->buffer, &start_iter, info->start);
+
+ switch (action)
+ {
+ case INSERT:
+ /* get the end iter */
+ gtk_text_buffer_get_iter_at_offset (undo->buffer, &end_iter, info->end);
+
+ /* delete the inserted text */
+ gtk_text_buffer_delete (undo->buffer, &start_iter, &end_iter);
+
+ break;
+
+ case DELETE:
+ /* insert the deleted text */
+ gtk_text_buffer_insert (undo->buffer, &start_iter, info->string, -1);
+
+ break;
+
+ default:
+ _mousepad_assert_not_reached ();
+ }
+
+ /* set the cursor, we scroll to the cursor in mousepad-document */
+ gtk_text_buffer_place_cursor (undo->buffer, &start_iter);
+
+ /* increase the position counter if we did a redo */
+ if (!undo_step)
+ undo->steps_position++;
+ }
+
+ /* set the can_undo boolean */
+ undo->can_undo = (undo->steps_position > 0);
+ undo->can_redo = (undo->steps_position < g_slist_length (undo->steps));
+
+ /* emit the can-undo and can-redo signals */
+ g_signal_emit (G_OBJECT (undo), undo_signals[CAN_UNDO], 0, undo->can_undo);
+ g_signal_emit (G_OBJECT (undo), undo_signals[CAN_REDO], 0, undo->can_redo);
+
+ /* remove our lock */
+ mousepad_undo_unlock (undo);
+}
+
+
+
+static void
+mousepad_undo_new_step (MousepadUndo *undo)
+{
+ MousepadUndoInfo *info;
+ gint i;
+ GSList *item;
+
+ /* leave when there is nothing todo */
+ if (undo->step_start == 0 && undo->step_end == 0)
+ return;
+
+ /* allocate the slice */
+ info = g_slice_new0 (MousepadUndoInfo);
+
+ /* set the info */
+ info->string = g_strdup (undo->step_buffer->str);
+ info->action = undo->step_action;
+ info->start = undo->step_start;
+ info->end = undo->step_end;
+
+ /* append to the steps list */
+ undo->steps = g_slist_append (undo->steps, info);
+
+ /* set the list position */
+ undo->steps_position = g_slist_length (undo->steps);
+
+ /* erase the buffer */
+ undo->step_buffer = g_string_erase (undo->step_buffer, 0, -1);
+
+ /* check the list length */
+ if (G_UNLIKELY (g_slist_length (undo->steps) > MAX_UNDO_STEPS))
+ for (i = g_slist_length (undo->steps); i > MAX_UNDO_STEPS; i--)
+ {
+ /* get the first item in the list */
+ item = g_slist_nth (undo->steps, 0);
+
+ /* cleanup the data */
+ mousepad_undo_free_step (item->data);
+
+ /* delete the node in the list */
+ undo->steps = g_slist_delete_link (undo->steps, item);
+ }
+}
+
+
+
+static void
+mousepad_undo_handle_step (const gchar *text,
+ gint start,
+ gint end,
+ MousepadUndoAction action,
+ MousepadUndo *undo)
+{
+ gboolean create_new_step = FALSE;
+
+ /* check if we need to update whether we can undo */
+ if (undo->can_undo != TRUE)
+ {
+ undo->can_undo = TRUE;
+
+ /* emit the can-undo signal */
+ g_signal_emit (G_OBJECT (undo), undo_signals[CAN_UNDO], 0, undo->can_undo);
+ }
+
+ /* check if we need to create a new step after we appended the data */
+ if (ABS (end - start) == 1)
+ {
+ switch (g_utf8_get_char (text))
+ {
+ case ' ':
+ case '\t':
+ case '\n':
+ create_new_step = TRUE;
+ break;
+ }
+ }
+
+ /* try to append to the active step */
+ if (undo->step_action == action
+ && action == INSERT
+ && undo->step_end == start)
+ {
+ /* append the inserted string */
+ undo->step_buffer = g_string_append_len (undo->step_buffer, text, (start - end));
+
+ /* update the end position */
+ undo->step_end = end;
+ }
+ else if (undo->step_action == action
+ && action == DELETE
+ && undo->step_start == end)
+ {
+ /* prepend the deleted text */
+ undo->step_buffer = g_string_prepend_len (undo->step_buffer, text, (end - start));
+
+ /* update the start position */
+ undo->step_start = start;
+ }
+ else
+ {
+ /* we really need a new step */
+ create_new_step = TRUE;
+ }
+
+ /* create a new step if needed */
+ if (create_new_step)
+ {
+ /* create step */
+ mousepad_undo_new_step (undo);
+
+ /* set the new info */
+ undo->step_buffer = g_string_append_len (undo->step_buffer, text, ABS (start - end));
+ undo->step_action = action;
+ undo->step_start = start;
+ undo->step_end = end;
+ }
+}
+
+
+
+static void
+mousepad_undo_insert_text (GtkTextBuffer *buffer,
+ GtkTextIter *pos,
+ const gchar *text,
+ gint length,
+ MousepadUndo *undo)
+{
+ gint start, end;
+
+ /* quit when the undo manager is locked */
+ if (undo->locked)
+ return;
+
+ /* get the start and end position */
+ start = gtk_text_iter_get_offset (pos);
+ end = start + length;
+
+ /* append the changes */
+ mousepad_undo_handle_step (text, start, end, INSERT, undo);
+}
+
+
+
+static void
+mousepad_undo_delete_range (GtkTextBuffer *buffer,
+ GtkTextIter *start_iter,
+ GtkTextIter *end_iter,
+ MousepadUndo *undo)
+{
+ gint start, end;
+ gchar *text;
+
+ /* quit when the undo manager is locked */
+ if (undo->locked)
+ return;
+
+ /* get the start and end position */
+ start = gtk_text_iter_get_offset (start_iter);
+ end = gtk_text_iter_get_offset (end_iter);
+
+ /* get the deleted string */
+ text = gtk_text_buffer_get_slice (buffer, start_iter, end_iter, FALSE);
+
+ /* append the changes */
+ mousepad_undo_handle_step (text, start, end, DELETE, undo);
+
+ /* cleanup */
+ g_free (text);
+}
+
+
+
+MousepadUndo *
+mousepad_undo_new (GtkTextBuffer *buffer)
+{
+ MousepadUndo *undo;
+
+ _mousepad_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), NULL);
+
+ /* create the undo object */
+ undo = g_object_new (MOUSEPAD_TYPE_UNDO, NULL);
+
+ /* set the buffer (we also take a reference) */
+ undo->buffer = g_object_ref (G_OBJECT (buffer));
+
+ /* connect signals to the buffer so we can monitor it */
+ g_signal_connect (G_OBJECT (buffer), "insert-text", G_CALLBACK (mousepad_undo_insert_text), undo);
+ g_signal_connect (G_OBJECT (buffer), "delete-range", G_CALLBACK (mousepad_undo_delete_range), undo);
+
+ return undo;
+}
+
+
+
+void
+mousepad_undo_lock (MousepadUndo *undo)
+{
+ _mousepad_return_if_fail (MOUSEPAD_IS_UNDO (undo));
+
+ /* increase the lock count */
+ undo->locked++;
+}
+
+
+
+void
+mousepad_undo_unlock (MousepadUndo *undo)
+{
+ _mousepad_return_if_fail (MOUSEPAD_IS_UNDO (undo));
+ _mousepad_return_if_fail (undo->locked > 0);
+
+ /* decrease the lock count */
+ undo->locked--;
+}
+
+
+
+void
+mousepad_undo_do_undo (MousepadUndo *undo)
+{
+ /* run the undo step */
+ mousepad_undo_preform_step (undo, TRUE);
+}
+
+
+
+void
+mousepad_undo_do_redo (MousepadUndo *undo)
+{
+ /* run the redo step */
+ mousepad_undo_preform_step (undo, FALSE);
+}
+
+
+
+gboolean
+mousepad_undo_can_undo (MousepadUndo *undo)
+{
+ _mousepad_return_val_if_fail (MOUSEPAD_IS_UNDO (undo), FALSE);
+
+ return undo->can_undo;
+}
+
+
+
+gboolean
+mousepad_undo_can_redo (MousepadUndo *undo)
+{
+ _mousepad_return_val_if_fail (MOUSEPAD_IS_UNDO (undo), FALSE);
+
+ return undo->can_redo;
+}
+
+
+
+void
+mousepad_undo_populate_popup (GtkTextView *textview,
+ GtkMenu *menu,
+ MousepadUndo *undo)
+{
+ GtkWidget *item;
+ gboolean editable;
+
+ _mousepad_return_if_fail (MOUSEPAD_IS_UNDO (undo));
+
+ /* whether the textview is editable */
+ editable = gtk_text_view_get_editable (textview);
+
+ /* separator */
+ item = gtk_separator_menu_item_new ();
+ gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), item);
+ gtk_widget_show (item);
+
+ /* redo item */
+ item = gtk_image_menu_item_new_from_stock (GTK_STOCK_REDO, NULL);
+ gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), item);
+ gtk_widget_set_sensitive (item, editable && mousepad_undo_can_redo (undo));
+ g_signal_connect_swapped (G_OBJECT (item), "activate", G_CALLBACK (mousepad_undo_do_redo), undo);
+ gtk_widget_show (item);
+
+ /* undo item */
+ item = gtk_image_menu_item_new_from_stock (GTK_STOCK_UNDO, NULL);
+ gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), item);
+ gtk_widget_set_sensitive (item, editable && mousepad_undo_can_undo (undo));
+ g_signal_connect_swapped (G_OBJECT (item), "activate", G_CALLBACK (mousepad_undo_do_undo), undo);
+ gtk_widget_show (item);
+}
diff --git a/mousepad/mousepad-undo.h b/mousepad/mousepad-undo.h
new file mode 100644
index 0000000..86ce9ae
--- /dev/null
+++ b/mousepad/mousepad-undo.h
@@ -0,0 +1,57 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2007 Nick Schermer <nick at xfce.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 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
+ */
+
+#ifndef __MOUSEPAD_UNDO_H__
+#define __MOUSEPAD_UNDO_H__
+
+G_BEGIN_DECLS
+
+typedef struct _MousepadUndoClass MousepadUndoClass;
+typedef struct _MousepadUndo MousepadUndo;
+
+#define MOUSEPAD_TYPE_UNDO (mousepad_undo_get_type ())
+#define MOUSEPAD_UNDO(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MOUSEPAD_TYPE_UNDO, MousepadUndo))
+#define MOUSEPAD_UNDO_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MOUSEPAD_TYPE_UNDO, MousepadUndoClass))
+#define MOUSEPAD_IS_UNDO(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MOUSEPAD_TYPE_UNDO))
+#define MOUSEPAD_IS_UNDO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MOUSEPAD_TYPE_UNDO))
+#define MOUSEPAD_UNDO_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MOUSEPAD_TYPE_UNDO, MousepadUndoClass))
+
+GType mousepad_undo_get_type (void) G_GNUC_CONST;
+
+MousepadUndo *mousepad_undo_new (GtkTextBuffer *buffer);
+
+void mousepad_undo_lock (MousepadUndo *undo);
+
+void mousepad_undo_unlock (MousepadUndo *undo);
+
+void mousepad_undo_do_undo (MousepadUndo *undo);
+
+void mousepad_undo_do_redo (MousepadUndo *undo);
+
+gboolean mousepad_undo_can_undo (MousepadUndo *undo);
+
+gboolean mousepad_undo_can_redo (MousepadUndo *undo);
+
+void mousepad_undo_populate_popup (GtkTextView *textview,
+ GtkMenu *menu,
+ MousepadUndo *undo);
+
+G_END_DECLS
+
+#endif /* !__MOUSEPAD_UNDO_H__ */
diff --git a/mousepad/mousepad-view.c b/mousepad/mousepad-view.c
index ed70907..cc6afd7 100644
--- a/mousepad/mousepad-view.c
+++ b/mousepad/mousepad-view.c
@@ -33,8 +33,6 @@
static void mousepad_view_class_init (MousepadViewClass *klass);
-static void mousepad_view_init (MousepadView *view);
-static void mousepad_view_finalize (GObject *object);
static gboolean mousepad_view_key_press_event (GtkWidget *widget,
GdkEventKey *event);
static void mousepad_view_indent_lines (MousepadView *view,
@@ -86,7 +84,7 @@ mousepad_view_get_type (void)
sizeof (MousepadViewClass),
(GClassInitFunc) mousepad_view_class_init,
sizeof (MousepadView),
- (GInstanceInitFunc) mousepad_view_init,
+ NULL,
0);
}
@@ -98,14 +96,10 @@ mousepad_view_get_type (void)
static void
mousepad_view_class_init (MousepadViewClass *klass)
{
- GObjectClass *gobject_class;
GtkWidgetClass *widget_class;
mousepad_view_parent_class = g_type_class_peek_parent (klass);
- gobject_class = G_OBJECT_CLASS (klass);
- gobject_class->finalize = mousepad_view_finalize;
-
widget_class = GTK_WIDGET_CLASS (klass);
widget_class->key_press_event = mousepad_view_key_press_event;
widget_class->expose_event = mousepad_view_expose;
@@ -113,22 +107,6 @@ mousepad_view_class_init (MousepadViewClass *klass)
-static void
-mousepad_view_init (MousepadView *view)
-{
- /* empty */
-}
-
-
-
-static void
-mousepad_view_finalize (GObject *object)
-{
- (*G_OBJECT_CLASS (mousepad_view_parent_class)->finalize) (object);
-}
-
-
-
/**
* mousepad_view_key_press_event:
* @widget : A #GtkWidget.
diff --git a/mousepad/mousepad-window-ui.xml b/mousepad/mousepad-window-ui.xml
index 25b4096..1477e41 100644
--- a/mousepad/mousepad-window-ui.xml
+++ b/mousepad/mousepad-window-ui.xml
@@ -25,6 +25,8 @@
<separator />
<menuitem action="reload" />
<separator />
+ <menuitem action="print-document" />
+ <separator />
<menuitem action="close-tab" />
<menuitem action="close-window" />
<menuitem action="close-all-windows" />
diff --git a/mousepad/mousepad-window.c b/mousepad/mousepad-window.c
index 8779309..14affd9 100644
--- a/mousepad/mousepad-window.c
+++ b/mousepad/mousepad-window.c
@@ -85,6 +85,8 @@ static gboolean mousepad_window_close_document (MousepadW
MousepadDocument *document);
static void mousepad_window_set_title (MousepadWindow *window,
MousepadDocument *document);
+static void mousepad_window_toggle_overwrite (MousepadWindow *window,
+ gboolean overwrite);
/* notebook signals */
static void mousepad_window_page_notified (GtkNotebook *notebook,
@@ -119,6 +121,10 @@ static void mousepad_window_overwrite_changed (MousepadD
static void mousepad_window_selection_changed (MousepadDocument *document,
gboolean selected,
MousepadWindow *window);
+static void mousepad_window_can_undo (MousepadWindow *window,
+ gboolean can_undo);
+static void mousepad_window_can_redo (MousepadWindow *window,
+ gboolean can_redo);
/* menu updaters */
static void mousepad_window_update_actions (MousepadWindow *window);
@@ -152,6 +158,8 @@ static void mousepad_window_action_save_file_as (GtkAction
MousepadWindow *window);
static void mousepad_window_action_reload (GtkAction *action,
MousepadWindow *window);
+static void mousepad_window_action_print (GtkAction *action,
+ MousepadWindow *window);
static void mousepad_window_action_close_tab (GtkAction *action,
MousepadWindow *window);
static void mousepad_window_action_close (GtkAction *action,
@@ -160,6 +168,10 @@ static void mousepad_window_action_close_all_windows (GtkAction
MousepadWindow *window);
static void mousepad_window_action_open_new_tab (GtkAction *action,
MousepadWindow *window);
+static void mousepad_window_action_undo (GtkAction *action,
+ MousepadWindow *window);
+static void mousepad_window_action_redo (GtkAction *action,
+ MousepadWindow *window);
static void mousepad_window_action_cut (GtkAction *action,
MousepadWindow *window);
static void mousepad_window_action_copy (GtkAction *action,
@@ -267,13 +279,14 @@ static const GtkActionEntry action_entries[] =
{ "save-file", GTK_STOCK_SAVE, N_("_Save"), NULL, N_("Save the current file"), G_CALLBACK (mousepad_window_action_save_file), },
{ "save-file-as", GTK_STOCK_SAVE_AS, N_("Save _As"), NULL, N_("Save current document as another file"), G_CALLBACK (mousepad_window_action_save_file_as), },
{ "reload", GTK_STOCK_REFRESH, N_("Re_load"), NULL, N_("Reload this document."), G_CALLBACK (mousepad_window_action_reload), },
+ { "print-document", GTK_STOCK_PRINT, N_("_Print"), "<control>P", N_("Prin the current page"), G_CALLBACK (mousepad_window_action_print), },
{ "close-tab", GTK_STOCK_CLOSE, N_("C_lose Tab"), "<control>W", N_("Close the current file"), G_CALLBACK (mousepad_window_action_close_tab), },
{ "close-window", GTK_STOCK_QUIT, N_("_Close Window"), "<control>Q", N_("Quit the program"), G_CALLBACK (mousepad_window_action_close), },
{ "close-all-windows", NULL, N_("Close _All Windows"), "<control><shift>W", N_("Close all Mousepad windows"), G_CALLBACK (mousepad_window_action_close_all_windows), },
{ "edit-menu", NULL, N_("_Edit"), NULL, NULL, NULL, },
- { "undo", GTK_STOCK_UNDO, N_("_Undo"), NULL, N_("Undo the last action"), NULL, },
- { "redo", GTK_STOCK_REDO, N_("_Redo"), NULL, N_("Redo the last undone action"), NULL, },
+ { "undo", GTK_STOCK_UNDO, N_("_Undo"), "<control>Z", N_("Undo the last action"), G_CALLBACK (mousepad_window_action_undo), },
+ { "redo", GTK_STOCK_REDO, N_("_Redo"), "<control>Y", N_("Redo the last undone action"), G_CALLBACK (mousepad_window_action_redo), },
{ "cut", GTK_STOCK_CUT, N_("Cu_t"), NULL, N_("Cut the selection"), G_CALLBACK (mousepad_window_action_cut), },
{ "copy", GTK_STOCK_COPY, N_("_Copy"), NULL, N_("Copy the selection"), G_CALLBACK (mousepad_window_action_copy), },
{ "paste", GTK_STOCK_PASTE, N_("_Paste"), NULL, N_("Paste the clipboard"), G_CALLBACK (mousepad_window_action_paste), },
@@ -953,6 +966,8 @@ mousepad_window_add (MousepadWindow *window,
g_signal_connect (G_OBJECT (document), "modified-changed", G_CALLBACK (mousepad_window_modified_changed), window);
g_signal_connect (G_OBJECT (document), "cursor-changed", G_CALLBACK (mousepad_window_cursor_changed), window);
g_signal_connect (G_OBJECT (document), "overwrite-changed", G_CALLBACK (mousepad_window_overwrite_changed), window);
+ g_signal_connect_swapped (G_OBJECT (document), "can-undo", G_CALLBACK (mousepad_window_can_undo), window);
+ g_signal_connect_swapped (G_OBJECT (document), "can-redo", G_CALLBACK (mousepad_window_can_redo), window);
/* insert the page right from the active tab */
page = gtk_notebook_get_current_page (GTK_NOTEBOOK (window->notebook));
@@ -1077,6 +1092,18 @@ mousepad_window_set_title (MousepadWindow *window,
+static void
+mousepad_window_toggle_overwrite (MousepadWindow *window,
+ gboolean overwrite)
+{
+ _mousepad_return_if_fail (MOUSEPAD_IS_WINDOW (window));
+
+ if (G_LIKELY (window->active))
+ mousepad_document_set_overwrite (window->active, overwrite);
+}
+
+
+
/**
* Notebook Signal Functions
**/
@@ -1294,6 +1321,30 @@ mousepad_window_selection_changed (MousepadDocument *document,
+static void
+mousepad_window_can_undo (MousepadWindow *window,
+ gboolean can_undo)
+{
+ GtkAction *action;
+
+ action = gtk_action_group_get_action (window->window_actions, "undo");
+ gtk_action_set_sensitive (action, can_undo);
+}
+
+
+
+static void
+mousepad_window_can_redo (MousepadWindow *window,
+ gboolean can_redo)
+{
+ GtkAction *action;
+
+ action = gtk_action_group_get_action (window->window_actions, "redo");
+ gtk_action_set_sensitive (action, can_redo);
+}
+
+
+
/**
* Menu Update Functions
**/
@@ -1349,6 +1400,10 @@ mousepad_window_update_actions (MousepadWindow *window)
action = gtk_action_group_get_action (window->window_actions, "auto-indent");
gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), active);
+ /* set the sensitivity of the undo and redo actions */
+ mousepad_window_can_undo (window, mousepad_document_get_can_undo (document));
+ mousepad_window_can_redo (window, mousepad_document_get_can_redo (document));
+
/* set the sensitivity of the selection actions */
has_selection = mousepad_document_get_has_selection (document);
mousepad_window_selection_changed (document, has_selection, window);
@@ -1981,6 +2036,15 @@ mousepad_window_action_reload (GtkAction *action,
static void
+mousepad_window_action_print (GtkAction *action,
+ MousepadWindow *window)
+{
+
+}
+
+
+
+static void
mousepad_window_action_close_tab (GtkAction *action,
MousepadWindow *window)
{
@@ -2056,6 +2120,26 @@ mousepad_window_action_close_all_windows (GtkAction *action,
static void
+mousepad_window_action_undo (GtkAction *action,
+ MousepadWindow *window)
+{
+ if (G_LIKELY (window->active != NULL))
+ mousepad_document_undo (window->active);
+}
+
+
+
+static void
+mousepad_window_action_redo (GtkAction *action,
+ MousepadWindow *window)
+{
+ if (G_LIKELY (window->active != NULL))
+ mousepad_document_redo (window->active);
+}
+
+
+
+static void
mousepad_window_action_cut (GtkAction *action,
MousepadWindow *window)
{
@@ -2300,6 +2384,10 @@ mousepad_window_action_statusbar (GtkToggleAction *action,
gtk_table_attach (GTK_TABLE (window->table), window->statusbar, 0, 1, 5, 6, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
gtk_widget_show (window->statusbar);
+ /* overwrite toggle signal */
+ g_signal_connect_swapped (G_OBJECT (window->statusbar), "enable-overwrite",
+ G_CALLBACK (mousepad_window_toggle_overwrite), window);
+
/* set the statsbar text */
document = window->active;
if (document != NULL)
More information about the Xfce4-commits
mailing list