Merging search-regex branch
svn merge -r 893:900 svn+ssh://svn.berlios.de/svnroot/repos/ggap/moo/branches/search-regexmaster
parent
f4a2e8a2f3
commit
e05a644874
1
moo/TODO
1
moo/TODO
|
@ -12,6 +12,7 @@ Editor
|
||||||
Terminal
|
Terminal
|
||||||
========
|
========
|
||||||
|
|
||||||
|
0. FIX IT!
|
||||||
1. Think about profiles, can they help?
|
1. Think about profiles, can they help?
|
||||||
2. Terminal settings.
|
2. Terminal settings.
|
||||||
|
|
||||||
|
|
|
@ -11,8 +11,8 @@ mooedit_srcdir = $(srcdir)/$(mooedit)
|
||||||
mooedit_glade = $(mooedit)/glade
|
mooedit_glade = $(mooedit)/glade
|
||||||
|
|
||||||
moo_extra_dist += \
|
moo_extra_dist += \
|
||||||
$(mooedit_glade)/mooeditgotoline.glade \
|
$(mooedit_glade)/mootextgotoline.glade \
|
||||||
$(mooedit_glade)/mooeditfind.glade \
|
$(mooedit_glade)/mootextfind.glade \
|
||||||
$(mooedit_glade)/mooeditprefs.glade \
|
$(mooedit_glade)/mooeditprefs.glade \
|
||||||
$(mooedit_glade)/mooeditcolorsprefs.glade \
|
$(mooedit_glade)/mooeditcolorsprefs.glade \
|
||||||
$(mooedit_glade)/moopluginprefs.glade
|
$(mooedit_glade)/moopluginprefs.glade
|
||||||
|
@ -86,7 +86,7 @@ mooedit_include_headers = \
|
||||||
$(mooedit)/mooedit.h \
|
$(mooedit)/mooedit.h \
|
||||||
$(mooedit)/mooeditor.h \
|
$(mooedit)/mooeditor.h \
|
||||||
$(mooedit)/mooeditprefs.h \
|
$(mooedit)/mooeditprefs.h \
|
||||||
$(mooedit)/mooeditsearch.h \
|
$(mooedit)/mootextsearch.h \
|
||||||
$(mooedit)/mooeditwindow.h \
|
$(mooedit)/mooeditwindow.h \
|
||||||
$(mooedit)/mooindenter.h \
|
$(mooedit)/mooindenter.h \
|
||||||
$(mooedit)/moolang.h \
|
$(mooedit)/moolang.h \
|
||||||
|
@ -106,8 +106,6 @@ mooedit_noinst_headers = \
|
||||||
$(mooedit)/mooeditcolorsprefs-glade.h \
|
$(mooedit)/mooeditcolorsprefs-glade.h \
|
||||||
$(mooedit)/mooeditdialogs.h \
|
$(mooedit)/mooeditdialogs.h \
|
||||||
$(mooedit)/mooeditfileops.h \
|
$(mooedit)/mooeditfileops.h \
|
||||||
$(mooedit)/mooeditfind-glade.h \
|
|
||||||
$(mooedit)/mooeditgotoline-glade.h \
|
|
||||||
$(mooedit)/mooeditprefs-glade.h \
|
$(mooedit)/mooeditprefs-glade.h \
|
||||||
$(mooedit)/moohighlighter.h \
|
$(mooedit)/moohighlighter.h \
|
||||||
$(mooedit)/moolang-aux.h \
|
$(mooedit)/moolang-aux.h \
|
||||||
|
@ -116,6 +114,9 @@ mooedit_noinst_headers = \
|
||||||
$(mooedit)/moolang-strings.h \
|
$(mooedit)/moolang-strings.h \
|
||||||
$(mooedit)/moolinebuffer.h \
|
$(mooedit)/moolinebuffer.h \
|
||||||
$(mooedit)/moopluginprefs-glade.h \
|
$(mooedit)/moopluginprefs-glade.h \
|
||||||
|
$(mooedit)/mootextfind-glade.h \
|
||||||
|
$(mooedit)/mootextfind.h \
|
||||||
|
$(mooedit)/mootextgotoline-glade.h \
|
||||||
$(mooedit)/mootextbtree.h \
|
$(mooedit)/mootextbtree.h \
|
||||||
$(mooedit)/mootextview-private.h
|
$(mooedit)/mootextview-private.h
|
||||||
|
|
||||||
|
@ -128,12 +129,12 @@ mooedit_sources = \
|
||||||
$(mooedit)/mooedit.c \
|
$(mooedit)/mooedit.c \
|
||||||
$(mooedit)/mooeditdialogs.c \
|
$(mooedit)/mooeditdialogs.c \
|
||||||
$(mooedit)/mooeditfileops.c \
|
$(mooedit)/mooeditfileops.c \
|
||||||
$(mooedit)/mooeditfind.c \
|
$(mooedit)/mootextfind.c \
|
||||||
$(mooedit)/mooeditinput.c \
|
$(mooedit)/mooeditinput.c \
|
||||||
$(mooedit)/mooeditor.c \
|
$(mooedit)/mooeditor.c \
|
||||||
$(mooedit)/mooeditprefs.c \
|
$(mooedit)/mooeditprefs.c \
|
||||||
$(mooedit)/mooeditprefspage.c \
|
$(mooedit)/mooeditprefspage.c \
|
||||||
$(mooedit)/mooeditsearch.c \
|
$(mooedit)/mootextsearch.c \
|
||||||
$(mooedit)/mooeditwindow.c \
|
$(mooedit)/mooeditwindow.c \
|
||||||
$(mooedit)/moohighlighter.c \
|
$(mooedit)/moohighlighter.c \
|
||||||
$(mooedit)/mooindenter.c \
|
$(mooedit)/mooindenter.c \
|
||||||
|
@ -151,20 +152,20 @@ mooedit_sources = \
|
||||||
$(mooedit)/mootextview.c
|
$(mooedit)/mootextview.c
|
||||||
|
|
||||||
mooedit_built_sources = \
|
mooedit_built_sources = \
|
||||||
$(mooedit)/mooeditgotoline-glade.h \
|
$(mooedit)/mootextgotoline-glade.h \
|
||||||
$(mooedit)/mooeditfind-glade.h \
|
$(mooedit)/mootextfind-glade.h \
|
||||||
$(mooedit)/moopluginprefs-glade.h \
|
$(mooedit)/moopluginprefs-glade.h \
|
||||||
$(mooedit)/mooeditprefs-glade.h \
|
$(mooedit)/mooeditprefs-glade.h \
|
||||||
$(mooedit)/mooeditcolorsprefs-glade.h
|
$(mooedit)/mooeditcolorsprefs-glade.h
|
||||||
|
|
||||||
|
|
||||||
$(mooedit)/mooeditgotoline-glade.h: $(mooedit_srcdir)/glade/mooeditgotoline.glade $(XML2H)
|
$(mooedit)/mootextgotoline-glade.h: $(mooedit_srcdir)/glade/mootextgotoline.glade $(XML2H)
|
||||||
sh $(XML2H) MOO_EDIT_GOTO_LINE_GLADE_UI $(mooedit_srcdir)/glade/mooeditgotoline.glade \
|
sh $(XML2H) MOO_TEXT_GOTO_LINE_GLADE_UI $(mooedit_srcdir)/glade/mootextgotoline.glade \
|
||||||
> $(mooedit)/mooeditgotoline-glade.h
|
> $(mooedit)/mootextgotoline-glade.h
|
||||||
|
|
||||||
$(mooedit)/mooeditfind-glade.h: $(mooedit_srcdir)/glade/mooeditfind.glade $(XML2H)
|
$(mooedit)/mootextfind-glade.h: $(mooedit_srcdir)/glade/mootextfind.glade $(XML2H)
|
||||||
sh $(XML2H) MOO_EDIT_FIND_GLADE_UI $(mooedit_srcdir)/glade/mooeditfind.glade \
|
sh $(XML2H) MOO_TEXT_FIND_GLADE_UI $(mooedit_srcdir)/glade/mootextfind.glade \
|
||||||
> $(mooedit)/mooeditfind-glade.h
|
> $(mooedit)/mootextfind-glade.h
|
||||||
|
|
||||||
$(mooedit)/mooeditprefs-glade.h: $(mooedit_srcdir)/glade/mooeditprefs.glade $(XML2H)
|
$(mooedit)/mooeditprefs-glade.h: $(mooedit_srcdir)/glade/mooeditprefs.glade $(XML2H)
|
||||||
sh $(XML2H) MOO_EDIT_PREFS_GLADE_UI $(mooedit_srcdir)/glade/mooeditprefs.glade \
|
sh $(XML2H) MOO_EDIT_PREFS_GLADE_UI $(mooedit_srcdir)/glade/mooeditprefs.glade \
|
||||||
|
|
|
@ -64,14 +64,14 @@
|
||||||
</child>
|
</child>
|
||||||
|
|
||||||
<child>
|
<child>
|
||||||
<widget class="GtkVBox" id="vbox1">
|
<widget class="GtkVBox" id="vbox">
|
||||||
<property name="border_width">3</property>
|
<property name="border_width">3</property>
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="homogeneous">False</property>
|
<property name="homogeneous">False</property>
|
||||||
<property name="spacing">3</property>
|
<property name="spacing">3</property>
|
||||||
|
|
||||||
<child>
|
<child>
|
||||||
<widget class="GtkFrame" id="frame1">
|
<widget class="GtkFrame" id="find_frame">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="label_xalign">0</property>
|
<property name="label_xalign">0</property>
|
||||||
<property name="label_yalign">0.5</property>
|
<property name="label_yalign">0.5</property>
|
||||||
|
@ -117,7 +117,7 @@
|
||||||
</child>
|
</child>
|
||||||
|
|
||||||
<child>
|
<child>
|
||||||
<widget class="GtkEntry" id="text_to_find">
|
<widget class="GtkEntry" id="search_entry">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="editable">True</property>
|
<property name="editable">True</property>
|
||||||
<property name="visibility">True</property>
|
<property name="visibility">True</property>
|
||||||
|
@ -141,7 +141,7 @@
|
||||||
<property name="spacing">0</property>
|
<property name="spacing">0</property>
|
||||||
|
|
||||||
<child>
|
<child>
|
||||||
<widget class="GtkCheckButton" id="regular_expression">
|
<widget class="GtkCheckButton" id="regex">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">True</property>
|
<property name="can_focus">True</property>
|
||||||
<property name="label" translatable="yes">Regular expression </property>
|
<property name="label" translatable="yes">Regular expression </property>
|
||||||
|
@ -258,7 +258,7 @@
|
||||||
</child>
|
</child>
|
||||||
|
|
||||||
<child>
|
<child>
|
||||||
<widget class="GtkEntry" id="replacement_text">
|
<widget class="GtkEntry" id="replace_entry">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="editable">True</property>
|
<property name="editable">True</property>
|
||||||
<property name="visibility">True</property>
|
<property name="visibility">True</property>
|
||||||
|
@ -282,10 +282,10 @@
|
||||||
<property name="spacing">0</property>
|
<property name="spacing">0</property>
|
||||||
|
|
||||||
<child>
|
<child>
|
||||||
<widget class="GtkCheckButton" id="use_placeholders">
|
<widget class="GtkCheckButton" id="repl_literal">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">True</property>
|
<property name="can_focus">True</property>
|
||||||
<property name="label" translatable="yes">Use placeholders </property>
|
<property name="label" translatable="yes">Literal replacement</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use_underline">True</property>
|
||||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||||
<property name="focus_on_click">False</property>
|
<property name="focus_on_click">False</property>
|
||||||
|
@ -338,7 +338,7 @@
|
||||||
</child>
|
</child>
|
||||||
|
|
||||||
<child>
|
<child>
|
||||||
<widget class="GtkFrame" id="frame2">
|
<widget class="GtkFrame" id="options_frame">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="label_xalign">0</property>
|
<property name="label_xalign">0</property>
|
||||||
<property name="label_yalign">0.5</property>
|
<property name="label_yalign">0.5</property>
|
||||||
|
@ -366,7 +366,7 @@
|
||||||
<property name="column_spacing">3</property>
|
<property name="column_spacing">3</property>
|
||||||
|
|
||||||
<child>
|
<child>
|
||||||
<widget class="GtkCheckButton" id="whole_words_only">
|
<widget class="GtkCheckButton" id="whole_words">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">True</property>
|
<property name="can_focus">True</property>
|
||||||
<property name="label" translatable="yes">Whole words only</property>
|
<property name="label" translatable="yes">Whole words only</property>
|
||||||
|
@ -410,7 +410,7 @@
|
||||||
</child>
|
</child>
|
||||||
|
|
||||||
<child>
|
<child>
|
||||||
<widget class="GtkCheckButton" id="selected_text">
|
<widget class="GtkCheckButton" id="selected">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">True</property>
|
<property name="can_focus">True</property>
|
||||||
<property name="label" translatable="yes">Selected text</property>
|
<property name="label" translatable="yes">Selected text</property>
|
||||||
|
@ -453,7 +453,7 @@
|
||||||
</child>
|
</child>
|
||||||
|
|
||||||
<child>
|
<child>
|
||||||
<widget class="GtkCheckButton" id="find_backwards">
|
<widget class="GtkCheckButton" id="backwards">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">True</property>
|
<property name="can_focus">True</property>
|
||||||
<property name="label" translatable="yes">Find backwards</property>
|
<property name="label" translatable="yes">Find backwards</property>
|
||||||
|
@ -474,7 +474,7 @@
|
||||||
</child>
|
</child>
|
||||||
|
|
||||||
<child>
|
<child>
|
||||||
<widget class="GtkCheckButton" id="dont_prompt_on_replace">
|
<widget class="GtkCheckButton" id="dont_prompt">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">True</property>
|
<property name="can_focus">True</property>
|
||||||
<property name="label" translatable="yes">Don't prompt on replace</property>
|
<property name="label" translatable="yes">Don't prompt on replace</property>
|
||||||
|
@ -570,7 +570,7 @@
|
||||||
<property name="use_underline">True</property>
|
<property name="use_underline">True</property>
|
||||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||||
<property name="focus_on_click">False</property>
|
<property name="focus_on_click">False</property>
|
||||||
<property name="response_id">3</property>
|
<property name="response_id">2</property>
|
||||||
</widget>
|
</widget>
|
||||||
</child>
|
</child>
|
||||||
|
|
||||||
|
@ -583,7 +583,7 @@
|
||||||
<property name="use_underline">True</property>
|
<property name="use_underline">True</property>
|
||||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||||
<property name="focus_on_click">False</property>
|
<property name="focus_on_click">False</property>
|
||||||
<property name="response_id">4</property>
|
<property name="response_id">3</property>
|
||||||
</widget>
|
</widget>
|
||||||
</child>
|
</child>
|
||||||
|
|
||||||
|
@ -596,7 +596,7 @@
|
||||||
<property name="use_underline">True</property>
|
<property name="use_underline">True</property>
|
||||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||||
<property name="focus_on_click">False</property>
|
<property name="focus_on_click">False</property>
|
||||||
<property name="response_id">2</property>
|
<property name="response_id">1</property>
|
||||||
</widget>
|
</widget>
|
||||||
</child>
|
</child>
|
||||||
|
|
||||||
|
@ -609,7 +609,7 @@
|
||||||
<property name="use_underline">True</property>
|
<property name="use_underline">True</property>
|
||||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||||
<property name="focus_on_click">False</property>
|
<property name="focus_on_click">False</property>
|
||||||
<property name="response_id">-6</property>
|
<property name="response_id">0</property>
|
||||||
</widget>
|
</widget>
|
||||||
</child>
|
</child>
|
||||||
</widget>
|
</widget>
|
|
@ -20,7 +20,6 @@
|
||||||
#define __MOO_EDIT_PRIVATE_H__
|
#define __MOO_EDIT_PRIVATE_H__
|
||||||
|
|
||||||
#include "mooedit/mooeditor.h"
|
#include "mooedit/mooeditor.h"
|
||||||
#include "mooedit/mooeditsearch.h"
|
|
||||||
#include "mooedit/mootextview.h"
|
#include "mooedit/mootextview.h"
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
|
@ -16,10 +16,11 @@
|
||||||
#include "mooedit/mooeditdialogs.h"
|
#include "mooedit/mooeditdialogs.h"
|
||||||
#include "mooedit/mooedit-private.h"
|
#include "mooedit/mooedit-private.h"
|
||||||
#include "mooedit/mooeditprefs.h"
|
#include "mooedit/mooeditprefs.h"
|
||||||
#include "mooedit/mooeditfind-glade.h"
|
#include "mooedit/mootextfind-glade.h"
|
||||||
#include "mooutils/moodialogs.h"
|
#include "mooutils/moodialogs.h"
|
||||||
#include "mooutils/moostock.h"
|
#include "mooutils/moostock.h"
|
||||||
#include "mooutils/mooglade.h"
|
#include "mooutils/mooglade.h"
|
||||||
|
#include "mooutils/eggregex.h"
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
|
|
||||||
|
@ -576,24 +577,38 @@ moo_edit_file_modified_on_disk_dialog (MooEdit *edit)
|
||||||
/* Search dialogs
|
/* Search dialogs
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
static GtkWindow *
|
||||||
|
get_parent_window (GtkWidget *widget)
|
||||||
|
{
|
||||||
|
if (widget)
|
||||||
|
{
|
||||||
|
widget = gtk_widget_get_toplevel (widget);
|
||||||
|
|
||||||
|
if (GTK_WIDGET_TOPLEVEL (widget))
|
||||||
|
return GTK_WINDOW (widget);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
moo_text_nothing_found_dialog (MooTextView *view,
|
moo_text_nothing_found_dialog (GtkWidget *parent,
|
||||||
const char *text,
|
const char *text,
|
||||||
gboolean regex)
|
gboolean regex)
|
||||||
{
|
{
|
||||||
GtkWindow *parent_window;
|
|
||||||
GtkWidget *dialog;
|
GtkWidget *dialog;
|
||||||
char *msg_text;
|
char *msg_text;
|
||||||
|
|
||||||
g_return_if_fail (MOO_IS_TEXT_VIEW (view) && text != NULL);
|
g_return_if_fail (text != NULL);
|
||||||
|
|
||||||
if (regex)
|
if (regex)
|
||||||
msg_text = g_strdup_printf ("Search pattern '%s' not found!", text);
|
msg_text = g_strdup_printf ("Search pattern '%s' not found!", text);
|
||||||
else
|
else
|
||||||
msg_text = g_strdup_printf ("Search string '%s' not found!", text);
|
msg_text = g_strdup_printf ("Search string '%s' not found!", text);
|
||||||
|
|
||||||
parent_window = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (view)));
|
dialog = gtk_message_dialog_new (get_parent_window (parent),
|
||||||
dialog = gtk_message_dialog_new (parent_window, GTK_DIALOG_MODAL,
|
GTK_DIALOG_MODAL,
|
||||||
GTK_MESSAGE_INFO, GTK_BUTTONS_NONE,
|
GTK_MESSAGE_INFO, GTK_BUTTONS_NONE,
|
||||||
msg_text);
|
msg_text);
|
||||||
gtk_dialog_add_buttons (GTK_DIALOG (dialog), GTK_STOCK_CLOSE,
|
gtk_dialog_add_buttons (GTK_DIALOG (dialog), GTK_STOCK_CLOSE,
|
||||||
|
@ -608,16 +623,13 @@ moo_text_nothing_found_dialog (MooTextView *view,
|
||||||
|
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
moo_text_search_from_beginning_dialog (MooTextView *view,
|
moo_text_search_from_start_dialog (GtkWidget *widget,
|
||||||
gboolean backwards)
|
gboolean backwards)
|
||||||
{
|
{
|
||||||
GtkWindow *parent_window;
|
|
||||||
GtkWidget *dialog;
|
GtkWidget *dialog;
|
||||||
int response;
|
int response;
|
||||||
const char *msg;
|
const char *msg;
|
||||||
|
|
||||||
g_return_val_if_fail (MOO_IS_TEXT_VIEW (view), FALSE);
|
|
||||||
|
|
||||||
if (backwards)
|
if (backwards)
|
||||||
msg = "Beginning of document reached.\n"
|
msg = "Beginning of document reached.\n"
|
||||||
"Continue from the end?";
|
"Continue from the end?";
|
||||||
|
@ -625,8 +637,7 @@ moo_text_search_from_beginning_dialog (MooTextView *view,
|
||||||
msg = "End of document reached.\n"
|
msg = "End of document reached.\n"
|
||||||
"Continue from the beginning?";
|
"Continue from the beginning?";
|
||||||
|
|
||||||
parent_window = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (view)));
|
dialog = gtk_message_dialog_new (get_parent_window (widget), GTK_DIALOG_MODAL,
|
||||||
dialog = gtk_message_dialog_new (parent_window, GTK_DIALOG_MODAL,
|
|
||||||
GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE,
|
GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE,
|
||||||
msg);
|
msg);
|
||||||
gtk_dialog_add_buttons (GTK_DIALOG (dialog),
|
gtk_dialog_add_buttons (GTK_DIALOG (dialog),
|
||||||
|
@ -649,31 +660,34 @@ moo_text_search_from_beginning_dialog (MooTextView *view,
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
moo_text_regex_error_dialog (MooTextView *view,
|
moo_text_regex_error_dialog (GtkWidget *parent,
|
||||||
GError *err)
|
GError *error)
|
||||||
{
|
{
|
||||||
GtkWindow *parent_window;
|
|
||||||
GtkWidget *dialog;
|
GtkWidget *dialog;
|
||||||
char *msg_text = NULL;
|
char *msg_text = NULL;
|
||||||
|
|
||||||
g_return_if_fail (MOO_IS_TEXT_VIEW (view));
|
if (error)
|
||||||
|
{
|
||||||
if (err) {
|
if (error->domain != EGG_REGEX_ERROR)
|
||||||
if (err->domain != EGG_REGEX_ERROR)
|
{
|
||||||
g_warning ("%s: unknown error domain", G_STRLOC);
|
g_warning ("%s: unknown error domain", G_STRLOC);
|
||||||
else if (err->code != EGG_REGEX_ERROR_COMPILE &&
|
}
|
||||||
err->code != EGG_REGEX_ERROR_OPTIMIZE &&
|
else if (error->code != EGG_REGEX_ERROR_COMPILE &&
|
||||||
err->code != EGG_REGEX_ERROR_REPLACE)
|
error->code != EGG_REGEX_ERROR_OPTIMIZE &&
|
||||||
g_warning ("%s: unknown error code", G_STRLOC);
|
error->code != EGG_REGEX_ERROR_REPLACE)
|
||||||
|
{
|
||||||
|
g_warning ("%s: unknown error code", G_STRLOC);
|
||||||
|
}
|
||||||
|
|
||||||
msg_text = g_strdup (err->message);
|
msg_text = g_strdup (error->message);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
msg_text = g_strdup_printf ("Invalid regular expression");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!msg_text)
|
dialog = gtk_message_dialog_new (get_parent_window (parent),
|
||||||
msg_text = g_strdup_printf ("Invalid regular expression");
|
GTK_DIALOG_MODAL,
|
||||||
|
|
||||||
parent_window = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (view)));
|
|
||||||
dialog = gtk_message_dialog_new (parent_window, GTK_DIALOG_MODAL,
|
|
||||||
GTK_MESSAGE_ERROR, GTK_BUTTONS_NONE,
|
GTK_MESSAGE_ERROR, GTK_BUTTONS_NONE,
|
||||||
msg_text);
|
msg_text);
|
||||||
gtk_dialog_add_buttons (GTK_DIALOG (dialog), GTK_STOCK_CLOSE,
|
gtk_dialog_add_buttons (GTK_DIALOG (dialog), GTK_STOCK_CLOSE,
|
||||||
|
@ -688,15 +702,12 @@ moo_text_regex_error_dialog (MooTextView *view,
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
moo_text_replaced_n_dialog (MooTextView *view,
|
moo_text_replaced_n_dialog (GtkWidget *parent,
|
||||||
guint n)
|
guint n)
|
||||||
{
|
{
|
||||||
GtkWindow *parent_window;
|
|
||||||
GtkWidget *dialog;
|
GtkWidget *dialog;
|
||||||
char *msg_text;
|
char *msg_text;
|
||||||
|
|
||||||
g_return_if_fail (MOO_IS_TEXT_VIEW (view));
|
|
||||||
|
|
||||||
if (!n)
|
if (!n)
|
||||||
msg_text = g_strdup_printf ("No replacement made");
|
msg_text = g_strdup_printf ("No replacement made");
|
||||||
else if (n == 1)
|
else if (n == 1)
|
||||||
|
@ -704,8 +715,8 @@ moo_text_replaced_n_dialog (MooTextView *view,
|
||||||
else
|
else
|
||||||
msg_text = g_strdup_printf ("%d replacements made", n);
|
msg_text = g_strdup_printf ("%d replacements made", n);
|
||||||
|
|
||||||
parent_window = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (view)));
|
dialog = gtk_message_dialog_new (get_parent_window (parent),
|
||||||
dialog = gtk_message_dialog_new (parent_window, GTK_DIALOG_MODAL,
|
GTK_DIALOG_MODAL,
|
||||||
GTK_MESSAGE_INFO, GTK_BUTTONS_NONE,
|
GTK_MESSAGE_INFO, GTK_BUTTONS_NONE,
|
||||||
msg_text);
|
msg_text);
|
||||||
gtk_dialog_add_buttons (GTK_DIALOG (dialog), GTK_STOCK_CLOSE,
|
gtk_dialog_add_buttons (GTK_DIALOG (dialog), GTK_STOCK_CLOSE,
|
||||||
|
@ -720,22 +731,17 @@ moo_text_replaced_n_dialog (MooTextView *view,
|
||||||
|
|
||||||
|
|
||||||
GtkWidget*
|
GtkWidget*
|
||||||
moo_text_prompt_on_replace_dialog (MooTextView *view)
|
moo_text_prompt_on_replace_dialog (GtkWidget *parent)
|
||||||
{
|
{
|
||||||
GtkWidget *dialog;
|
GtkWidget *dialog;
|
||||||
GtkWindow *parent_window;
|
|
||||||
MooGladeXML *xml;
|
MooGladeXML *xml;
|
||||||
|
|
||||||
g_return_val_if_fail (MOO_IS_TEXT_VIEW (view), NULL);
|
xml = moo_glade_xml_new_from_buf (MOO_TEXT_FIND_GLADE_UI, -1,
|
||||||
|
|
||||||
xml = moo_glade_xml_new_from_buf (MOO_EDIT_FIND_GLADE_UI, -1,
|
|
||||||
"prompt_on_replace_dialog", NULL);
|
"prompt_on_replace_dialog", NULL);
|
||||||
dialog = moo_glade_xml_get_widget (xml, "prompt_on_replace_dialog");
|
dialog = moo_glade_xml_get_widget (xml, "prompt_on_replace_dialog");
|
||||||
moo_glade_xml_unref (xml);
|
moo_glade_xml_unref (xml);
|
||||||
|
|
||||||
parent_window = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (view)));
|
gtk_window_set_transient_for (GTK_WINDOW (dialog), get_parent_window (parent));
|
||||||
|
|
||||||
gtk_window_set_transient_for (GTK_WINDOW (dialog), parent_window);
|
|
||||||
|
|
||||||
return dialog;
|
return dialog;
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,17 +54,19 @@ void moo_edit_reload_error_dialog (GtkWidget *widget,
|
||||||
const char *err_msg);
|
const char *err_msg);
|
||||||
|
|
||||||
|
|
||||||
void moo_text_nothing_found_dialog (MooTextView *view,
|
void moo_text_nothing_found_dialog (GtkWidget *parent,
|
||||||
const char *text,
|
const char *text,
|
||||||
gboolean regex);
|
gboolean regex);
|
||||||
gboolean moo_text_search_from_beginning_dialog
|
gboolean moo_text_search_from_start_dialog (GtkWidget *parent,
|
||||||
(MooTextView *view,
|
|
||||||
gboolean backwards);
|
gboolean backwards);
|
||||||
void moo_text_regex_error_dialog (MooTextView *view,
|
void moo_text_regex_error_dialog (GtkWidget *parent,
|
||||||
GError *error);
|
GError *error);
|
||||||
void moo_text_replaced_n_dialog (MooTextView *view,
|
|
||||||
|
gboolean moo_text_replace_from_start_dialog (GtkWidget *parent,
|
||||||
|
int replaced);
|
||||||
|
void moo_text_replaced_n_dialog (GtkWidget *parent,
|
||||||
guint n);
|
guint n);
|
||||||
GtkWidget *moo_text_prompt_on_replace_dialog (MooTextView *view);
|
GtkWidget *moo_text_prompt_on_replace_dialog (GtkWidget *parent);
|
||||||
|
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
|
@ -1,923 +0,0 @@
|
||||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4; coding: utf-8 -*-
|
|
||||||
*
|
|
||||||
* mooeditfind.c
|
|
||||||
*
|
|
||||||
* Copyright (C) 2004-2005 by Yevgen Muntyan <muntyan@math.tamu.edu>
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* See COPYING file that comes with this distribution.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define MOOEDIT_COMPILATION
|
|
||||||
#include "mooedit/mootextview-private.h"
|
|
||||||
#include "mooedit/mooeditsearch.h"
|
|
||||||
#include "mooedit/mooeditprefs.h"
|
|
||||||
#include "mooedit/mooeditdialogs.h"
|
|
||||||
#include "mooedit/mooeditgotoline-glade.h"
|
|
||||||
#include "mooedit/mooeditfind-glade.h"
|
|
||||||
#include "mooutils/moohistoryentry.h"
|
|
||||||
#include "mooutils/moocompat.h"
|
|
||||||
#include "mooutils/mooglade.h"
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
scroll_to_mark (MooTextView *view,
|
|
||||||
GtkTextMark *mark)
|
|
||||||
{
|
|
||||||
gtk_text_view_scroll_to_mark (GTK_TEXT_VIEW (view), mark, 0.2, FALSE, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************/
|
|
||||||
/* Go to line
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void update_spin_value (GtkRange *scale,
|
|
||||||
GtkSpinButton *spin);
|
|
||||||
static gboolean update_scale_value (GtkSpinButton *spin,
|
|
||||||
GtkRange *scale);
|
|
||||||
|
|
||||||
static void update_spin_value (GtkRange *scale,
|
|
||||||
GtkSpinButton *spin)
|
|
||||||
{
|
|
||||||
double value = gtk_range_get_value (scale);
|
|
||||||
g_signal_handlers_block_matched (spin, G_SIGNAL_MATCH_FUNC, 0, 0, 0,
|
|
||||||
(gpointer)update_scale_value, 0);
|
|
||||||
gtk_spin_button_set_value (spin, value);
|
|
||||||
g_signal_handlers_unblock_matched (spin, G_SIGNAL_MATCH_FUNC, 0, 0, 0,
|
|
||||||
(gpointer)update_scale_value, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean update_scale_value (GtkSpinButton *spin,
|
|
||||||
GtkRange *scale)
|
|
||||||
{
|
|
||||||
double value = gtk_spin_button_get_value (spin);
|
|
||||||
g_signal_handlers_block_matched (scale, G_SIGNAL_MATCH_FUNC, 0, 0, 0,
|
|
||||||
(gpointer)update_spin_value, 0);
|
|
||||||
gtk_range_set_value (scale, value);
|
|
||||||
g_signal_handlers_unblock_matched (scale, G_SIGNAL_MATCH_FUNC, 0, 0, 0,
|
|
||||||
(gpointer)update_spin_value, 0);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
moo_text_view_goto_line (MooTextView *view,
|
|
||||||
int line)
|
|
||||||
{
|
|
||||||
GtkWidget *dialog;
|
|
||||||
GtkTextBuffer *buffer;
|
|
||||||
int line_count;
|
|
||||||
GtkTextIter iter;
|
|
||||||
GtkRange *scale;
|
|
||||||
GtkSpinButton *spin;
|
|
||||||
|
|
||||||
g_return_if_fail (MOO_IS_TEXT_VIEW (view));
|
|
||||||
|
|
||||||
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
|
|
||||||
line_count = gtk_text_buffer_get_line_count (buffer);
|
|
||||||
|
|
||||||
if (line < 0 || line >= line_count)
|
|
||||||
{
|
|
||||||
MooGladeXML *xml;
|
|
||||||
|
|
||||||
xml = moo_glade_xml_new_from_buf (MOO_EDIT_GOTO_LINE_GLADE_UI,
|
|
||||||
-1, NULL, NULL);
|
|
||||||
g_return_if_fail (xml != NULL);
|
|
||||||
|
|
||||||
dialog = moo_glade_xml_get_widget (xml, "dialog");
|
|
||||||
|
|
||||||
#if GTK_CHECK_VERSION(2,6,0)
|
|
||||||
gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
|
|
||||||
GTK_RESPONSE_OK,
|
|
||||||
GTK_RESPONSE_CANCEL,
|
|
||||||
-1);
|
|
||||||
#endif /* GTK_CHECK_VERSION(2,6,0) */
|
|
||||||
|
|
||||||
gtk_text_buffer_get_iter_at_mark (buffer, &iter, gtk_text_buffer_get_insert (buffer));
|
|
||||||
line = gtk_text_iter_get_line (&iter);
|
|
||||||
|
|
||||||
scale = moo_glade_xml_get_widget (xml, "scale");
|
|
||||||
gtk_range_set_range (scale, 1, line_count + 1);
|
|
||||||
gtk_range_set_value (scale, line + 1);
|
|
||||||
|
|
||||||
spin = moo_glade_xml_get_widget (xml, "spin");
|
|
||||||
gtk_entry_set_activates_default (GTK_ENTRY (spin), TRUE);
|
|
||||||
gtk_spin_button_set_range (spin, 1, line_count);
|
|
||||||
gtk_spin_button_set_value (spin, line + 1);
|
|
||||||
gtk_editable_select_region (GTK_EDITABLE (spin), 0, -1);
|
|
||||||
|
|
||||||
g_signal_connect (scale, "value-changed", G_CALLBACK (update_spin_value), spin);
|
|
||||||
g_signal_connect (spin, "value-changed", G_CALLBACK (update_scale_value), scale);
|
|
||||||
|
|
||||||
gtk_window_set_transient_for (GTK_WINDOW (dialog),
|
|
||||||
GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (view))));
|
|
||||||
|
|
||||||
moo_glade_xml_unref (xml);
|
|
||||||
|
|
||||||
if (gtk_dialog_run (GTK_DIALOG (dialog)) != GTK_RESPONSE_OK)
|
|
||||||
{
|
|
||||||
gtk_widget_destroy (dialog);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
line = (int)gtk_spin_button_get_value (spin) - 1;
|
|
||||||
gtk_widget_destroy (dialog);
|
|
||||||
}
|
|
||||||
|
|
||||||
gtk_text_buffer_get_iter_at_line (buffer, &iter, line);
|
|
||||||
gtk_text_buffer_place_cursor (buffer, &iter);
|
|
||||||
scroll_to_mark (view, gtk_text_buffer_get_insert (buffer));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************/
|
|
||||||
/* Search and replace
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void set (GtkWidget *dialog,
|
|
||||||
gboolean regex,
|
|
||||||
gboolean case_sensitive,
|
|
||||||
gboolean whole_words,
|
|
||||||
gboolean from_cursor,
|
|
||||||
gboolean backwards,
|
|
||||||
gboolean selected,
|
|
||||||
gboolean dont_prompt_on_replace);
|
|
||||||
static void get (GtkWidget *dialog,
|
|
||||||
gboolean *regex,
|
|
||||||
gboolean *case_sensitive,
|
|
||||||
gboolean *whole_words,
|
|
||||||
gboolean *from_cursor,
|
|
||||||
gboolean *backwards,
|
|
||||||
gboolean *selected,
|
|
||||||
gboolean *dont_prompt_on_replace);
|
|
||||||
static const char *get_text (GtkWidget *dialog);
|
|
||||||
static const char *get_replace_with (GtkWidget *dialog);
|
|
||||||
static void set_text (GtkWidget *dialog,
|
|
||||||
const char *text);
|
|
||||||
static void set_replace_with (GtkWidget *dialog,
|
|
||||||
const char *text);
|
|
||||||
|
|
||||||
static GtkWidget *create_find_dialog (gboolean replace);
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
MooTextView *view;
|
|
||||||
GtkWidget *dialog;
|
|
||||||
MooTextReplaceResponseType response;
|
|
||||||
} PromptFuncData;
|
|
||||||
|
|
||||||
static MooTextReplaceResponseType prompt_on_replace_func
|
|
||||||
(const char *text,
|
|
||||||
EggRegex *regex,
|
|
||||||
const char *replacement,
|
|
||||||
GtkTextIter *to_replace_start,
|
|
||||||
GtkTextIter *to_replace_end,
|
|
||||||
gpointer data);
|
|
||||||
|
|
||||||
static GtkWidget*
|
|
||||||
create_find_dialog (gboolean replace)
|
|
||||||
{
|
|
||||||
MooGladeXML *xml;
|
|
||||||
GtkWidget *dialog, *replace_frame, *dont_prompt_on_replace;
|
|
||||||
GtkButton *ok_btn;
|
|
||||||
MooHistoryEntry *text_to_find, *replacement_text;
|
|
||||||
|
|
||||||
xml = moo_glade_xml_new_empty ();
|
|
||||||
moo_glade_xml_map_id (xml, "text_to_find", MOO_TYPE_HISTORY_ENTRY);
|
|
||||||
moo_glade_xml_map_id (xml, "replacement_text", MOO_TYPE_HISTORY_ENTRY);
|
|
||||||
moo_glade_xml_parse_memory (xml, MOO_EDIT_FIND_GLADE_UI, -1, "dialog");
|
|
||||||
|
|
||||||
dialog = moo_glade_xml_get_widget (xml, "dialog");
|
|
||||||
g_return_val_if_fail (dialog != NULL, NULL);
|
|
||||||
|
|
||||||
g_object_set_data_full (G_OBJECT (dialog), "moo-dialog-xml",
|
|
||||||
xml, (GDestroyNotify) moo_glade_xml_unref);
|
|
||||||
|
|
||||||
replace_frame = moo_glade_xml_get_widget (xml, "replace_frame");
|
|
||||||
dont_prompt_on_replace = moo_glade_xml_get_widget (xml, "dont_prompt_on_replace");
|
|
||||||
ok_btn = moo_glade_xml_get_widget (xml, "ok_btn");
|
|
||||||
|
|
||||||
text_to_find = moo_glade_xml_get_widget (xml, "text_to_find");
|
|
||||||
replacement_text = moo_glade_xml_get_widget (xml, "replacement_text");
|
|
||||||
moo_history_entry_set_list (text_to_find, _moo_text_search_params->text_to_find_history);
|
|
||||||
moo_history_entry_set_list (replacement_text, _moo_text_search_params->replacement_history);
|
|
||||||
|
|
||||||
if (replace)
|
|
||||||
{
|
|
||||||
gtk_window_set_title (GTK_WINDOW (dialog), "Replace");
|
|
||||||
gtk_widget_show (replace_frame);
|
|
||||||
gtk_widget_show (dont_prompt_on_replace);
|
|
||||||
gtk_button_set_label (ok_btn, GTK_STOCK_FIND_AND_REPLACE);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
gtk_window_set_title (GTK_WINDOW (dialog), "Find");
|
|
||||||
gtk_widget_hide (replace_frame);
|
|
||||||
gtk_widget_hide (dont_prompt_on_replace);
|
|
||||||
gtk_button_set_label (ok_btn, GTK_STOCK_FIND);
|
|
||||||
}
|
|
||||||
|
|
||||||
return dialog;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
_moo_text_view_find (MooTextView *view)
|
|
||||||
{
|
|
||||||
GtkWidget *dialog;
|
|
||||||
gboolean regex, case_sensitive, whole_words, from_cursor, backwards, selected;
|
|
||||||
GtkTextIter sel_start, sel_end;
|
|
||||||
int response;
|
|
||||||
MooTextSearchOptions options;
|
|
||||||
const char *text;
|
|
||||||
GtkTextMark *insert;
|
|
||||||
GtkTextBuffer *buffer;
|
|
||||||
|
|
||||||
g_return_if_fail (MOO_IS_TEXT_VIEW (view));
|
|
||||||
|
|
||||||
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
|
|
||||||
|
|
||||||
regex = _moo_text_search_params->regex;
|
|
||||||
case_sensitive = _moo_text_search_params->case_sensitive;
|
|
||||||
backwards = _moo_text_search_params->backwards;
|
|
||||||
whole_words = _moo_text_search_params->whole_words;
|
|
||||||
from_cursor = _moo_text_search_params->from_cursor;
|
|
||||||
|
|
||||||
selected = FALSE;
|
|
||||||
if (moo_prefs_get_bool (moo_edit_setting (MOO_EDIT_PREFS_SEARCH_SELECTED)) &&
|
|
||||||
gtk_text_buffer_get_selection_bounds (buffer, &sel_start, &sel_end) &&
|
|
||||||
ABS (gtk_text_iter_get_line (&sel_start) - gtk_text_iter_get_line (&sel_end) > 1))
|
|
||||||
selected = TRUE;
|
|
||||||
|
|
||||||
dialog = create_find_dialog (FALSE);
|
|
||||||
set (dialog, regex, case_sensitive, whole_words,
|
|
||||||
from_cursor, backwards, selected, FALSE);
|
|
||||||
|
|
||||||
if (gtk_text_buffer_get_selection_bounds (buffer, &sel_start, &sel_end) &&
|
|
||||||
gtk_text_iter_get_line (&sel_start) == gtk_text_iter_get_line (&sel_end))
|
|
||||||
{
|
|
||||||
char *selection = gtk_text_buffer_get_text (buffer, &sel_start, &sel_end, TRUE);
|
|
||||||
set_text (dialog, selection);
|
|
||||||
g_free (selection);
|
|
||||||
}
|
|
||||||
else if (_moo_text_search_params->text)
|
|
||||||
{
|
|
||||||
set_text (dialog, _moo_text_search_params->text);
|
|
||||||
}
|
|
||||||
|
|
||||||
gtk_window_set_transient_for (GTK_WINDOW (dialog),
|
|
||||||
GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (view))));
|
|
||||||
response = gtk_dialog_run (GTK_DIALOG (dialog));
|
|
||||||
|
|
||||||
if (response != GTK_RESPONSE_OK)
|
|
||||||
{
|
|
||||||
gtk_widget_destroy (dialog);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
get (dialog, ®ex, &case_sensitive, &whole_words,
|
|
||||||
&from_cursor, &backwards, &selected, NULL);
|
|
||||||
|
|
||||||
if (selected)
|
|
||||||
{
|
|
||||||
g_warning ("%s: searching in selected not imlemented\n", G_STRLOC);
|
|
||||||
gtk_widget_destroy (dialog);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_moo_text_search_params->regex = regex;
|
|
||||||
_moo_text_search_params->case_sensitive = case_sensitive;
|
|
||||||
_moo_text_search_params->backwards = backwards;
|
|
||||||
_moo_text_search_params->whole_words = whole_words;
|
|
||||||
_moo_text_search_params->from_cursor = from_cursor;
|
|
||||||
|
|
||||||
_moo_text_search_params->last_search_stamp++;
|
|
||||||
view->priv->last_search_stamp = _moo_text_search_params->last_search_stamp;
|
|
||||||
|
|
||||||
g_free (_moo_text_search_params->text);
|
|
||||||
_moo_text_search_params->text = g_strdup (get_text (dialog));
|
|
||||||
text = _moo_text_search_params->text;
|
|
||||||
gtk_widget_destroy (dialog);
|
|
||||||
|
|
||||||
if (text && text[0])
|
|
||||||
moo_history_list_add (_moo_text_search_params->text_to_find_history, text);
|
|
||||||
|
|
||||||
options = 0;
|
|
||||||
|
|
||||||
if (regex)
|
|
||||||
options |= MOO_TEXT_SEARCH_REGEX;
|
|
||||||
if (backwards)
|
|
||||||
options |= MOO_TEXT_SEARCH_BACKWARDS;
|
|
||||||
if (!case_sensitive)
|
|
||||||
options |= MOO_TEXT_SEARCH_CASE_INSENSITIVE;
|
|
||||||
|
|
||||||
insert = gtk_text_buffer_get_insert (buffer);
|
|
||||||
|
|
||||||
{
|
|
||||||
GtkTextIter start, search_start, limit, match_start, match_end;
|
|
||||||
gboolean result;
|
|
||||||
GError *err = NULL;
|
|
||||||
|
|
||||||
if (from_cursor) {
|
|
||||||
gtk_text_buffer_get_iter_at_mark (buffer, &start, insert);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (backwards)
|
|
||||||
gtk_text_buffer_get_end_iter (buffer, &start);
|
|
||||||
else
|
|
||||||
gtk_text_buffer_get_start_iter (buffer, &start);
|
|
||||||
}
|
|
||||||
|
|
||||||
search_start = start;
|
|
||||||
|
|
||||||
if (backwards)
|
|
||||||
gtk_text_buffer_get_start_iter (buffer, &limit);
|
|
||||||
else
|
|
||||||
gtk_text_buffer_get_end_iter (buffer, &limit);
|
|
||||||
|
|
||||||
result = moo_text_search (&start, &limit, text,
|
|
||||||
&match_start, &match_end, options,
|
|
||||||
&err);
|
|
||||||
if (!result)
|
|
||||||
{
|
|
||||||
if (err) {
|
|
||||||
moo_text_regex_error_dialog (view, err);
|
|
||||||
g_error_free (err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!from_cursor) {
|
|
||||||
moo_text_nothing_found_dialog (view, text, regex);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if ((backwards && gtk_text_iter_is_end (&start)) ||
|
|
||||||
(!backwards && gtk_text_iter_is_start (&start)))
|
|
||||||
{
|
|
||||||
moo_text_nothing_found_dialog (view, text, regex);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!moo_text_search_from_beginning_dialog (view, backwards))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (backwards)
|
|
||||||
gtk_text_buffer_get_end_iter (buffer, &start);
|
|
||||||
else
|
|
||||||
gtk_text_buffer_get_start_iter (buffer, &start);
|
|
||||||
|
|
||||||
limit = search_start;
|
|
||||||
|
|
||||||
result = moo_text_search (&start, &limit, text,
|
|
||||||
&match_start, &match_end, options,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
if (!result) {
|
|
||||||
moo_text_nothing_found_dialog (view, text, regex);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (backwards)
|
|
||||||
gtk_text_iter_order (&match_end, &match_start);
|
|
||||||
|
|
||||||
if (!view->priv->last_found_start) {
|
|
||||||
view->priv->last_found_start =
|
|
||||||
gtk_text_buffer_create_mark (buffer, NULL, &match_start, TRUE);
|
|
||||||
view->priv->last_found_end =
|
|
||||||
gtk_text_buffer_create_mark (buffer, NULL, &match_end, TRUE);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
gtk_text_buffer_move_mark (buffer, view->priv->last_found_start,
|
|
||||||
&match_start);
|
|
||||||
gtk_text_buffer_move_mark (buffer, view->priv->last_found_end,
|
|
||||||
&match_end);
|
|
||||||
}
|
|
||||||
|
|
||||||
gtk_text_buffer_select_range (buffer, &match_end, &match_start);
|
|
||||||
scroll_to_mark (view, insert);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
_moo_text_view_find_next (MooTextView *view)
|
|
||||||
{
|
|
||||||
gboolean regex, case_sensitive, whole_words, backwards;
|
|
||||||
MooTextSearchOptions options;
|
|
||||||
const char *text;
|
|
||||||
GtkTextMark *insert;
|
|
||||||
GtkTextBuffer *buffer;
|
|
||||||
|
|
||||||
g_return_if_fail (MOO_IS_TEXT_VIEW (view));
|
|
||||||
|
|
||||||
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
|
|
||||||
|
|
||||||
if (_moo_text_search_params->last_search_stamp < 0 ||
|
|
||||||
!_moo_text_search_params->text)
|
|
||||||
return moo_text_view_find_interactive (view);
|
|
||||||
|
|
||||||
regex = _moo_text_search_params->regex;
|
|
||||||
case_sensitive = _moo_text_search_params->case_sensitive;
|
|
||||||
backwards = _moo_text_search_params->backwards;
|
|
||||||
whole_words = _moo_text_search_params->whole_words;
|
|
||||||
|
|
||||||
view->priv->last_search_stamp = _moo_text_search_params->last_search_stamp;
|
|
||||||
|
|
||||||
text = _moo_text_search_params->text;
|
|
||||||
|
|
||||||
options = 0;
|
|
||||||
if (regex) options |= MOO_TEXT_SEARCH_REGEX;
|
|
||||||
if (backwards) options |= MOO_TEXT_SEARCH_BACKWARDS;
|
|
||||||
if (!case_sensitive) options |= MOO_TEXT_SEARCH_CASE_INSENSITIVE;
|
|
||||||
|
|
||||||
insert = gtk_text_buffer_get_insert (buffer);
|
|
||||||
|
|
||||||
{
|
|
||||||
GtkTextIter start, search_start, match_start, match_end, limit;
|
|
||||||
gboolean result;
|
|
||||||
|
|
||||||
gtk_text_buffer_get_iter_at_mark (buffer, &start, insert);
|
|
||||||
search_start = start;
|
|
||||||
|
|
||||||
if (backwards)
|
|
||||||
gtk_text_buffer_get_start_iter (buffer, &limit);
|
|
||||||
else
|
|
||||||
gtk_text_buffer_get_end_iter (buffer, &limit);
|
|
||||||
|
|
||||||
result = moo_text_search (&start, &limit, text,
|
|
||||||
&match_start, &match_end, options,
|
|
||||||
NULL);
|
|
||||||
if (!result)
|
|
||||||
{
|
|
||||||
if ((backwards && gtk_text_iter_is_end (&start)) ||
|
|
||||||
(!backwards && gtk_text_iter_is_start (&start)))
|
|
||||||
{
|
|
||||||
moo_text_nothing_found_dialog (view, text, regex);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!moo_text_search_from_beginning_dialog (view, backwards))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (backwards)
|
|
||||||
gtk_text_buffer_get_end_iter (buffer, &start);
|
|
||||||
else
|
|
||||||
gtk_text_buffer_get_start_iter (buffer, &start);
|
|
||||||
|
|
||||||
limit = search_start;
|
|
||||||
|
|
||||||
result = moo_text_search (&start, &search_start, text,
|
|
||||||
&match_start, &match_end, options,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
if (!result) {
|
|
||||||
moo_text_nothing_found_dialog (view, text, regex);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (backwards)
|
|
||||||
gtk_text_iter_order (&match_end, &match_start);
|
|
||||||
|
|
||||||
if (!view->priv->last_found_start) {
|
|
||||||
view->priv->last_found_start =
|
|
||||||
gtk_text_buffer_create_mark (buffer, NULL, &match_start, TRUE);
|
|
||||||
view->priv->last_found_end =
|
|
||||||
gtk_text_buffer_create_mark (buffer, NULL, &match_end, TRUE);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
gtk_text_buffer_move_mark (buffer, view->priv->last_found_start,
|
|
||||||
&match_start);
|
|
||||||
gtk_text_buffer_move_mark (buffer, view->priv->last_found_end,
|
|
||||||
&match_end);
|
|
||||||
}
|
|
||||||
|
|
||||||
gtk_text_buffer_select_range (buffer, &match_end, &match_start);
|
|
||||||
scroll_to_mark (view, insert);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
_moo_text_view_find_previous (MooTextView *view)
|
|
||||||
{
|
|
||||||
gboolean regex, case_sensitive, whole_words, backwards;
|
|
||||||
MooTextSearchOptions options;
|
|
||||||
const char *text;
|
|
||||||
GtkTextMark *insert;
|
|
||||||
GtkTextBuffer *buffer;
|
|
||||||
|
|
||||||
g_return_if_fail (MOO_IS_TEXT_VIEW (view));
|
|
||||||
|
|
||||||
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
|
|
||||||
|
|
||||||
if (_moo_text_search_params->last_search_stamp < 0 ||
|
|
||||||
!_moo_text_search_params->text)
|
|
||||||
return moo_text_view_find_interactive (view);
|
|
||||||
|
|
||||||
regex = _moo_text_search_params->regex;
|
|
||||||
case_sensitive = _moo_text_search_params->case_sensitive;
|
|
||||||
backwards = _moo_text_search_params->backwards;
|
|
||||||
whole_words = _moo_text_search_params->whole_words;
|
|
||||||
|
|
||||||
view->priv->last_search_stamp = _moo_text_search_params->last_search_stamp;
|
|
||||||
|
|
||||||
text = _moo_text_search_params->text;
|
|
||||||
|
|
||||||
options = 0;
|
|
||||||
if (regex) options |= MOO_TEXT_SEARCH_REGEX;
|
|
||||||
if (!backwards) options |= MOO_TEXT_SEARCH_BACKWARDS;
|
|
||||||
if (!case_sensitive) options |= MOO_TEXT_SEARCH_CASE_INSENSITIVE;
|
|
||||||
|
|
||||||
insert = gtk_text_buffer_get_insert (buffer);
|
|
||||||
|
|
||||||
{
|
|
||||||
GtkTextIter start, search_start, match_start, match_end, limit;
|
|
||||||
gboolean result;
|
|
||||||
|
|
||||||
gtk_text_buffer_get_iter_at_mark (buffer, &start, insert);
|
|
||||||
search_start = start;
|
|
||||||
|
|
||||||
if (!backwards)
|
|
||||||
gtk_text_buffer_get_start_iter (buffer, &limit);
|
|
||||||
else
|
|
||||||
gtk_text_buffer_get_end_iter (buffer, &limit);
|
|
||||||
|
|
||||||
result = moo_text_search (&start, &limit, text,
|
|
||||||
&match_start, &match_end, options,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
if (!result)
|
|
||||||
{
|
|
||||||
if ((!backwards && gtk_text_iter_is_end (&start)) ||
|
|
||||||
(backwards && gtk_text_iter_is_start (&start)))
|
|
||||||
{
|
|
||||||
moo_text_nothing_found_dialog (view, text, regex);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!moo_text_search_from_beginning_dialog (view, !backwards))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!backwards)
|
|
||||||
gtk_text_buffer_get_end_iter (buffer, &start);
|
|
||||||
else
|
|
||||||
gtk_text_buffer_get_start_iter (buffer, &start);
|
|
||||||
|
|
||||||
limit = search_start;
|
|
||||||
|
|
||||||
result = moo_text_search (&start, &search_start, text,
|
|
||||||
&match_start, &match_end, options,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
if (!result) {
|
|
||||||
moo_text_nothing_found_dialog (view, text, regex);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!backwards)
|
|
||||||
gtk_text_iter_order (&match_end, &match_start);
|
|
||||||
|
|
||||||
if (!view->priv->last_found_start) {
|
|
||||||
view->priv->last_found_start =
|
|
||||||
gtk_text_buffer_create_mark (buffer, NULL, &match_start, TRUE);
|
|
||||||
view->priv->last_found_end =
|
|
||||||
gtk_text_buffer_create_mark (buffer, NULL, &match_end, TRUE);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
gtk_text_buffer_move_mark (buffer, view->priv->last_found_start,
|
|
||||||
&match_start);
|
|
||||||
gtk_text_buffer_move_mark (buffer, view->priv->last_found_end,
|
|
||||||
&match_end);
|
|
||||||
}
|
|
||||||
|
|
||||||
gtk_text_buffer_select_range (buffer, &match_end, &match_start);
|
|
||||||
scroll_to_mark (view, insert);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
_moo_text_view_replace (MooTextView *view)
|
|
||||||
{
|
|
||||||
GtkWidget *dialog;
|
|
||||||
gboolean regex, case_sensitive, whole_words, from_cursor,
|
|
||||||
backwards, selected, dont_prompt_on_replace;
|
|
||||||
GtkTextIter sel_start, sel_end;
|
|
||||||
MooTextSearchOptions options;
|
|
||||||
const char *text, *replace_with;
|
|
||||||
GtkTextMark *insert;
|
|
||||||
GtkTextBuffer *buffer;
|
|
||||||
|
|
||||||
g_return_if_fail (MOO_IS_TEXT_VIEW (view));
|
|
||||||
|
|
||||||
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
|
|
||||||
|
|
||||||
regex = _moo_text_search_params->regex;
|
|
||||||
case_sensitive = _moo_text_search_params->case_sensitive;
|
|
||||||
backwards = _moo_text_search_params->backwards;
|
|
||||||
whole_words = _moo_text_search_params->whole_words;
|
|
||||||
from_cursor = _moo_text_search_params->from_cursor;
|
|
||||||
dont_prompt_on_replace = _moo_text_search_params->dont_prompt_on_replace;
|
|
||||||
|
|
||||||
selected = FALSE;
|
|
||||||
if (moo_prefs_get_bool (moo_edit_setting (MOO_EDIT_PREFS_SEARCH_SELECTED)) &&
|
|
||||||
gtk_text_buffer_get_selection_bounds (buffer, &sel_start, &sel_end) &&
|
|
||||||
ABS (gtk_text_iter_get_line (&sel_start) - gtk_text_iter_get_line (&sel_end) > 1))
|
|
||||||
selected = TRUE;
|
|
||||||
|
|
||||||
dialog = create_find_dialog (TRUE);
|
|
||||||
set (dialog, regex, case_sensitive, whole_words,
|
|
||||||
from_cursor, backwards, selected, dont_prompt_on_replace);
|
|
||||||
|
|
||||||
if (gtk_text_buffer_get_selection_bounds (buffer, &sel_start, &sel_end) &&
|
|
||||||
gtk_text_iter_get_line (&sel_start) == gtk_text_iter_get_line (&sel_end))
|
|
||||||
{
|
|
||||||
char *selection = gtk_text_buffer_get_text (buffer, &sel_start, &sel_end, TRUE);
|
|
||||||
set_text (dialog, selection);
|
|
||||||
g_free (selection);
|
|
||||||
}
|
|
||||||
else if (_moo_text_search_params->text)
|
|
||||||
{
|
|
||||||
set_text (dialog, _moo_text_search_params->text);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_moo_text_search_params->replace_with)
|
|
||||||
set_replace_with (dialog, _moo_text_search_params->replace_with);
|
|
||||||
|
|
||||||
gtk_window_set_transient_for (GTK_WINDOW (dialog),
|
|
||||||
GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (view))));
|
|
||||||
|
|
||||||
if (gtk_dialog_run (GTK_DIALOG (dialog)) != GTK_RESPONSE_OK)
|
|
||||||
{
|
|
||||||
gtk_widget_destroy (dialog);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
get (dialog, ®ex, &case_sensitive, &whole_words,
|
|
||||||
&from_cursor, &backwards, &selected, &dont_prompt_on_replace);
|
|
||||||
|
|
||||||
if (selected)
|
|
||||||
{
|
|
||||||
g_warning ("%s: searching in selected not imlemented\n", G_STRLOC);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_moo_text_search_params->regex = regex;
|
|
||||||
_moo_text_search_params->case_sensitive = case_sensitive;
|
|
||||||
_moo_text_search_params->backwards = backwards;
|
|
||||||
_moo_text_search_params->whole_words = whole_words;
|
|
||||||
_moo_text_search_params->from_cursor = from_cursor;
|
|
||||||
_moo_text_search_params->dont_prompt_on_replace = dont_prompt_on_replace;
|
|
||||||
|
|
||||||
_moo_text_search_params->last_search_stamp++;
|
|
||||||
view->priv->last_search_stamp = _moo_text_search_params->last_search_stamp;
|
|
||||||
|
|
||||||
g_free (_moo_text_search_params->text);
|
|
||||||
_moo_text_search_params->text = g_strdup (get_text (dialog));
|
|
||||||
text = _moo_text_search_params->text;
|
|
||||||
g_free (_moo_text_search_params->replace_with);
|
|
||||||
_moo_text_search_params->replace_with = g_strdup (get_replace_with (dialog));
|
|
||||||
replace_with = _moo_text_search_params->replace_with;
|
|
||||||
gtk_widget_destroy (dialog);
|
|
||||||
|
|
||||||
if (text && text[0])
|
|
||||||
moo_history_list_add (_moo_text_search_params->text_to_find_history, text);
|
|
||||||
if (replace_with && replace_with[0])
|
|
||||||
moo_history_list_add (_moo_text_search_params->replacement_history, replace_with);
|
|
||||||
|
|
||||||
options = 0;
|
|
||||||
if (regex) options |= MOO_TEXT_SEARCH_REGEX;
|
|
||||||
if (backwards) options |= MOO_TEXT_SEARCH_BACKWARDS;
|
|
||||||
if (!case_sensitive) options |= MOO_TEXT_SEARCH_CASE_INSENSITIVE;
|
|
||||||
|
|
||||||
insert = gtk_text_buffer_get_insert (buffer);
|
|
||||||
|
|
||||||
G_STMT_START {
|
|
||||||
GtkTextIter start, limit;
|
|
||||||
gboolean result;
|
|
||||||
GError *err = NULL;
|
|
||||||
PromptFuncData data = {view, NULL, MOO_TEXT_REPLACE};
|
|
||||||
|
|
||||||
if (from_cursor) {
|
|
||||||
gtk_text_buffer_get_iter_at_mark (buffer, &start, insert);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (backwards)
|
|
||||||
gtk_text_buffer_get_end_iter (buffer, &start);
|
|
||||||
else
|
|
||||||
gtk_text_buffer_get_start_iter (buffer, &start);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (backwards)
|
|
||||||
gtk_text_buffer_get_start_iter (buffer, &limit);
|
|
||||||
else
|
|
||||||
gtk_text_buffer_get_end_iter (buffer, &limit);
|
|
||||||
|
|
||||||
if (!dont_prompt_on_replace) {
|
|
||||||
result = moo_text_replace_all_interactive (&start, &limit, text,
|
|
||||||
replace_with,
|
|
||||||
options, &err,
|
|
||||||
prompt_on_replace_func,
|
|
||||||
&data);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
result = moo_text_replace_all_interactive (&start, &limit, text,
|
|
||||||
replace_with, options,
|
|
||||||
&err, moo_text_replace_func_replace_all,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
g_return_if_fail (result != MOO_TEXT_REPLACE_INVALID_ARGS);
|
|
||||||
|
|
||||||
if (result == MOO_TEXT_REPLACE_REGEX_ERROR || err) {
|
|
||||||
moo_text_regex_error_dialog (view, err);
|
|
||||||
if (err) g_error_free (err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!from_cursor || data.response == MOO_TEXT_REPLACE_STOP) {
|
|
||||||
if (data.dialog) gtk_widget_destroy (data.dialog);
|
|
||||||
moo_text_replaced_n_dialog (view, result);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((backwards && gtk_text_iter_is_end (&start)) ||
|
|
||||||
(!backwards && gtk_text_iter_is_start (&start)))
|
|
||||||
{
|
|
||||||
if (data.dialog) gtk_widget_destroy (data.dialog);
|
|
||||||
moo_text_replaced_n_dialog (view, result);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!moo_text_search_from_beginning_dialog (view, backwards))
|
|
||||||
{
|
|
||||||
if (data.dialog) gtk_widget_destroy (data.dialog);
|
|
||||||
moo_text_replaced_n_dialog (view, result);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
int result2;
|
|
||||||
|
|
||||||
if (backwards)
|
|
||||||
gtk_text_buffer_get_end_iter (buffer, &start);
|
|
||||||
else
|
|
||||||
gtk_text_buffer_get_start_iter (buffer, &start);
|
|
||||||
|
|
||||||
gtk_text_buffer_get_iter_at_mark (buffer, &limit, insert);
|
|
||||||
|
|
||||||
if (!dont_prompt_on_replace)
|
|
||||||
result2 = moo_text_replace_all_interactive (&start, &limit, text,
|
|
||||||
replace_with,
|
|
||||||
options, &err,
|
|
||||||
prompt_on_replace_func,
|
|
||||||
&data);
|
|
||||||
else
|
|
||||||
result2 = moo_text_replace_all_interactive (&start, &limit, text,
|
|
||||||
replace_with, options, &err,
|
|
||||||
moo_text_replace_func_replace_all,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
g_return_if_fail (result2 >= 0);
|
|
||||||
|
|
||||||
if (data.dialog) gtk_widget_destroy (data.dialog);
|
|
||||||
moo_text_replaced_n_dialog (view, result + result2);
|
|
||||||
}
|
|
||||||
} G_STMT_END;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static MooTextReplaceResponseType prompt_on_replace_func
|
|
||||||
(G_GNUC_UNUSED const char *text,
|
|
||||||
G_GNUC_UNUSED EggRegex *regex,
|
|
||||||
G_GNUC_UNUSED const char *replacement,
|
|
||||||
GtkTextIter *to_replace_start,
|
|
||||||
GtkTextIter *to_replace_end,
|
|
||||||
gpointer d)
|
|
||||||
{
|
|
||||||
PromptFuncData *data = (PromptFuncData*) d;
|
|
||||||
GtkTextBuffer *buffer;
|
|
||||||
int response;
|
|
||||||
|
|
||||||
buffer = gtk_text_iter_get_buffer (to_replace_end);
|
|
||||||
gtk_text_buffer_select_range (buffer, to_replace_end, to_replace_start);
|
|
||||||
scroll_to_mark (data->view, gtk_text_buffer_get_insert (buffer));
|
|
||||||
|
|
||||||
if (!data->dialog)
|
|
||||||
data->dialog = moo_text_prompt_on_replace_dialog (data->view);
|
|
||||||
|
|
||||||
response = gtk_dialog_run (GTK_DIALOG (data->dialog));
|
|
||||||
|
|
||||||
if (response == GTK_RESPONSE_DELETE_EVENT ||
|
|
||||||
response == GTK_RESPONSE_CANCEL)
|
|
||||||
data->response = MOO_TEXT_REPLACE_STOP;
|
|
||||||
else
|
|
||||||
data->response = (MooTextReplaceResponseType)response;
|
|
||||||
|
|
||||||
return data->response;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#define GET_WIDGET(name) \
|
|
||||||
GtkWidget *name = moo_glade_xml_get_widget (xml, #name);
|
|
||||||
#define GET_TOGGLE_BUTTON(name) \
|
|
||||||
GtkToggleButton *name = moo_glade_xml_get_widget (xml, #name);
|
|
||||||
|
|
||||||
static void set (GtkWidget *dialog,
|
|
||||||
gboolean regex,
|
|
||||||
gboolean casesensitive,
|
|
||||||
gboolean whole_words,
|
|
||||||
gboolean fromcursor,
|
|
||||||
gboolean backwards,
|
|
||||||
gboolean selected,
|
|
||||||
gboolean dontpromptonreplace)
|
|
||||||
{
|
|
||||||
MooGladeXML *xml = g_object_get_data (G_OBJECT (dialog), "moo-dialog-xml");
|
|
||||||
|
|
||||||
GET_TOGGLE_BUTTON (regular_expression);
|
|
||||||
GET_TOGGLE_BUTTON (case_sensitive);
|
|
||||||
GET_TOGGLE_BUTTON (whole_words_only);
|
|
||||||
GET_TOGGLE_BUTTON (from_cursor);
|
|
||||||
GET_TOGGLE_BUTTON (find_backwards);
|
|
||||||
GET_TOGGLE_BUTTON (selected_text);
|
|
||||||
GET_TOGGLE_BUTTON (dont_prompt_on_replace);
|
|
||||||
|
|
||||||
gtk_toggle_button_set_active (regular_expression, regex);
|
|
||||||
gtk_toggle_button_set_active (case_sensitive, casesensitive);
|
|
||||||
gtk_toggle_button_set_active (whole_words_only, whole_words);
|
|
||||||
gtk_toggle_button_set_active (from_cursor, fromcursor);
|
|
||||||
gtk_toggle_button_set_active (find_backwards, backwards);
|
|
||||||
gtk_toggle_button_set_active (selected_text, selected);
|
|
||||||
gtk_toggle_button_set_active (dont_prompt_on_replace, dontpromptonreplace);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void get (GtkWidget *dialog,
|
|
||||||
gboolean *regex,
|
|
||||||
gboolean *casesensitive,
|
|
||||||
gboolean *whole_words,
|
|
||||||
gboolean *fromcursor,
|
|
||||||
gboolean *backwards,
|
|
||||||
gboolean *selected,
|
|
||||||
gboolean *dontpromptonreplace)
|
|
||||||
{
|
|
||||||
MooGladeXML *xml = g_object_get_data (G_OBJECT (dialog), "moo-dialog-xml");
|
|
||||||
|
|
||||||
GET_TOGGLE_BUTTON (regular_expression);
|
|
||||||
GET_TOGGLE_BUTTON (case_sensitive);
|
|
||||||
GET_TOGGLE_BUTTON (whole_words_only);
|
|
||||||
GET_TOGGLE_BUTTON (from_cursor);
|
|
||||||
GET_TOGGLE_BUTTON (find_backwards);
|
|
||||||
GET_TOGGLE_BUTTON (selected_text);
|
|
||||||
GET_TOGGLE_BUTTON (dont_prompt_on_replace);
|
|
||||||
|
|
||||||
if (regex) *regex = gtk_toggle_button_get_active (regular_expression);
|
|
||||||
if (casesensitive) *casesensitive = gtk_toggle_button_get_active (case_sensitive);
|
|
||||||
if (whole_words) *whole_words = gtk_toggle_button_get_active (whole_words_only);
|
|
||||||
if (fromcursor) *fromcursor = gtk_toggle_button_get_active (from_cursor);
|
|
||||||
if (backwards) *backwards = gtk_toggle_button_get_active (find_backwards);
|
|
||||||
if (selected) *selected = gtk_toggle_button_get_active (selected_text);
|
|
||||||
if (dontpromptonreplace) *dontpromptonreplace = gtk_toggle_button_get_active (dont_prompt_on_replace);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void set_text (GtkWidget *dialog,
|
|
||||||
const char *text)
|
|
||||||
{
|
|
||||||
MooGladeXML *xml = g_object_get_data (G_OBJECT (dialog), "moo-dialog-xml");
|
|
||||||
GET_WIDGET (text_to_find);
|
|
||||||
moo_combo_entry_set_text (MOO_COMBO (text_to_find), text);
|
|
||||||
moo_combo_select_region (MOO_COMBO (text_to_find), 0, -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void set_replace_with (GtkWidget *dialog,
|
|
||||||
const char *text)
|
|
||||||
{
|
|
||||||
MooGladeXML *xml = g_object_get_data (G_OBJECT (dialog), "moo-dialog-xml");
|
|
||||||
GET_WIDGET (replacement_text);
|
|
||||||
moo_combo_entry_set_text (MOO_COMBO (replacement_text), text);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char *get_text (GtkWidget *dialog)
|
|
||||||
{
|
|
||||||
MooGladeXML *xml = g_object_get_data (G_OBJECT (dialog), "moo-dialog-xml");
|
|
||||||
GET_WIDGET (text_to_find);
|
|
||||||
return moo_combo_entry_get_text (MOO_COMBO (text_to_find));
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char *get_replace_with (GtkWidget *dialog)
|
|
||||||
{
|
|
||||||
MooGladeXML *xml = g_object_get_data (G_OBJECT (dialog), "moo-dialog-xml");
|
|
||||||
GET_WIDGET (replacement_text);
|
|
||||||
return moo_combo_entry_get_text (MOO_COMBO (replacement_text));
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,110 +0,0 @@
|
||||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4; coding: utf-8 -*-
|
|
||||||
*
|
|
||||||
* mooeditsearch.h
|
|
||||||
*
|
|
||||||
* Copyright (C) 2004-2005 by Yevgen Muntyan <muntyan@math.tamu.edu>
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* See COPYING file that comes with this distribution.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __MOO_EDIT_SEARCH_H__
|
|
||||||
#define __MOO_EDIT_SEARCH_H__
|
|
||||||
|
|
||||||
#include <mooedit/mooedit.h>
|
|
||||||
#include <mooedit/mootextview.h>
|
|
||||||
#include <mooutils/eggregex.h>
|
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
|
||||||
|
|
||||||
|
|
||||||
#define MOO_TYPE_TEXT_SEARCH_OPTIONS (moo_text_search_options_get_type ())
|
|
||||||
#define MOO_TYPE_TEXT_REPLACE_RESPONSE_TYPE (moo_text_replace_response_type_get_type ())
|
|
||||||
GType moo_text_search_options_get_type (void) G_GNUC_UNUSED;
|
|
||||||
GType moo_text_replace_response_type_get_type (void) G_GNUC_UNUSED;
|
|
||||||
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
MOO_TEXT_SEARCH_BACKWARDS = 1 << 0,
|
|
||||||
MOO_TEXT_SEARCH_CASE_INSENSITIVE = 1 << 1,
|
|
||||||
MOO_TEXT_SEARCH_REGEX = 1 << 2
|
|
||||||
} MooTextSearchOptions;
|
|
||||||
|
|
||||||
|
|
||||||
gboolean moo_text_search (const GtkTextIter *start,
|
|
||||||
const GtkTextIter *limit,
|
|
||||||
const char *text,
|
|
||||||
GtkTextIter *match_start,
|
|
||||||
GtkTextIter *match_end,
|
|
||||||
MooTextSearchOptions options,
|
|
||||||
GError **error);
|
|
||||||
|
|
||||||
gboolean moo_text_search_regex (const GtkTextIter *start,
|
|
||||||
const GtkTextIter *limit,
|
|
||||||
EggRegex *regex,
|
|
||||||
GtkTextIter *match_start,
|
|
||||||
GtkTextIter *match_end,
|
|
||||||
gboolean backwards);
|
|
||||||
|
|
||||||
|
|
||||||
#define MOO_TEXT_REPLACE_INVALID_ARGS ((int)-1)
|
|
||||||
#define MOO_TEXT_REPLACE_REGEX_ERROR ((int)-2)
|
|
||||||
|
|
||||||
/* Do not change numerical values!!! */
|
|
||||||
typedef enum {
|
|
||||||
MOO_TEXT_REPLACE_STOP = 0,
|
|
||||||
MOO_TEXT_REPLACE_AND_STOP = 1,
|
|
||||||
MOO_TEXT_REPLACE_SKIP = 2,
|
|
||||||
MOO_TEXT_REPLACE = 3,
|
|
||||||
MOO_TEXT_REPLACE_ALL = 4
|
|
||||||
} MooTextReplaceResponseType;
|
|
||||||
|
|
||||||
/* replacement is real replacement text when searching for regex */
|
|
||||||
typedef MooTextReplaceResponseType (* MooTextReplaceFunc) (const char *text,
|
|
||||||
EggRegex *regex,
|
|
||||||
const char *replacement,
|
|
||||||
GtkTextIter *to_replace_start,
|
|
||||||
GtkTextIter *to_replace_end,
|
|
||||||
gpointer data);
|
|
||||||
|
|
||||||
MooTextReplaceResponseType moo_text_replace_func_replace_all
|
|
||||||
(const char *text,
|
|
||||||
EggRegex *regex,
|
|
||||||
const char *replacement,
|
|
||||||
GtkTextIter *to_replace_start,
|
|
||||||
GtkTextIter *to_replace_end,
|
|
||||||
gpointer data);
|
|
||||||
|
|
||||||
int moo_text_replace_all_interactive(GtkTextIter *start,
|
|
||||||
GtkTextIter *end,
|
|
||||||
const char *text,
|
|
||||||
const char *replacement,
|
|
||||||
MooTextSearchOptions options,
|
|
||||||
GError **error,
|
|
||||||
MooTextReplaceFunc func,
|
|
||||||
gpointer data);
|
|
||||||
|
|
||||||
int moo_text_replace_regex_all_interactive
|
|
||||||
(GtkTextIter *start,
|
|
||||||
GtkTextIter *end,
|
|
||||||
EggRegex *regex,
|
|
||||||
const char *replacement,
|
|
||||||
gboolean backwards,
|
|
||||||
GError **error,
|
|
||||||
MooTextReplaceFunc func,
|
|
||||||
gpointer data);
|
|
||||||
|
|
||||||
|
|
||||||
void _moo_text_view_find (MooTextView *edit);
|
|
||||||
void _moo_text_view_replace (MooTextView *edit);
|
|
||||||
void _moo_text_view_find_next (MooTextView *edit);
|
|
||||||
void _moo_text_view_find_previous (MooTextView *edit);
|
|
||||||
|
|
||||||
|
|
||||||
G_END_DECLS
|
|
||||||
|
|
||||||
#endif /* __MOO_EDIT_SEARCH_H__ */
|
|
|
@ -483,11 +483,12 @@ moo_rule_regex_new (const char *pattern,
|
||||||
regex = egg_regex_new (pattern, regex_compile_options,
|
regex = egg_regex_new (pattern, regex_compile_options,
|
||||||
regex_match_options, &error);
|
regex_match_options, &error);
|
||||||
|
|
||||||
if (!regex)
|
if (error)
|
||||||
{
|
{
|
||||||
g_warning ("could not compile pattern '%s': %s",
|
g_warning ("could not compile pattern '%s': %s",
|
||||||
pattern, error->message);
|
pattern, error->message);
|
||||||
g_error_free (error);
|
g_error_free (error);
|
||||||
|
egg_regex_unref (regex);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,9 @@ struct _MooTextBufferPrivate {
|
||||||
MooBracketMatchType bracket_found;
|
MooBracketMatchType bracket_found;
|
||||||
|
|
||||||
LineBuffer *line_buf;
|
LineBuffer *line_buf;
|
||||||
|
|
||||||
|
int cursor_moved_frozen;
|
||||||
|
gboolean cursor_moved;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -67,9 +70,15 @@ static void moo_text_buffer_apply_tag (GtkTextBuffer *buffer,
|
||||||
static void moo_text_buffer_delete_range (GtkTextBuffer *buffer,
|
static void moo_text_buffer_delete_range (GtkTextBuffer *buffer,
|
||||||
GtkTextIter *start,
|
GtkTextIter *start,
|
||||||
GtkTextIter *end);
|
GtkTextIter *end);
|
||||||
|
static void moo_text_buffer_begin_user_action (GtkTextBuffer *buffer);
|
||||||
|
static void moo_text_buffer_end_user_action (GtkTextBuffer *buffer);
|
||||||
|
|
||||||
static void moo_text_buffer_queue_highlight (MooTextBuffer *buffer);
|
static void moo_text_buffer_queue_highlight (MooTextBuffer *buffer);
|
||||||
|
|
||||||
|
static void cursor_moved (MooTextBuffer *buffer,
|
||||||
|
const GtkTextIter *iter);
|
||||||
|
static void freeze_cursor_moved (MooTextBuffer *buffer);
|
||||||
|
static void thaw_cursor_moved (MooTextBuffer *buffer);
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
CURSOR_MOVED,
|
CURSOR_MOVED,
|
||||||
|
@ -108,6 +117,8 @@ moo_text_buffer_class_init (MooTextBufferClass *klass)
|
||||||
buffer_class->insert_text = moo_text_buffer_insert_text;
|
buffer_class->insert_text = moo_text_buffer_insert_text;
|
||||||
buffer_class->delete_range = moo_text_buffer_delete_range;
|
buffer_class->delete_range = moo_text_buffer_delete_range;
|
||||||
buffer_class->apply_tag = moo_text_buffer_apply_tag;
|
buffer_class->apply_tag = moo_text_buffer_apply_tag;
|
||||||
|
buffer_class->begin_user_action = moo_text_buffer_begin_user_action;
|
||||||
|
buffer_class->end_user_action = moo_text_buffer_end_user_action;
|
||||||
|
|
||||||
klass->cursor_moved = moo_text_buffer_cursor_moved;
|
klass->cursor_moved = moo_text_buffer_cursor_moved;
|
||||||
|
|
||||||
|
@ -162,7 +173,7 @@ moo_text_buffer_class_init (MooTextBufferClass *klass)
|
||||||
signals[CURSOR_MOVED] =
|
signals[CURSOR_MOVED] =
|
||||||
g_signal_new ("cursor-moved",
|
g_signal_new ("cursor-moved",
|
||||||
G_OBJECT_CLASS_TYPE (klass),
|
G_OBJECT_CLASS_TYPE (klass),
|
||||||
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
|
G_SIGNAL_RUN_LAST,
|
||||||
G_STRUCT_OFFSET (MooTextBufferClass, cursor_moved),
|
G_STRUCT_OFFSET (MooTextBufferClass, cursor_moved),
|
||||||
NULL, NULL,
|
NULL, NULL,
|
||||||
_moo_marshal_VOID__BOXED,
|
_moo_marshal_VOID__BOXED,
|
||||||
|
@ -209,6 +220,20 @@ moo_text_buffer_new (GtkTextTagTable *table)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
moo_text_buffer_begin_user_action (GtkTextBuffer *buffer)
|
||||||
|
{
|
||||||
|
moo_text_buffer_freeze (MOO_TEXT_BUFFER (buffer));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
moo_text_buffer_end_user_action (GtkTextBuffer *buffer)
|
||||||
|
{
|
||||||
|
moo_text_buffer_thaw (MOO_TEXT_BUFFER (buffer));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
moo_text_buffer_mark_set (GtkTextBuffer *text_buffer,
|
moo_text_buffer_mark_set (GtkTextBuffer *text_buffer,
|
||||||
const GtkTextIter *iter,
|
const GtkTextIter *iter,
|
||||||
|
@ -242,7 +267,7 @@ moo_text_buffer_mark_set (GtkTextBuffer *text_buffer,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mark == insert)
|
if (mark == insert)
|
||||||
g_signal_emit (buffer, signals[CURSOR_MOVED], 0, iter);
|
cursor_moved (buffer, iter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -282,7 +307,7 @@ moo_text_buffer_insert_text (GtkTextBuffer *text_buffer,
|
||||||
|
|
||||||
moo_text_buffer_queue_highlight (buffer);
|
moo_text_buffer_queue_highlight (buffer);
|
||||||
|
|
||||||
g_signal_emit (buffer, signals[CURSOR_MOVED], 0, pos);
|
cursor_moved (buffer, pos);
|
||||||
|
|
||||||
if (!buffer->priv->has_text)
|
if (!buffer->priv->has_text)
|
||||||
{
|
{
|
||||||
|
@ -300,11 +325,17 @@ moo_text_buffer_delete_range (GtkTextBuffer *text_buffer,
|
||||||
MooTextBuffer *buffer = MOO_TEXT_BUFFER (text_buffer);
|
MooTextBuffer *buffer = MOO_TEXT_BUFFER (text_buffer);
|
||||||
int first_line, last_line;
|
int first_line, last_line;
|
||||||
|
|
||||||
gtk_text_buffer_remove_all_tags (text_buffer, start, end);
|
|
||||||
|
|
||||||
first_line = gtk_text_iter_get_line (start);
|
first_line = gtk_text_iter_get_line (start);
|
||||||
last_line = gtk_text_iter_get_line (end);
|
last_line = gtk_text_iter_get_line (end);
|
||||||
|
|
||||||
|
#define MANY_LINES 1000
|
||||||
|
if (buffer->priv->lang && buffer->priv->do_highlight &&
|
||||||
|
last_line - first_line > MANY_LINES)
|
||||||
|
{
|
||||||
|
gtk_text_buffer_remove_all_tags (text_buffer, start, end);
|
||||||
|
}
|
||||||
|
#undef MANY_LINES
|
||||||
|
|
||||||
GTK_TEXT_BUFFER_CLASS(moo_text_buffer_parent_class)->delete_range (text_buffer, start, end);
|
GTK_TEXT_BUFFER_CLASS(moo_text_buffer_parent_class)->delete_range (text_buffer, start, end);
|
||||||
|
|
||||||
if (first_line < last_line)
|
if (first_line < last_line)
|
||||||
|
@ -315,7 +346,7 @@ moo_text_buffer_delete_range (GtkTextBuffer *text_buffer,
|
||||||
moo_line_buffer_invalidate (buffer->priv->line_buf, first_line);
|
moo_line_buffer_invalidate (buffer->priv->line_buf, first_line);
|
||||||
moo_text_buffer_queue_highlight (buffer);
|
moo_text_buffer_queue_highlight (buffer);
|
||||||
|
|
||||||
g_signal_emit (buffer, signals[CURSOR_MOVED], 0, start);
|
cursor_moved (buffer, start);
|
||||||
|
|
||||||
if (buffer->priv->has_text)
|
if (buffer->priv->has_text)
|
||||||
{
|
{
|
||||||
|
@ -551,12 +582,60 @@ moo_text_buffer_apply_scheme (MooTextBuffer *buffer,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
moo_text_buffer_freeze (MooTextBuffer *buffer)
|
||||||
|
{
|
||||||
|
g_return_if_fail (MOO_IS_TEXT_BUFFER (buffer));
|
||||||
|
freeze_cursor_moved (buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
moo_text_buffer_thaw (MooTextBuffer *buffer)
|
||||||
|
{
|
||||||
|
g_return_if_fail (MOO_IS_TEXT_BUFFER (buffer));
|
||||||
|
thaw_cursor_moved (buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Matching brackets
|
/* Matching brackets
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define FIND_BRACKETS_LIMIT 10000
|
#define FIND_BRACKETS_LIMIT 10000
|
||||||
|
|
||||||
|
static void
|
||||||
|
cursor_moved (MooTextBuffer *buffer,
|
||||||
|
const GtkTextIter *where)
|
||||||
|
{
|
||||||
|
if (!buffer->priv->cursor_moved_frozen)
|
||||||
|
g_signal_emit (buffer, signals[CURSOR_MOVED], 0, where);
|
||||||
|
else
|
||||||
|
buffer->priv->cursor_moved = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
freeze_cursor_moved (MooTextBuffer *buffer)
|
||||||
|
{
|
||||||
|
buffer->priv->cursor_moved_frozen++;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
thaw_cursor_moved (MooTextBuffer *buffer)
|
||||||
|
{
|
||||||
|
g_return_if_fail (buffer->priv->cursor_moved_frozen > 0);
|
||||||
|
|
||||||
|
if (!--buffer->priv->cursor_moved_frozen && buffer->priv->cursor_moved)
|
||||||
|
{
|
||||||
|
GtkTextIter iter;
|
||||||
|
GtkTextMark *insert = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (buffer));
|
||||||
|
gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (buffer), &iter, insert);
|
||||||
|
cursor_moved (buffer, &iter);
|
||||||
|
buffer->priv->cursor_moved = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
moo_text_buffer_cursor_moved (MooTextBuffer *buffer,
|
moo_text_buffer_cursor_moved (MooTextBuffer *buffer,
|
||||||
const GtkTextIter *where)
|
const GtkTextIter *where)
|
||||||
|
|
|
@ -70,6 +70,9 @@ void moo_text_buffer_set_brackets (MooTextBuffer *buf
|
||||||
void moo_text_buffer_set_check_brackets (MooTextBuffer *buffer,
|
void moo_text_buffer_set_check_brackets (MooTextBuffer *buffer,
|
||||||
gboolean check);
|
gboolean check);
|
||||||
|
|
||||||
|
void moo_text_buffer_freeze (MooTextBuffer *buffer);
|
||||||
|
void moo_text_buffer_thaw (MooTextBuffer *buffer);
|
||||||
|
|
||||||
gboolean moo_text_buffer_has_text (MooTextBuffer *buffer);
|
gboolean moo_text_buffer_has_text (MooTextBuffer *buffer);
|
||||||
gboolean moo_text_buffer_has_selection (MooTextBuffer *buffer);
|
gboolean moo_text_buffer_has_selection (MooTextBuffer *buffer);
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,87 @@
|
||||||
|
/*
|
||||||
|
* mootextfind.h
|
||||||
|
*
|
||||||
|
* Copyright (C) 2004-2005 by Yevgen Muntyan <muntyan@math.tamu.edu>
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* See COPYING file that comes with this distribution.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __MOO_TEXT_FIND_H__
|
||||||
|
#define __MOO_TEXT_FIND_H__
|
||||||
|
|
||||||
|
#include <gtk/gtktextview.h>
|
||||||
|
#include <gtk/gtkdialog.h>
|
||||||
|
#include "mooutils/moohistorylist.h"
|
||||||
|
#include "mooutils/mooglade.h"
|
||||||
|
#include "mooutils/eggregex.h"
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
|
||||||
|
#define MOO_TYPE_FIND (moo_find_get_type ())
|
||||||
|
#define MOO_FIND(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), MOO_TYPE_FIND, MooFind))
|
||||||
|
#define MOO_FIND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MOO_TYPE_FIND, MooFindClass))
|
||||||
|
#define MOO_IS_FIND(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), MOO_TYPE_FIND))
|
||||||
|
#define MOO_IS_FIND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MOO_TYPE_FIND))
|
||||||
|
#define MOO_FIND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MOO_TYPE_FIND, MooFindClass))
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct _MooFind MooFind;
|
||||||
|
typedef struct _MooFindClass MooFindClass;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
MOO_FIND_REGEX = 1 << 0,
|
||||||
|
MOO_FIND_CASELESS = 1 << 1,
|
||||||
|
MOO_FIND_IN_SELECTED = 1 << 2,
|
||||||
|
MOO_FIND_BACKWARDS = 1 << 3,
|
||||||
|
MOO_FIND_WHOLE_WORDS = 1 << 4,
|
||||||
|
MOO_FIND_FROM_CURSOR = 1 << 5,
|
||||||
|
MOO_FIND_DONT_PROMPT = 1 << 6,
|
||||||
|
MOO_FIND_REPL_LITERAL = 1 << 7
|
||||||
|
} MooFindFlags;
|
||||||
|
|
||||||
|
struct _MooFind
|
||||||
|
{
|
||||||
|
GtkDialog base;
|
||||||
|
MooGladeXML *xml;
|
||||||
|
EggRegex *regex;
|
||||||
|
guint replace : 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _MooFindClass
|
||||||
|
{
|
||||||
|
GtkDialogClass base_class;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
GType moo_find_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
|
GtkWidget *moo_find_new (gboolean replace);
|
||||||
|
|
||||||
|
void moo_find_setup (MooFind *find,
|
||||||
|
GtkTextView *view);
|
||||||
|
gboolean moo_find_run (MooFind *find);
|
||||||
|
|
||||||
|
void moo_find_set_flags (MooFind *find,
|
||||||
|
MooFindFlags flags);
|
||||||
|
MooFindFlags moo_find_get_flags (MooFind *find);
|
||||||
|
/* returned string/regex must be freed/unrefed */
|
||||||
|
char *moo_find_get_text (MooFind *find);
|
||||||
|
EggRegex *moo_find_get_regex (MooFind *find);
|
||||||
|
char *moo_find_get_replacement (MooFind *find);
|
||||||
|
|
||||||
|
void moo_text_view_run_find (GtkTextView *view);
|
||||||
|
void moo_text_view_run_replace (GtkTextView *view);
|
||||||
|
void moo_text_view_run_find_next (GtkTextView *view);
|
||||||
|
void moo_text_view_run_find_prev (GtkTextView *view);
|
||||||
|
void moo_text_view_run_goto_line (GtkTextView *view);
|
||||||
|
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __MOO_TEXT_FIND_H__ */
|
|
@ -0,0 +1,842 @@
|
||||||
|
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4; coding: utf-8 -*-
|
||||||
|
*
|
||||||
|
* mootextsearch.c
|
||||||
|
*
|
||||||
|
* Copyright (C) 2004-2005 by Yevgen Muntyan <muntyan@math.tamu.edu>
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* See COPYING file that comes with this distribution.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mooedit/mootextsearch.h"
|
||||||
|
#include "mooedit/gtksourceiter.h"
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
moo_text_search_regex_forward (const GtkTextIter *search_start,
|
||||||
|
const GtkTextIter *search_end,
|
||||||
|
EggRegex *regex,
|
||||||
|
GtkTextIter *match_start,
|
||||||
|
GtkTextIter *match_end,
|
||||||
|
char **string,
|
||||||
|
int *match_offset,
|
||||||
|
int *match_len)
|
||||||
|
{
|
||||||
|
GtkTextIter start, end;
|
||||||
|
GtkTextBuffer *buffer;
|
||||||
|
int start_offset;
|
||||||
|
char *text, *text_start;
|
||||||
|
|
||||||
|
g_return_val_if_fail (search_start != NULL, FALSE);
|
||||||
|
g_return_val_if_fail (match_start != NULL && match_end != NULL, FALSE);
|
||||||
|
g_return_val_if_fail (regex != NULL, FALSE);
|
||||||
|
|
||||||
|
buffer = gtk_text_iter_get_buffer (search_start);
|
||||||
|
|
||||||
|
start = *search_start;
|
||||||
|
start_offset = gtk_text_iter_get_line_offset (&start);
|
||||||
|
if (start_offset)
|
||||||
|
gtk_text_iter_set_line_offset (&start, 0);
|
||||||
|
|
||||||
|
end = *search_start;
|
||||||
|
if (!gtk_text_iter_ends_line (&end))
|
||||||
|
gtk_text_iter_forward_to_line_end (&end);
|
||||||
|
|
||||||
|
while (TRUE)
|
||||||
|
{
|
||||||
|
text = gtk_text_buffer_get_slice (buffer, &start, &end, TRUE);
|
||||||
|
text_start = g_utf8_offset_to_pointer (text, start_offset);
|
||||||
|
|
||||||
|
egg_regex_clear (regex);
|
||||||
|
|
||||||
|
if (egg_regex_match_extended (regex, text, -1, text_start - text, 0) > 0)
|
||||||
|
{
|
||||||
|
int start_pos, end_pos;
|
||||||
|
egg_regex_fetch_pos (regex, text, 0, &start_pos, &end_pos);
|
||||||
|
|
||||||
|
*match_start = start;
|
||||||
|
gtk_text_iter_forward_chars (match_start, g_utf8_pointer_to_offset (text, text + start_pos));
|
||||||
|
|
||||||
|
if (search_end && gtk_text_iter_compare (match_start, search_end) > 0)
|
||||||
|
{
|
||||||
|
g_free (text);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
*match_end = *match_start;
|
||||||
|
gtk_text_iter_forward_chars (match_end, g_utf8_pointer_to_offset (text + start_pos, text + end_pos));
|
||||||
|
|
||||||
|
if (string)
|
||||||
|
*string = text;
|
||||||
|
else
|
||||||
|
g_free (text);
|
||||||
|
|
||||||
|
if (match_offset)
|
||||||
|
*match_offset = start_pos;
|
||||||
|
if (match_len)
|
||||||
|
*match_len = end_pos - start_pos;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
start = end;
|
||||||
|
start_offset = 0;
|
||||||
|
|
||||||
|
if (!gtk_text_iter_forward_line (&start))
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (search_end && gtk_text_iter_compare (&start, search_end) > 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
end = start;
|
||||||
|
|
||||||
|
if (!gtk_text_iter_ends_line (&end))
|
||||||
|
gtk_text_iter_forward_to_line_end (&end);
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
find_last_match (EggRegex *regex,
|
||||||
|
const char *text,
|
||||||
|
EggRegexMatchFlags flags,
|
||||||
|
int *start_pos,
|
||||||
|
int *end_pos)
|
||||||
|
{
|
||||||
|
int len, start;
|
||||||
|
|
||||||
|
*start_pos = -1;
|
||||||
|
egg_regex_clear (regex);
|
||||||
|
len = strlen (text);
|
||||||
|
start = 0;
|
||||||
|
|
||||||
|
while (egg_regex_match_extended (regex, text, len, start, flags) > 0)
|
||||||
|
{
|
||||||
|
egg_regex_fetch_pos (regex, text, 0, start_pos, end_pos);
|
||||||
|
start = *start_pos + 1;
|
||||||
|
if (start >= len)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return *start_pos >= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
moo_text_search_regex_backward (const GtkTextIter *search_start,
|
||||||
|
const GtkTextIter *search_end,
|
||||||
|
EggRegex *regex,
|
||||||
|
GtkTextIter *match_start,
|
||||||
|
GtkTextIter *match_end,
|
||||||
|
char **string,
|
||||||
|
int *match_offset,
|
||||||
|
int *match_len)
|
||||||
|
{
|
||||||
|
GtkTextIter slice_start, slice_end;
|
||||||
|
GtkTextBuffer *buffer;
|
||||||
|
char *text;
|
||||||
|
EggRegexMatchFlags flags;
|
||||||
|
|
||||||
|
g_return_val_if_fail (search_start != NULL, FALSE);
|
||||||
|
g_return_val_if_fail (match_start != NULL && match_end != NULL, FALSE);
|
||||||
|
g_return_val_if_fail (regex != NULL, FALSE);
|
||||||
|
|
||||||
|
buffer = gtk_text_iter_get_buffer (search_start);
|
||||||
|
slice_start = *search_start;
|
||||||
|
slice_end = slice_start;
|
||||||
|
gtk_text_iter_backward_line (&slice_start);
|
||||||
|
flags = 0;
|
||||||
|
|
||||||
|
if (!gtk_text_iter_ends_line (&slice_end))
|
||||||
|
flags |= EGG_REGEX_MATCH_NOTEOL;
|
||||||
|
|
||||||
|
while (TRUE)
|
||||||
|
{
|
||||||
|
int start_pos, end_pos;
|
||||||
|
|
||||||
|
text = gtk_text_buffer_get_slice (buffer, &slice_start, &slice_end, TRUE);
|
||||||
|
|
||||||
|
if (find_last_match (regex, text, flags, &start_pos, &end_pos))
|
||||||
|
{
|
||||||
|
*match_start = slice_start;
|
||||||
|
gtk_text_iter_forward_chars (match_start, g_utf8_pointer_to_offset (text, text + start_pos));
|
||||||
|
|
||||||
|
if (search_end && gtk_text_iter_compare (match_start, search_end) < 0)
|
||||||
|
{
|
||||||
|
g_free (text);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
*match_end = *match_start;
|
||||||
|
gtk_text_iter_forward_chars (match_end, g_utf8_pointer_to_offset (text + start_pos, text + end_pos));
|
||||||
|
|
||||||
|
if (string)
|
||||||
|
*string = text;
|
||||||
|
else
|
||||||
|
g_free (text);
|
||||||
|
|
||||||
|
if (match_offset)
|
||||||
|
*match_offset = start_pos;
|
||||||
|
if (match_len)
|
||||||
|
*match_len = end_pos - start_pos;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
slice_end = slice_start;
|
||||||
|
flags = 0;
|
||||||
|
|
||||||
|
if (gtk_text_iter_is_start (&slice_end))
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (search_end && gtk_text_iter_compare (&slice_end, search_end) < 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
gtk_text_iter_backward_line (&slice_start);
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static EggRegex *
|
||||||
|
get_regex (const char *pattern,
|
||||||
|
MooTextSearchFlags flags,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
static EggRegex *saved_regex;
|
||||||
|
static char *saved_pattern;
|
||||||
|
static MooTextSearchFlags saved_flags;
|
||||||
|
GError *tmp_error = NULL;
|
||||||
|
|
||||||
|
if (!saved_pattern || strcmp (saved_pattern, pattern) || saved_flags != flags)
|
||||||
|
{
|
||||||
|
EggRegexCompileFlags re_flags = 0;
|
||||||
|
|
||||||
|
egg_regex_unref (saved_regex);
|
||||||
|
g_free (saved_pattern);
|
||||||
|
|
||||||
|
saved_pattern = g_strdup (pattern);
|
||||||
|
saved_flags = flags;
|
||||||
|
|
||||||
|
if (flags & MOO_TEXT_SEARCH_CASELESS)
|
||||||
|
re_flags |= EGG_REGEX_CASELESS;
|
||||||
|
|
||||||
|
saved_regex = egg_regex_new (saved_pattern, re_flags, 0, &tmp_error);
|
||||||
|
|
||||||
|
if (tmp_error)
|
||||||
|
{
|
||||||
|
g_free (saved_pattern);
|
||||||
|
saved_pattern = NULL;
|
||||||
|
g_propagate_error (error, tmp_error);
|
||||||
|
egg_regex_unref (saved_regex);
|
||||||
|
saved_regex = NULL;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
egg_regex_optimize (saved_regex, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
return saved_regex;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
is_whole_word (const GtkTextIter *start,
|
||||||
|
const GtkTextIter *end)
|
||||||
|
{
|
||||||
|
GtkTextIter s = *start;
|
||||||
|
GtkTextIter e = *end;
|
||||||
|
|
||||||
|
gtk_text_iter_order (&s, &e);
|
||||||
|
|
||||||
|
if (!gtk_text_iter_starts_line (&s))
|
||||||
|
{
|
||||||
|
gunichar c;
|
||||||
|
gtk_text_iter_backward_char (&s);
|
||||||
|
c = gtk_text_iter_get_char (&s);
|
||||||
|
if (g_unichar_isalnum (c))
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!gtk_text_iter_ends_line (&e))
|
||||||
|
{
|
||||||
|
gunichar c = gtk_text_iter_get_char (&e);
|
||||||
|
if (g_unichar_isalnum (c))
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
moo_text_search_forward (const GtkTextIter *start,
|
||||||
|
const char *str,
|
||||||
|
MooTextSearchFlags flags,
|
||||||
|
GtkTextIter *match_start,
|
||||||
|
GtkTextIter *match_end,
|
||||||
|
const GtkTextIter *end)
|
||||||
|
{
|
||||||
|
EggRegex *regex;
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
g_return_val_if_fail (start != NULL, FALSE);
|
||||||
|
g_return_val_if_fail (str != NULL, FALSE);
|
||||||
|
g_return_val_if_fail (match_start != NULL && match_end != NULL, FALSE);
|
||||||
|
|
||||||
|
if (!(flags & MOO_TEXT_SEARCH_REGEX))
|
||||||
|
{
|
||||||
|
GtkSourceSearchFlags gs_flags = 0;
|
||||||
|
GtkTextIter real_end, real_start;
|
||||||
|
|
||||||
|
if (flags & MOO_TEXT_SEARCH_CASELESS)
|
||||||
|
gs_flags |= GTK_SOURCE_SEARCH_CASE_INSENSITIVE;
|
||||||
|
|
||||||
|
/* http://bugzilla.gnome.org/show_bug.cgi?id=321299 */
|
||||||
|
if (!end || gtk_text_iter_is_end (end))
|
||||||
|
{
|
||||||
|
end = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
real_end = *end;
|
||||||
|
gtk_text_iter_forward_char (&real_end);
|
||||||
|
end = &real_end;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(flags & MOO_TEXT_SEARCH_WHOLE_WORDS))
|
||||||
|
return gtk_source_iter_forward_search (start, str, gs_flags,
|
||||||
|
match_start, match_end, end);
|
||||||
|
|
||||||
|
real_start = *start;
|
||||||
|
|
||||||
|
while (gtk_source_iter_forward_search (&real_start, str, gs_flags,
|
||||||
|
match_start, match_end, end))
|
||||||
|
{
|
||||||
|
if (is_whole_word (match_start, match_end))
|
||||||
|
return TRUE;
|
||||||
|
real_start = *match_end;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
regex = get_regex (str, flags, &error);
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
g_warning ("%s: %s", G_STRLOC, error->message);
|
||||||
|
g_error_free (error);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!regex)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
return moo_text_search_regex_forward (start, end, regex,
|
||||||
|
match_start, match_end,
|
||||||
|
NULL, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
moo_text_search_backward (const GtkTextIter *start,
|
||||||
|
const char *str,
|
||||||
|
MooTextSearchFlags flags,
|
||||||
|
GtkTextIter *match_start,
|
||||||
|
GtkTextIter *match_end,
|
||||||
|
const GtkTextIter *end)
|
||||||
|
{
|
||||||
|
EggRegex *regex;
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
g_return_val_if_fail (start != NULL, FALSE);
|
||||||
|
g_return_val_if_fail (str != NULL, FALSE);
|
||||||
|
g_return_val_if_fail (match_start != NULL && match_end != NULL, FALSE);
|
||||||
|
|
||||||
|
if (!(flags & MOO_TEXT_SEARCH_REGEX))
|
||||||
|
{
|
||||||
|
GtkSourceSearchFlags gs_flags = 0;
|
||||||
|
GtkTextIter real_start;
|
||||||
|
|
||||||
|
if (flags & MOO_TEXT_SEARCH_CASELESS)
|
||||||
|
gs_flags |= GTK_SOURCE_SEARCH_CASE_INSENSITIVE;
|
||||||
|
|
||||||
|
if (!(flags & MOO_TEXT_SEARCH_WHOLE_WORDS))
|
||||||
|
return gtk_source_iter_backward_search (start, str, gs_flags,
|
||||||
|
match_start, match_end, end);
|
||||||
|
|
||||||
|
real_start = *start;
|
||||||
|
|
||||||
|
while (gtk_source_iter_backward_search (&real_start, str, gs_flags,
|
||||||
|
match_start, match_end, end))
|
||||||
|
{
|
||||||
|
if (is_whole_word (match_start, match_end))
|
||||||
|
return TRUE;
|
||||||
|
real_start = *match_start;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
regex = get_regex (str, flags, &error);
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
g_warning ("%s: %s", G_STRLOC, error->message);
|
||||||
|
g_error_free (error);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!regex)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
return moo_text_search_regex_backward (start, end, regex,
|
||||||
|
match_start, match_end,
|
||||||
|
NULL, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
moo_text_replace_regex_all_real (GtkTextIter *start,
|
||||||
|
GtkTextIter *end,
|
||||||
|
EggRegex *regex,
|
||||||
|
const char *replacement,
|
||||||
|
gboolean replacement_literal,
|
||||||
|
MooTextReplaceFunc func,
|
||||||
|
gpointer func_data)
|
||||||
|
{
|
||||||
|
int count = 0;
|
||||||
|
GtkTextMark *end_mark;
|
||||||
|
GtkTextBuffer *buffer;
|
||||||
|
MooTextReplaceResponse response;
|
||||||
|
gboolean need_end_user_action = FALSE;
|
||||||
|
char *freeme = NULL;
|
||||||
|
const char *const_replacement = NULL;
|
||||||
|
GError *error = NULL;
|
||||||
|
gboolean was_zero_match = FALSE;
|
||||||
|
|
||||||
|
g_return_val_if_fail (start != NULL, 0);
|
||||||
|
g_return_val_if_fail (regex != NULL, 0);
|
||||||
|
g_return_val_if_fail (replacement != NULL, 0);
|
||||||
|
|
||||||
|
if (replacement_literal)
|
||||||
|
{
|
||||||
|
const_replacement = replacement;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
freeme = egg_regex_try_eval_replacement (regex, replacement, &error);
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
g_warning ("%s: %s", G_STRLOC, error->message);
|
||||||
|
g_error_free (error);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const_replacement = freeme;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer = gtk_text_iter_get_buffer (start);
|
||||||
|
|
||||||
|
if (end && !gtk_text_iter_is_end (end))
|
||||||
|
{
|
||||||
|
end_mark = gtk_text_buffer_create_mark (buffer, NULL, end, TRUE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
end = NULL;
|
||||||
|
end_mark = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (func)
|
||||||
|
{
|
||||||
|
response = MOO_TEXT_REPLACE_DO_REPLACE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gtk_text_buffer_begin_user_action (buffer);
|
||||||
|
need_end_user_action = TRUE;
|
||||||
|
response = MOO_TEXT_REPLACE_ALL;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (TRUE)
|
||||||
|
{
|
||||||
|
GtkTextIter match_start, match_end;
|
||||||
|
char *freeme_here = NULL;
|
||||||
|
const char *real_replacement;
|
||||||
|
char *string;
|
||||||
|
GError *error = NULL;
|
||||||
|
int match_len;
|
||||||
|
|
||||||
|
if (!moo_text_search_regex_forward (start, end, regex, &match_start, &match_end,
|
||||||
|
&string, NULL, &match_len))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if (!match_len)
|
||||||
|
{
|
||||||
|
if (was_zero_match && gtk_text_iter_equal (&match_start, start))
|
||||||
|
{
|
||||||
|
was_zero_match = FALSE;
|
||||||
|
g_free (string);
|
||||||
|
|
||||||
|
if (!gtk_text_iter_forward_char (start))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
was_zero_match = TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
was_zero_match = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (const_replacement)
|
||||||
|
{
|
||||||
|
real_replacement = const_replacement;
|
||||||
|
g_free (string);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
freeme_here = egg_regex_eval_replacement (regex, string, replacement, &error);
|
||||||
|
g_free (string);
|
||||||
|
|
||||||
|
if (!freeme_here)
|
||||||
|
{
|
||||||
|
g_warning ("%s: %s", G_STRLOC, error->message);
|
||||||
|
g_error_free (error);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
real_replacement = freeme_here;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response != MOO_TEXT_REPLACE_ALL)
|
||||||
|
{
|
||||||
|
response = func (NULL, regex, real_replacement, &match_start, &match_end, func_data);
|
||||||
|
|
||||||
|
if (!response)
|
||||||
|
{
|
||||||
|
g_free (freeme_here);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response != MOO_TEXT_REPLACE_SKIP && (match_len || *real_replacement))
|
||||||
|
{
|
||||||
|
count++;
|
||||||
|
|
||||||
|
if (response == MOO_TEXT_REPLACE_ALL)
|
||||||
|
{
|
||||||
|
if (!need_end_user_action)
|
||||||
|
{
|
||||||
|
gtk_text_buffer_begin_user_action (buffer);
|
||||||
|
need_end_user_action = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gtk_text_buffer_begin_user_action (buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
gtk_text_buffer_delete (buffer, &match_start, &match_end);
|
||||||
|
gtk_text_buffer_insert (buffer, &match_end, real_replacement, -1);
|
||||||
|
|
||||||
|
if (response != MOO_TEXT_REPLACE_ALL)
|
||||||
|
gtk_text_buffer_end_user_action (buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
*start = match_end;
|
||||||
|
|
||||||
|
if (was_zero_match && !*real_replacement)
|
||||||
|
{
|
||||||
|
if (gtk_text_iter_is_end (start))
|
||||||
|
{
|
||||||
|
g_free (freeme_here);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
gtk_text_iter_forward_char (start);
|
||||||
|
was_zero_match = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (end)
|
||||||
|
gtk_text_buffer_get_iter_at_mark (buffer, end, end_mark);
|
||||||
|
|
||||||
|
g_free (freeme_here);
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
if (end_mark)
|
||||||
|
gtk_text_buffer_delete_mark (buffer, end_mark);
|
||||||
|
if (need_end_user_action)
|
||||||
|
gtk_text_buffer_end_user_action (buffer);
|
||||||
|
g_free (freeme);
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
moo_text_replace_regex_all (GtkTextIter *start,
|
||||||
|
GtkTextIter *end,
|
||||||
|
EggRegex *regex,
|
||||||
|
const char *replacement,
|
||||||
|
gboolean replacement_literal)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (start != NULL, 0);
|
||||||
|
g_return_val_if_fail (regex != NULL, 0);
|
||||||
|
g_return_val_if_fail (replacement != NULL, 0);
|
||||||
|
|
||||||
|
return moo_text_replace_regex_all_real (start, end, regex, replacement,
|
||||||
|
replacement_literal, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
moo_text_replace_regex_all_interactive (GtkTextIter *start,
|
||||||
|
GtkTextIter *end,
|
||||||
|
EggRegex *regex,
|
||||||
|
const char *replacement,
|
||||||
|
gboolean replacement_literal,
|
||||||
|
MooTextReplaceFunc func,
|
||||||
|
gpointer func_data)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (start != NULL, 0);
|
||||||
|
g_return_val_if_fail (regex != NULL, 0);
|
||||||
|
g_return_val_if_fail (replacement != NULL, 0);
|
||||||
|
g_return_val_if_fail (func != NULL, 0);
|
||||||
|
|
||||||
|
return moo_text_replace_regex_all_real (start, end, regex,
|
||||||
|
replacement, replacement_literal,
|
||||||
|
func, func_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
moo_text_replace_all (GtkTextIter *start,
|
||||||
|
GtkTextIter *end,
|
||||||
|
const char *text,
|
||||||
|
const char *replacement,
|
||||||
|
MooTextSearchFlags flags)
|
||||||
|
{
|
||||||
|
int count = 0;
|
||||||
|
GtkTextMark *end_mark;
|
||||||
|
GtkTextBuffer *buffer;
|
||||||
|
|
||||||
|
g_return_val_if_fail (start != NULL, 0);
|
||||||
|
g_return_val_if_fail (text != NULL, 0);
|
||||||
|
g_return_val_if_fail (text[0] != 0, 0);
|
||||||
|
g_return_val_if_fail (replacement != NULL, 0);
|
||||||
|
|
||||||
|
if (flags & MOO_TEXT_SEARCH_REGEX)
|
||||||
|
{
|
||||||
|
GError *error = NULL;
|
||||||
|
EggRegex *regex = get_regex (text, flags, &error);
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
g_warning ("%s: %s", G_STRLOC, error->message);
|
||||||
|
g_error_free (error);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!regex)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return moo_text_replace_regex_all (start, end, regex, replacement,
|
||||||
|
flags & MOO_TEXT_SEARCH_REPL_LITERAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer = gtk_text_iter_get_buffer (start);
|
||||||
|
gtk_text_buffer_begin_user_action (buffer);
|
||||||
|
|
||||||
|
if (!end || gtk_text_iter_is_end (end))
|
||||||
|
end = NULL;
|
||||||
|
else
|
||||||
|
gtk_text_iter_forward_char (end);
|
||||||
|
|
||||||
|
if (end)
|
||||||
|
end_mark = gtk_text_buffer_create_mark (buffer, NULL, end, TRUE);
|
||||||
|
else
|
||||||
|
end_mark = NULL;
|
||||||
|
|
||||||
|
while (TRUE)
|
||||||
|
{
|
||||||
|
GtkTextIter match_start, match_end;
|
||||||
|
|
||||||
|
if (!moo_text_search_forward (start, text, flags, &match_start, &match_end, end))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
count++;
|
||||||
|
gtk_text_buffer_delete (buffer, &match_start, &match_end);
|
||||||
|
gtk_text_buffer_insert (buffer, &match_end, replacement, -1);
|
||||||
|
|
||||||
|
*start = match_end;
|
||||||
|
|
||||||
|
if (end)
|
||||||
|
gtk_text_buffer_get_iter_at_mark (buffer, end, end_mark);
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
if (end_mark)
|
||||||
|
gtk_text_buffer_delete_mark (buffer, end_mark);
|
||||||
|
|
||||||
|
gtk_text_buffer_end_user_action (buffer);
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
moo_text_replace_all_interactive (GtkTextIter *start,
|
||||||
|
GtkTextIter *end,
|
||||||
|
const char *text,
|
||||||
|
const char *replacement,
|
||||||
|
MooTextSearchFlags flags,
|
||||||
|
MooTextReplaceFunc func,
|
||||||
|
gpointer func_data)
|
||||||
|
{
|
||||||
|
int count = 0;
|
||||||
|
GtkTextMark *end_mark;
|
||||||
|
GtkTextBuffer *buffer;
|
||||||
|
MooTextReplaceResponse response = MOO_TEXT_REPLACE_DO_REPLACE;
|
||||||
|
gboolean need_end_user_action = FALSE;
|
||||||
|
|
||||||
|
g_return_val_if_fail (start != NULL, 0);
|
||||||
|
g_return_val_if_fail (text != NULL, 0);
|
||||||
|
g_return_val_if_fail (text[0] != 0, 0);
|
||||||
|
g_return_val_if_fail (replacement != NULL, 0);
|
||||||
|
g_return_val_if_fail (func != NULL, 0);
|
||||||
|
|
||||||
|
if (flags & MOO_TEXT_SEARCH_REGEX)
|
||||||
|
{
|
||||||
|
GError *error = NULL;
|
||||||
|
EggRegex *regex = get_regex (text, flags, &error);
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
g_warning ("%s: %s", G_STRLOC, error->message);
|
||||||
|
g_error_free (error);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!regex)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return moo_text_replace_regex_all_interactive (start, end, regex, replacement,
|
||||||
|
flags & MOO_TEXT_SEARCH_REPL_LITERAL,
|
||||||
|
func, func_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer = gtk_text_iter_get_buffer (start);
|
||||||
|
|
||||||
|
if (!end || gtk_text_iter_is_end (end))
|
||||||
|
end = NULL;
|
||||||
|
else
|
||||||
|
gtk_text_iter_forward_char (end);
|
||||||
|
|
||||||
|
if (end)
|
||||||
|
end_mark = gtk_text_buffer_create_mark (buffer, NULL, end, TRUE);
|
||||||
|
else
|
||||||
|
end_mark = NULL;
|
||||||
|
|
||||||
|
while (TRUE)
|
||||||
|
{
|
||||||
|
GtkTextIter match_start, match_end;
|
||||||
|
|
||||||
|
if (!moo_text_search_forward (start, text, flags, &match_start, &match_end, end))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if (response != MOO_TEXT_REPLACE_ALL)
|
||||||
|
{
|
||||||
|
response = func (text, NULL, replacement, &match_start, &match_end, func_data);
|
||||||
|
|
||||||
|
if (!response)
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response != MOO_TEXT_REPLACE_SKIP)
|
||||||
|
{
|
||||||
|
count++;
|
||||||
|
|
||||||
|
if (response == MOO_TEXT_REPLACE_ALL)
|
||||||
|
{
|
||||||
|
if (!need_end_user_action)
|
||||||
|
{
|
||||||
|
gtk_text_buffer_begin_user_action (buffer);
|
||||||
|
need_end_user_action = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gtk_text_buffer_begin_user_action (buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
gtk_text_buffer_delete (buffer, &match_start, &match_end);
|
||||||
|
gtk_text_buffer_insert (buffer, &match_end, replacement, -1);
|
||||||
|
|
||||||
|
if (response != MOO_TEXT_REPLACE_ALL)
|
||||||
|
gtk_text_buffer_end_user_action (buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
*start = match_end;
|
||||||
|
|
||||||
|
if (end)
|
||||||
|
gtk_text_buffer_get_iter_at_mark (buffer, end, end_mark);
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
if (end_mark)
|
||||||
|
gtk_text_buffer_delete_mark (buffer, end_mark);
|
||||||
|
if (need_end_user_action)
|
||||||
|
gtk_text_buffer_end_user_action (buffer);
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
GType
|
||||||
|
moo_text_search_flags_get_type (void)
|
||||||
|
{
|
||||||
|
static GType type = 0;
|
||||||
|
|
||||||
|
if (!type)
|
||||||
|
{
|
||||||
|
static const GFlagsValue values[] = {
|
||||||
|
{ MOO_TEXT_SEARCH_CASELESS, (char*)"MOO_TEXT_SEARCH_CASELESS", (char*)"caseless" },
|
||||||
|
{ MOO_TEXT_SEARCH_REGEX, (char*)"MOO_TEXT_SEARCH_REGEX", (char*)"regex" },
|
||||||
|
{ 0, NULL, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
type = g_flags_register_static ("MooTextSearchFlags", values);
|
||||||
|
}
|
||||||
|
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
GType
|
||||||
|
moo_text_replace_response_get_type (void)
|
||||||
|
{
|
||||||
|
static GType type = 0;
|
||||||
|
|
||||||
|
if (!type)
|
||||||
|
{
|
||||||
|
static const GFlagsValue values[] = {
|
||||||
|
{ MOO_TEXT_REPLACE_STOP, (char*)"MOO_TEXT_REPLACE_STOP", (char*)"stop" },
|
||||||
|
{ MOO_TEXT_REPLACE_SKIP, (char*)"MOO_TEXT_REPLACE_SKIP", (char*)"skip" },
|
||||||
|
{ MOO_TEXT_REPLACE_DO_REPLACE, (char*)"MOO_TEXT_REPLACE_DO_REPLACE", (char*)"do-replace" },
|
||||||
|
{ MOO_TEXT_REPLACE_ALL, (char*)"MOO_TEXT_REPLACE_ALL", (char*)"all" },
|
||||||
|
{ 0, NULL, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
type = g_flags_register_static ("MooTextReplaceResponse", values);
|
||||||
|
}
|
||||||
|
|
||||||
|
return type;
|
||||||
|
}
|
|
@ -0,0 +1,113 @@
|
||||||
|
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4; coding: utf-8 -*-
|
||||||
|
*
|
||||||
|
* mootextsearch.h
|
||||||
|
*
|
||||||
|
* Copyright (C) 2004-2005 by Yevgen Muntyan <muntyan@math.tamu.edu>
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* See COPYING file that comes with this distribution.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __MOO_TEXT_SEARCH_H__
|
||||||
|
#define __MOO_TEXT_SEARCH_H__
|
||||||
|
|
||||||
|
#include <mooedit/mootextiter.h>
|
||||||
|
#include <mooutils/eggregex.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
|
||||||
|
#define MOO_TYPE_TEXT_SEARCH_FLAGS (moo_text_search_flags_get_type ())
|
||||||
|
#define MOO_TYPE_TEXT_REPLACE_RESPONSE (moo_text_replace_response_get_type ())
|
||||||
|
GType moo_text_search_flags_get_type (void) G_GNUC_CONST;
|
||||||
|
GType moo_text_replace_response_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
MOO_TEXT_SEARCH_CASELESS = 1 << 0,
|
||||||
|
MOO_TEXT_SEARCH_REGEX = 1 << 1,
|
||||||
|
MOO_TEXT_SEARCH_WHOLE_WORDS = 1 << 2,
|
||||||
|
MOO_TEXT_SEARCH_REPL_LITERAL = 1 << 3
|
||||||
|
} MooTextSearchFlags;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
MOO_TEXT_REPLACE_STOP = 0,
|
||||||
|
MOO_TEXT_REPLACE_SKIP = 1,
|
||||||
|
MOO_TEXT_REPLACE_DO_REPLACE = 2,
|
||||||
|
MOO_TEXT_REPLACE_ALL = 3
|
||||||
|
} MooTextReplaceResponse;
|
||||||
|
|
||||||
|
/* replacement is evaluated in case of regex */
|
||||||
|
typedef MooTextReplaceResponse (*MooTextReplaceFunc) (const char *text,
|
||||||
|
EggRegex *regex,
|
||||||
|
const char *replacement,
|
||||||
|
const GtkTextIter *to_replace_start,
|
||||||
|
const GtkTextIter *to_replace_end,
|
||||||
|
gpointer user_data);
|
||||||
|
|
||||||
|
|
||||||
|
gboolean moo_text_search_forward (const GtkTextIter *start,
|
||||||
|
const char *str,
|
||||||
|
MooTextSearchFlags flags,
|
||||||
|
GtkTextIter *match_start,
|
||||||
|
GtkTextIter *match_end,
|
||||||
|
const GtkTextIter *end);
|
||||||
|
gboolean moo_text_search_backward (const GtkTextIter *start,
|
||||||
|
const char *str,
|
||||||
|
MooTextSearchFlags flags,
|
||||||
|
GtkTextIter *match_start,
|
||||||
|
GtkTextIter *match_end,
|
||||||
|
const GtkTextIter *end);
|
||||||
|
|
||||||
|
gboolean moo_text_search_regex_forward (const GtkTextIter *start,
|
||||||
|
const GtkTextIter *end,
|
||||||
|
EggRegex *regex,
|
||||||
|
GtkTextIter *match_start,
|
||||||
|
GtkTextIter *match_end,
|
||||||
|
char **string,
|
||||||
|
int *match_offset,
|
||||||
|
int *match_len);
|
||||||
|
gboolean moo_text_search_regex_backward (const GtkTextIter *start,
|
||||||
|
const GtkTextIter *end,
|
||||||
|
EggRegex *regex,
|
||||||
|
GtkTextIter *match_start,
|
||||||
|
GtkTextIter *match_end,
|
||||||
|
char **string,
|
||||||
|
int *match_offset,
|
||||||
|
int *match_len);
|
||||||
|
|
||||||
|
int moo_text_replace_regex_all (GtkTextIter *start,
|
||||||
|
GtkTextIter *end,
|
||||||
|
EggRegex *regex,
|
||||||
|
const char *replacement,
|
||||||
|
gboolean replacement_literal);
|
||||||
|
int moo_text_replace_all (GtkTextIter *start,
|
||||||
|
GtkTextIter *end,
|
||||||
|
const char *text,
|
||||||
|
const char *replacement,
|
||||||
|
MooTextSearchFlags flags);
|
||||||
|
|
||||||
|
int moo_text_replace_regex_all_interactive
|
||||||
|
(GtkTextIter *start,
|
||||||
|
GtkTextIter *end,
|
||||||
|
EggRegex *regex,
|
||||||
|
const char *replacement,
|
||||||
|
gboolean replacement_literal,
|
||||||
|
MooTextReplaceFunc func,
|
||||||
|
gpointer func_data);
|
||||||
|
int moo_text_replace_all_interactive (GtkTextIter *start,
|
||||||
|
GtkTextIter *end,
|
||||||
|
const char *text,
|
||||||
|
const char *replacement,
|
||||||
|
MooTextSearchFlags flags,
|
||||||
|
MooTextReplaceFunc func,
|
||||||
|
gpointer func_data);
|
||||||
|
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __MOO_TEXT_SEARCH_H__ */
|
|
@ -19,7 +19,6 @@
|
||||||
#ifndef __MOO_TEXT_VIEW_PRIVATE_H__
|
#ifndef __MOO_TEXT_VIEW_PRIVATE_H__
|
||||||
#define __MOO_TEXT_VIEW_PRIVATE_H__
|
#define __MOO_TEXT_VIEW_PRIVATE_H__
|
||||||
|
|
||||||
#include "mooedit/mooeditsearch.h"
|
|
||||||
#include "mooedit/mootextview.h"
|
#include "mooedit/mootextview.h"
|
||||||
#include "mooutils/gtksourceundomanager.h"
|
#include "mooutils/gtksourceundomanager.h"
|
||||||
#include "mooutils/moohistorylist.h"
|
#include "mooutils/moohistorylist.h"
|
||||||
|
@ -62,23 +61,6 @@ typedef enum {
|
||||||
} MooTextViewDragType;
|
} MooTextViewDragType;
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
int last_search_stamp;
|
|
||||||
char *text;
|
|
||||||
char *replace_with;
|
|
||||||
gboolean regex;
|
|
||||||
gboolean case_sensitive;
|
|
||||||
gboolean backwards;
|
|
||||||
gboolean whole_words;
|
|
||||||
gboolean from_cursor;
|
|
||||||
gboolean dont_prompt_on_replace;
|
|
||||||
MooHistoryList *text_to_find_history;
|
|
||||||
MooHistoryList *replacement_history;
|
|
||||||
} MooTextSearchParams;
|
|
||||||
|
|
||||||
extern MooTextSearchParams *_moo_text_search_params;
|
|
||||||
|
|
||||||
|
|
||||||
struct _MooTextViewPrivate {
|
struct _MooTextViewPrivate {
|
||||||
gboolean constructed;
|
gboolean constructed;
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include "mooedit/mootextview-private.h"
|
#include "mooedit/mootextview-private.h"
|
||||||
#include "mooedit/mootextview.h"
|
#include "mooedit/mootextview.h"
|
||||||
#include "mooedit/mootextbuffer.h"
|
#include "mooedit/mootextbuffer.h"
|
||||||
|
#include "mooedit/mootextfind.h"
|
||||||
#include "mooutils/moomarshals.h"
|
#include "mooutils/moomarshals.h"
|
||||||
#include "mooutils/mooutils-gobject.h"
|
#include "mooutils/mooutils-gobject.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -23,10 +24,6 @@
|
||||||
#define LIGHT_BLUE "#EEF6FF"
|
#define LIGHT_BLUE "#EEF6FF"
|
||||||
|
|
||||||
|
|
||||||
MooTextSearchParams *_moo_text_search_params;
|
|
||||||
static MooTextSearchParams search_params;
|
|
||||||
|
|
||||||
|
|
||||||
static GObject *moo_text_view_constructor (GType type,
|
static GObject *moo_text_view_constructor (GType type,
|
||||||
guint n_construct_properties,
|
guint n_construct_properties,
|
||||||
GObjectConstructParam *construct_param);
|
GObjectConstructParam *construct_param);
|
||||||
|
@ -60,7 +57,11 @@ static void cursor_moved (MooTextView *view,
|
||||||
static void proxy_prop_notify (MooTextView *view,
|
static void proxy_prop_notify (MooTextView *view,
|
||||||
GParamSpec *pspec);
|
GParamSpec *pspec);
|
||||||
|
|
||||||
static void goto_line (MooTextView *view);
|
static void find_interactive (MooTextView *view);
|
||||||
|
static void replace_interactive (MooTextView *view);
|
||||||
|
static void find_next_interactive (MooTextView *view);
|
||||||
|
static void find_prev_interactive (MooTextView *view);
|
||||||
|
static void goto_line_interactive (MooTextView *view);
|
||||||
|
|
||||||
static void insert_text_cb (MooTextView *view,
|
static void insert_text_cb (MooTextView *view,
|
||||||
GtkTextIter *iter,
|
GtkTextIter *iter,
|
||||||
|
@ -114,11 +115,6 @@ static void moo_text_view_class_init (MooTextViewClass *klass)
|
||||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||||
GtkTextViewClass *text_view_class = GTK_TEXT_VIEW_CLASS (klass);
|
GtkTextViewClass *text_view_class = GTK_TEXT_VIEW_CLASS (klass);
|
||||||
|
|
||||||
_moo_text_search_params = &search_params;
|
|
||||||
search_params.last_search_stamp = -1;
|
|
||||||
search_params.text_to_find_history = moo_history_list_new (NULL);
|
|
||||||
search_params.replacement_history = moo_history_list_new (NULL);
|
|
||||||
|
|
||||||
gobject_class->set_property = moo_text_view_set_property;
|
gobject_class->set_property = moo_text_view_set_property;
|
||||||
gobject_class->get_property = moo_text_view_get_property;
|
gobject_class->get_property = moo_text_view_get_property;
|
||||||
gobject_class->constructor = moo_text_view_constructor;
|
gobject_class->constructor = moo_text_view_constructor;
|
||||||
|
@ -137,11 +133,11 @@ static void moo_text_view_class_init (MooTextViewClass *klass)
|
||||||
|
|
||||||
klass->delete_selection = moo_text_view_delete_selection;
|
klass->delete_selection = moo_text_view_delete_selection;
|
||||||
klass->extend_selection = _moo_text_view_extend_selection;
|
klass->extend_selection = _moo_text_view_extend_selection;
|
||||||
klass->find_interactive = _moo_text_view_find;
|
klass->find_interactive = find_interactive;
|
||||||
klass->find_next_interactive = _moo_text_view_find_next;
|
klass->find_next_interactive = find_next_interactive;
|
||||||
klass->find_prev_interactive = _moo_text_view_find_previous;
|
klass->find_prev_interactive = find_prev_interactive;
|
||||||
klass->replace_interactive = _moo_text_view_replace;
|
klass->replace_interactive = replace_interactive;
|
||||||
klass->goto_line_interactive = goto_line;
|
klass->goto_line_interactive = goto_line_interactive;
|
||||||
klass->undo = moo_text_view_undo;
|
klass->undo = moo_text_view_undo;
|
||||||
klass->redo = moo_text_view_redo;
|
klass->redo = moo_text_view_redo;
|
||||||
klass->char_inserted = moo_text_view_char_inserted;
|
klass->char_inserted = moo_text_view_char_inserted;
|
||||||
|
@ -434,38 +430,34 @@ moo_text_view_delete_selection (MooTextView *view)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
static void
|
||||||
moo_text_view_find_interactive (MooTextView *view)
|
find_interactive (MooTextView *view)
|
||||||
{
|
{
|
||||||
g_return_if_fail (MOO_IS_TEXT_VIEW (view));
|
moo_text_view_run_find (GTK_TEXT_VIEW (view));
|
||||||
g_signal_emit (view, signals[FIND_INTERACTIVE], 0, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
moo_text_view_replace_interactive (MooTextView *view)
|
|
||||||
{
|
|
||||||
g_return_if_fail (MOO_IS_TEXT_VIEW (view));
|
|
||||||
g_signal_emit (view, signals[REPLACE_INTERACTIVE], 0, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
moo_text_view_find_next_interactive (MooTextView *view)
|
|
||||||
{
|
|
||||||
g_return_if_fail (MOO_IS_TEXT_VIEW (view));
|
|
||||||
g_signal_emit (view, signals[FIND_NEXT_INTERACTIVE], 0, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
moo_text_view_find_prev_interactive (MooTextView *view)
|
|
||||||
{
|
|
||||||
g_return_if_fail (MOO_IS_TEXT_VIEW (view));
|
|
||||||
g_signal_emit (view, signals[FIND_PREV_INTERACTIVE], 0, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
goto_line (MooTextView *view)
|
replace_interactive (MooTextView *view)
|
||||||
{
|
{
|
||||||
moo_text_view_goto_line (view, -1);
|
moo_text_view_run_replace (GTK_TEXT_VIEW (view));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
find_next_interactive (MooTextView *view)
|
||||||
|
{
|
||||||
|
moo_text_view_run_find_next (GTK_TEXT_VIEW (view));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
find_prev_interactive (MooTextView *view)
|
||||||
|
{
|
||||||
|
moo_text_view_run_find_prev (GTK_TEXT_VIEW (view));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
goto_line_interactive (MooTextView *view)
|
||||||
|
{
|
||||||
|
moo_text_view_run_goto_line (GTK_TEXT_VIEW (view));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -539,12 +531,12 @@ void
|
||||||
moo_text_view_redo (MooTextView *view)
|
moo_text_view_redo (MooTextView *view)
|
||||||
{
|
{
|
||||||
g_return_if_fail (MOO_IS_TEXT_VIEW (view));
|
g_return_if_fail (MOO_IS_TEXT_VIEW (view));
|
||||||
// _moo_text_buffer_freeze_highlight (get_moo_buffer (view));
|
moo_text_buffer_freeze (get_moo_buffer (view));
|
||||||
gtk_source_undo_manager_redo (view->priv->undo_mgr);
|
gtk_source_undo_manager_redo (view->priv->undo_mgr);
|
||||||
gtk_text_view_scroll_to_mark (GTK_TEXT_VIEW (view),
|
gtk_text_view_scroll_to_mark (GTK_TEXT_VIEW (view),
|
||||||
get_insert (view),
|
get_insert (view),
|
||||||
0, FALSE, 0, 0);
|
0, FALSE, 0, 0);
|
||||||
// _moo_text_buffer_thaw_highlight (get_moo_buffer (view));
|
moo_text_buffer_thaw (get_moo_buffer (view));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -552,12 +544,12 @@ void
|
||||||
moo_text_view_undo (MooTextView *view)
|
moo_text_view_undo (MooTextView *view)
|
||||||
{
|
{
|
||||||
g_return_if_fail (MOO_IS_TEXT_VIEW (view));
|
g_return_if_fail (MOO_IS_TEXT_VIEW (view));
|
||||||
// _moo_text_buffer_freeze_highlight (get_moo_buffer (view));
|
moo_text_buffer_freeze (get_moo_buffer (view));
|
||||||
gtk_source_undo_manager_undo (view->priv->undo_mgr);
|
gtk_source_undo_manager_undo (view->priv->undo_mgr);
|
||||||
gtk_text_view_scroll_to_mark (GTK_TEXT_VIEW (view),
|
gtk_text_view_scroll_to_mark (GTK_TEXT_VIEW (view),
|
||||||
get_insert (view),
|
get_insert (view),
|
||||||
0, FALSE, 0, 0);
|
0, FALSE, 0, 0);
|
||||||
// _moo_text_buffer_thaw_highlight (get_moo_buffer (view));
|
moo_text_buffer_thaw (get_moo_buffer (view));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1436,29 +1428,28 @@ moo_text_view_strip_whitespace (MooTextView *view)
|
||||||
gtk_text_iter_forward_line (&iter))
|
gtk_text_iter_forward_line (&iter))
|
||||||
{
|
{
|
||||||
GtkTextIter end;
|
GtkTextIter end;
|
||||||
|
char *slice, *p;
|
||||||
|
int len;
|
||||||
|
|
||||||
if (gtk_text_iter_ends_line (&iter))
|
if (gtk_text_iter_ends_line (&iter))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
gtk_text_iter_forward_to_line_end (&iter);
|
|
||||||
end = iter;
|
end = iter;
|
||||||
|
gtk_text_iter_forward_to_line_end (&end);
|
||||||
|
|
||||||
do
|
slice = gtk_text_buffer_get_slice (buffer, &iter, &end, TRUE);
|
||||||
|
len = strlen (slice);
|
||||||
|
g_assert (len > 0);
|
||||||
|
|
||||||
|
for (p = slice + len; p > slice && (p[-1] == ' ' || p[-1] == '\t'); --p) ;
|
||||||
|
|
||||||
|
if (*p)
|
||||||
{
|
{
|
||||||
gunichar c;
|
gtk_text_iter_forward_chars (&iter, g_utf8_pointer_to_offset (slice, p));
|
||||||
|
gtk_text_buffer_delete (buffer, &iter, &end);
|
||||||
gtk_text_iter_backward_char (&iter);
|
|
||||||
c = gtk_text_iter_get_char (&iter);
|
|
||||||
|
|
||||||
if (!g_unichar_isspace (c))
|
|
||||||
{
|
|
||||||
gtk_text_iter_forward_char (&iter);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
while (!gtk_text_iter_starts_line (&iter));
|
|
||||||
|
|
||||||
gtk_text_buffer_delete (buffer, &iter, &end);
|
g_free (slice);
|
||||||
}
|
}
|
||||||
|
|
||||||
gtk_text_buffer_end_user_action (buffer);
|
gtk_text_buffer_end_user_action (buffer);
|
||||||
|
|
|
@ -100,10 +100,6 @@ void moo_text_view_undo (MooTextView *view);
|
||||||
void moo_text_view_start_not_undoable_action(MooTextView *view);
|
void moo_text_view_start_not_undoable_action(MooTextView *view);
|
||||||
void moo_text_view_end_not_undoable_action (MooTextView *view);
|
void moo_text_view_end_not_undoable_action (MooTextView *view);
|
||||||
|
|
||||||
void moo_text_view_find_interactive (MooTextView *view);
|
|
||||||
void moo_text_view_replace_interactive (MooTextView *view);
|
|
||||||
void moo_text_view_find_next_interactive (MooTextView *view);
|
|
||||||
void moo_text_view_find_prev_interactive (MooTextView *view);
|
|
||||||
void moo_text_view_goto_line (MooTextView *view,
|
void moo_text_view_goto_line (MooTextView *view,
|
||||||
int line);
|
int line);
|
||||||
|
|
||||||
|
|
|
@ -88,11 +88,11 @@
|
||||||
<context style="Region Marker" eol-context="#pop" name="Region Marker">
|
<context style="Region Marker" eol-context="#pop" name="Region Marker">
|
||||||
</context>
|
</context>
|
||||||
<context style="Comment" eol-context="#pop" name="Commentar 1">
|
<context style="Comment" eol-context="#pop" name="Commentar 1">
|
||||||
<IncludeRules from="##Misc##AlertRules"/>
|
<IncludeRules from="##Misc##CommonCommentRules"/>
|
||||||
</context>
|
</context>
|
||||||
<context style="Comment" eol-context="#stay" name="Commentar 2">
|
<context style="Comment" eol-context="#stay" name="Commentar 2">
|
||||||
<TwoChars style="Comment" context="#pop" char1="*" char2="/" endRegion="Comment"/>
|
<TwoChars style="Comment" context="#pop" char1="*" char2="/" endRegion="Comment"/>
|
||||||
<IncludeRules from="##Misc##AlertRules"/>
|
<IncludeRules from="##Misc##CommonCommentRules"/>
|
||||||
</context>
|
</context>
|
||||||
<context style="Preprocessor" eol-context="#pop" name="Preprocessor">
|
<context style="Preprocessor" eol-context="#pop" name="Preprocessor">
|
||||||
<LineContinue style="Preprocessor" context="#stay"/>
|
<LineContinue style="Preprocessor" context="#stay"/>
|
||||||
|
@ -111,7 +111,7 @@
|
||||||
</context>
|
</context>
|
||||||
<context style="Comment" eol-context="#stay" name="Outscoped" >
|
<context style="Comment" eol-context="#stay" name="Outscoped" >
|
||||||
<TwoChars style="Comment" context="Commentar 2" char1="/" char2="*" beginRegion="Comment"/>
|
<TwoChars style="Comment" context="Commentar 2" char1="/" char2="*" beginRegion="Comment"/>
|
||||||
<IncludeRules from="##Misc##AlertRules"/>
|
<IncludeRules from="##Misc##CommonCommentRules"/>
|
||||||
<Regex style="Comment" context="Outscoped intern" pattern="#\s*if" beginRegion="Outscoped" first-non-blank-only="true"/>
|
<Regex style="Comment" context="Outscoped intern" pattern="#\s*if" beginRegion="Outscoped" first-non-blank-only="true"/>
|
||||||
<Regex style="Preprocessor" context="#pop" pattern="#\s*(endif|else|elif)" endRegion="Outscoped" first-non-blank-only="true"/>
|
<Regex style="Preprocessor" context="#pop" pattern="#\s*(endif|else|elif)" endRegion="Outscoped" first-non-blank-only="true"/>
|
||||||
</context>
|
</context>
|
||||||
|
@ -137,7 +137,6 @@
|
||||||
<style name="Symbol" default-style="Normal"/>
|
<style name="Symbol" default-style="Normal"/>
|
||||||
<style name="Preprocessor" default-style="Others"/>
|
<style name="Preprocessor" default-style="Others"/>
|
||||||
<style name="Prep. Lib" default-style="Others"/> <!--,Qt::darkYellow,Qt::yellow,false,false)); -->
|
<style name="Prep. Lib" default-style="Others"/> <!--,Qt::darkYellow,Qt::yellow,false,false)); -->
|
||||||
<style name="Alert" default-style="Alert"/>
|
|
||||||
<style name="Region Marker" default-style="RegionMarker"/>
|
<style name="Region Marker" default-style="RegionMarker"/>
|
||||||
</styles>
|
</styles>
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,15 @@
|
||||||
<Keyword keyword="Alert" style="Alert"/>
|
<Keyword keyword="Alert" style="Alert"/>
|
||||||
</context>
|
</context>
|
||||||
|
|
||||||
|
<context name="LinkRules">
|
||||||
|
<Regex pattern="http://[^ ]*" style="Link"/>
|
||||||
|
</context>
|
||||||
|
|
||||||
|
<context name="CommonCommentRules">
|
||||||
|
<IncludeRules from="LinkRules"/>
|
||||||
|
<IncludeRules from="AlertRules"/>
|
||||||
|
</context>
|
||||||
|
|
||||||
<context name="ShebangRules">
|
<context name="ShebangRules">
|
||||||
<TwoChars char1="#" char2="!" bol-only="TRUE" first-line-only="TRUE" include-into-next="TRUE" context="Shebang" style="Shebang line"/>
|
<TwoChars char1="#" char2="!" bol-only="TRUE" first-line-only="TRUE" include-into-next="TRUE" context="Shebang" style="Shebang line"/>
|
||||||
</context>
|
</context>
|
||||||
|
@ -21,6 +30,7 @@
|
||||||
|
|
||||||
<styles>
|
<styles>
|
||||||
<style name="Alert" default-style="Alert"/>
|
<style name="Alert" default-style="Alert"/>
|
||||||
|
<style name="Link" underline="TRUE"/>
|
||||||
<style name="Shebang line" default-style="Comment" bold="TRUE" italic="FALSE"/>
|
<style name="Shebang line" default-style="Comment" bold="TRUE" italic="FALSE"/>
|
||||||
</styles>
|
</styles>
|
||||||
</language>
|
</language>
|
||||||
|
|
|
@ -32,7 +32,7 @@ _moo_edit_mod_init (void)
|
||||||
if (!mod)
|
if (!mod)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
// _moo_edit_add_constants (mod, "MOO_");
|
_moo_edit_add_constants (mod, "MOO_");
|
||||||
_moo_edit_register_classes (PyModule_GetDict (mod));
|
_moo_edit_register_classes (PyModule_GetDict (mod));
|
||||||
|
|
||||||
if (!PyErr_Occurred ())
|
if (!PyErr_Occurred ())
|
||||||
|
|
|
@ -149,17 +149,28 @@
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
(define-flags TextSearchOptions
|
(define-flags TextSearchFlags
|
||||||
(in-module "Moo")
|
(in-module "Moo")
|
||||||
(c-name "MooTextSearchOptions")
|
(c-name "MooTextSearchFlags")
|
||||||
(gtype-id "MOO_TYPE_TEXT_SEARCH_OPTIONS")
|
(gtype-id "MOO_TYPE_TEXT_SEARCH_FLAGS")
|
||||||
(values
|
(values
|
||||||
'("backwards" "MOO_TEXT_SEARCH_BACKWARDS")
|
'("caseless" "MOO_TEXT_SEARCH_CASELESS")
|
||||||
'("case-insensitive" "MOO_TEXT_SEARCH_CASE_INSENSITIVE")
|
|
||||||
'("regex" "MOO_TEXT_SEARCH_REGEX")
|
'("regex" "MOO_TEXT_SEARCH_REGEX")
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
(define-flags TextReplaceResponse
|
||||||
|
(in-module "Moo")
|
||||||
|
(c-name "MooTextReplaceResponse")
|
||||||
|
(gtype-id "MOO_TYPE_TEXT_REPLACE_RESPONSE")
|
||||||
|
(values
|
||||||
|
'("stop" "MOO_TEXT_REPLACE_STOP")
|
||||||
|
'("skip" "MOO_TEXT_REPLACE_SKIP")
|
||||||
|
'("do-replace" "MOO_TEXT_REPLACE_DO_REPLACE")
|
||||||
|
'("all" "MOO_TEXT_REPLACE_ALL")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
(define-flags TextStyleMask
|
(define-flags TextStyleMask
|
||||||
(in-module "Moo")
|
(in-module "Moo")
|
||||||
(c-name "MooTextStyleMask")
|
(c-name "MooTextStyleMask")
|
||||||
|
@ -420,80 +431,6 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;; From mooeditsearch.h
|
|
||||||
|
|
||||||
(define-function moo_text_search
|
|
||||||
(c-name "moo_text_search")
|
|
||||||
(return-type "gboolean")
|
|
||||||
(parameters
|
|
||||||
'("const-GtkTextIter*" "start")
|
|
||||||
'("const-GtkTextIter*" "limit")
|
|
||||||
'("const-char*" "text")
|
|
||||||
'("GtkTextIter*" "match_start")
|
|
||||||
'("GtkTextIter*" "match_end")
|
|
||||||
'("MooTextSearchOptions" "options")
|
|
||||||
'("GError**" "error")
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
(define-function moo_text_search_regex
|
|
||||||
(c-name "moo_text_search_regex")
|
|
||||||
(return-type "gboolean")
|
|
||||||
(parameters
|
|
||||||
'("const-GtkTextIter*" "start")
|
|
||||||
'("const-GtkTextIter*" "limit")
|
|
||||||
'("EggRegex*" "regex")
|
|
||||||
'("GtkTextIter*" "match_start")
|
|
||||||
'("GtkTextIter*" "match_end")
|
|
||||||
'("gboolean" "backwards")
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
(define-function moo_text_replace_func_replace_all
|
|
||||||
(c-name "moo_text_replace_func_replace_all")
|
|
||||||
(return-type "MooTextReplaceResponseType")
|
|
||||||
(parameters
|
|
||||||
'("const-char*" "text")
|
|
||||||
'("EggRegex*" "regex")
|
|
||||||
'("const-char*" "replacement")
|
|
||||||
'("GtkTextIter*" "to_replace_start")
|
|
||||||
'("GtkTextIter*" "to_replace_end")
|
|
||||||
'("gpointer" "data")
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
(define-function moo_text_replace_all_interactive
|
|
||||||
(c-name "moo_text_replace_all_interactive")
|
|
||||||
(return-type "int")
|
|
||||||
(parameters
|
|
||||||
'("GtkTextIter*" "start")
|
|
||||||
'("GtkTextIter*" "end")
|
|
||||||
'("const-char*" "text")
|
|
||||||
'("const-char*" "replacement")
|
|
||||||
'("MooTextSearchOptions" "options")
|
|
||||||
'("GError**" "error")
|
|
||||||
'("MooTextReplaceFunc" "func")
|
|
||||||
'("gpointer" "data")
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
(define-function moo_text_replace_regex_all_interactive
|
|
||||||
(c-name "moo_text_replace_regex_all_interactive")
|
|
||||||
(return-type "int")
|
|
||||||
(parameters
|
|
||||||
'("GtkTextIter*" "start")
|
|
||||||
'("GtkTextIter*" "end")
|
|
||||||
'("EggRegex*" "regex")
|
|
||||||
'("const-char*" "replacement")
|
|
||||||
'("gboolean" "backwards")
|
|
||||||
'("GError**" "error")
|
|
||||||
'("MooTextReplaceFunc" "func")
|
|
||||||
'("gpointer" "data")
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;; From mooeditwindow.h
|
;; From mooeditwindow.h
|
||||||
|
|
||||||
(define-method get_active_doc
|
(define-method get_active_doc
|
||||||
|
@ -1148,38 +1085,14 @@
|
||||||
(return-type "none")
|
(return-type "none")
|
||||||
)
|
)
|
||||||
|
|
||||||
(define-method find_interactive
|
;; (define-method goto_line
|
||||||
(of-object "MooTextView")
|
;; (of-object "MooTextView")
|
||||||
(c-name "moo_text_view_find_interactive")
|
;; (c-name "moo_text_view_goto_line")
|
||||||
(return-type "none")
|
;; (return-type "none")
|
||||||
)
|
;; (parameters
|
||||||
|
;; '("int" "line")
|
||||||
(define-method replace_interactive
|
;; )
|
||||||
(of-object "MooTextView")
|
;; )
|
||||||
(c-name "moo_text_view_replace_interactive")
|
|
||||||
(return-type "none")
|
|
||||||
)
|
|
||||||
|
|
||||||
(define-method find_next_interactive
|
|
||||||
(of-object "MooTextView")
|
|
||||||
(c-name "moo_text_view_find_next_interactive")
|
|
||||||
(return-type "none")
|
|
||||||
)
|
|
||||||
|
|
||||||
(define-method find_prev_interactive
|
|
||||||
(of-object "MooTextView")
|
|
||||||
(c-name "moo_text_view_find_prev_interactive")
|
|
||||||
(return-type "none")
|
|
||||||
)
|
|
||||||
|
|
||||||
(define-method goto_line
|
|
||||||
(of-object "MooTextView")
|
|
||||||
(c-name "moo_text_view_goto_line")
|
|
||||||
(return-type "none")
|
|
||||||
(parameters
|
|
||||||
'("int" "line")
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
(define-method set_font_from_string
|
(define-method set_font_from_string
|
||||||
(of-object "MooTextView")
|
(of-object "MooTextView")
|
||||||
|
@ -1278,3 +1191,58 @@
|
||||||
'("MooLang*" "lang" (null-ok))
|
'("MooLang*" "lang" (null-ok))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
;; From mootextsearch.h
|
||||||
|
|
||||||
|
(define-function search_forward
|
||||||
|
(c-name "moo_text_search_forward")
|
||||||
|
(return-type "gboolean")
|
||||||
|
(parameters
|
||||||
|
'("const-GtkTextIter*" "start")
|
||||||
|
'("const-char*" "str")
|
||||||
|
'("MooTextSearchFlags" "flags")
|
||||||
|
'("GtkTextIter*" "match_start")
|
||||||
|
'("GtkTextIter*" "match_end")
|
||||||
|
'("const-GtkTextIter*" "end" (null-ok))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
(define-function search_backward
|
||||||
|
(c-name "moo_text_search_backward")
|
||||||
|
(return-type "gboolean")
|
||||||
|
(parameters
|
||||||
|
'("const-GtkTextIter*" "start")
|
||||||
|
'("const-char*" "str")
|
||||||
|
'("MooTextSearchFlags" "flags")
|
||||||
|
'("GtkTextIter*" "match_start")
|
||||||
|
'("GtkTextIter*" "match_end")
|
||||||
|
'("const-GtkTextIter*" "end" (null-ok))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
(define-function replace_all
|
||||||
|
(c-name "moo_text_replace_all")
|
||||||
|
(return-type "int")
|
||||||
|
(parameters
|
||||||
|
'("GtkTextIter*" "start")
|
||||||
|
'("GtkTextIter*" "end")
|
||||||
|
'("const-char*" "text")
|
||||||
|
'("const-char*" "replacement")
|
||||||
|
'("MooTextSearchFlags" "flags")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
(define-function replace_all_interactive
|
||||||
|
(c-name "moo_text_replace_all_interactive")
|
||||||
|
(return-type "int")
|
||||||
|
(parameters
|
||||||
|
'("GtkTextIter*" "start")
|
||||||
|
'("GtkTextIter*" "end")
|
||||||
|
'("const-char*" "text")
|
||||||
|
'("const-char*" "replacement")
|
||||||
|
'("MooTextSearchFlags" "flags")
|
||||||
|
'("MooTextReplaceFunc" "func")
|
||||||
|
'("gpointer" "data")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
|
@ -4,7 +4,7 @@ headers
|
||||||
#define NO_IMPORT_PYGOBJECT
|
#define NO_IMPORT_PYGOBJECT
|
||||||
#include "pygobject.h"
|
#include "pygobject.h"
|
||||||
#include "mooedit/mooeditor.h"
|
#include "mooedit/mooeditor.h"
|
||||||
#include "mooedit/mooeditsearch.h"
|
#include "mooedit/mootextsearch.h"
|
||||||
#include "mooedit/mootextbuffer.h"
|
#include "mooedit/mootextbuffer.h"
|
||||||
#include "mooedit/moocmdview.h"
|
#include "mooedit/moocmdview.h"
|
||||||
#include "mooedit/mootextiter.h"
|
#include "mooedit/mootextiter.h"
|
||||||
|
@ -185,3 +185,81 @@ _wrap_moo_line_view_get_line_data (PyObject *self, PyObject *args)
|
||||||
g_value_unset (&data);
|
g_value_unset (&data);
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
%%
|
||||||
|
override moo_text_search_forward varargs
|
||||||
|
static PyObject *
|
||||||
|
_wrap_moo_text_search_forward (G_GNUC_UNUSED PyObject *self, PyObject *args)
|
||||||
|
{
|
||||||
|
PyObject *py_start, *py_flags, *py_end = Py_None;
|
||||||
|
char *str;
|
||||||
|
int flags;
|
||||||
|
const GtkTextIter *start, *end = NULL;
|
||||||
|
GtkTextIter match_start, match_end;
|
||||||
|
|
||||||
|
if (!PyArg_ParseTuple(args, (char*) "OsO|O:search_forward", &py_start, &str, &py_flags, &py_end))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (pyg_boxed_check (py_start, GTK_TYPE_TEXT_ITER))
|
||||||
|
start = pyg_boxed_get (py_start, GtkTextIter);
|
||||||
|
else
|
||||||
|
return_TypeErr ("start should be a GtkTextIter");
|
||||||
|
|
||||||
|
if (pyg_flags_get_value (MOO_TYPE_TEXT_SEARCH_FLAGS, py_flags, &flags))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (pyg_boxed_check(py_end, GTK_TYPE_TEXT_ITER))
|
||||||
|
end = pyg_boxed_get(py_end, GtkTextIter);
|
||||||
|
else if (py_end != Py_None)
|
||||||
|
return_TypeErr ("end should be a GtkTextIter or None");
|
||||||
|
|
||||||
|
if (moo_text_search_forward (start, str, flags, &match_start, &match_end, end))
|
||||||
|
{
|
||||||
|
PyObject *ret = PyTuple_New (2);
|
||||||
|
PyTuple_SET_ITEM (ret, 0, pyg_boxed_new (GTK_TYPE_TEXT_ITER, &match_start, TRUE, TRUE));
|
||||||
|
PyTuple_SET_ITEM (ret, 1, pyg_boxed_new (GTK_TYPE_TEXT_ITER, &match_end, TRUE, TRUE));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return_None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
%%
|
||||||
|
override moo_text_search_backward varargs
|
||||||
|
static PyObject *
|
||||||
|
_wrap_moo_text_search_backward (G_GNUC_UNUSED PyObject *self, PyObject *args)
|
||||||
|
{
|
||||||
|
PyObject *py_start, *py_flags, *py_end = Py_None;
|
||||||
|
char *str;
|
||||||
|
int flags;
|
||||||
|
const GtkTextIter *start, *end = NULL;
|
||||||
|
GtkTextIter match_start, match_end;
|
||||||
|
|
||||||
|
if (!PyArg_ParseTuple (args, (char*) "OsO|O:search_backward", &py_start, &str, &py_flags, &py_end))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (pyg_boxed_check (py_start, GTK_TYPE_TEXT_ITER))
|
||||||
|
start = pyg_boxed_get (py_start, GtkTextIter);
|
||||||
|
else
|
||||||
|
return_TypeErr ("start should be a GtkTextIter");
|
||||||
|
|
||||||
|
if (pyg_flags_get_value (MOO_TYPE_TEXT_SEARCH_FLAGS, py_flags, &flags))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (pyg_boxed_check(py_end, GTK_TYPE_TEXT_ITER))
|
||||||
|
end = pyg_boxed_get(py_end, GtkTextIter);
|
||||||
|
else if (py_end != Py_None)
|
||||||
|
return_TypeErr ("end should be a GtkTextIter or None");
|
||||||
|
|
||||||
|
if (moo_text_search_backward (start, str, flags, &match_start, &match_end, end))
|
||||||
|
{
|
||||||
|
PyObject *ret = PyTuple_New (2);
|
||||||
|
PyTuple_SET_ITEM (ret, 0, pyg_boxed_new (GTK_TYPE_TEXT_ITER, &match_start, TRUE, TRUE));
|
||||||
|
PyTuple_SET_ITEM (ret, 1, pyg_boxed_new (GTK_TYPE_TEXT_ITER, &match_end, TRUE, TRUE));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return_None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -159,7 +159,7 @@ egg_regex_new (const gchar *pattern,
|
||||||
void
|
void
|
||||||
egg_regex_unref (EggRegex *regex)
|
egg_regex_unref (EggRegex *regex)
|
||||||
{
|
{
|
||||||
if (--regex->ref_count)
|
if (!regex || --regex->ref_count)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
g_free (regex->pattern);
|
g_free (regex->pattern);
|
||||||
|
@ -172,10 +172,12 @@ egg_regex_unref (EggRegex *regex)
|
||||||
g_free (regex);
|
g_free (regex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
EggRegex *
|
||||||
egg_regex_ref (EggRegex *regex)
|
egg_regex_ref (EggRegex *regex)
|
||||||
{
|
{
|
||||||
++regex->ref_count;
|
if (regex)
|
||||||
|
++regex->ref_count;
|
||||||
|
return regex;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -228,6 +230,8 @@ egg_regex_optimize (EggRegex *regex,
|
||||||
{
|
{
|
||||||
const gchar *errmsg;
|
const gchar *errmsg;
|
||||||
|
|
||||||
|
g_return_if_fail (regex != NULL && regex->regex != NULL);
|
||||||
|
|
||||||
regex->extra = _pcre_study (regex->regex, 0, &errmsg);
|
regex->extra = _pcre_study (regex->regex, 0, &errmsg);
|
||||||
|
|
||||||
if (errmsg)
|
if (errmsg)
|
||||||
|
@ -1115,9 +1119,15 @@ egg_regex_eval_replacement (EggRegex *regex,
|
||||||
GString *result;
|
GString *result;
|
||||||
GList *list;
|
GList *list;
|
||||||
|
|
||||||
|
g_return_val_if_fail (replacement != NULL, NULL);
|
||||||
|
|
||||||
|
if (!*replacement)
|
||||||
|
return g_strdup ("");
|
||||||
|
|
||||||
list = split_replacement (replacement, error);
|
list = split_replacement (replacement, error);
|
||||||
|
|
||||||
if (!list) return NULL;
|
if (!list)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
result = g_string_new (NULL);
|
result = g_string_new (NULL);
|
||||||
interpolate_replacement (regex, string, result, list);
|
interpolate_replacement (regex, string, result, list);
|
||||||
|
@ -1131,19 +1141,107 @@ egg_regex_eval_replacement (EggRegex *regex,
|
||||||
/**
|
/**
|
||||||
* egg_regex_check_replacement:
|
* egg_regex_check_replacement:
|
||||||
* @replacement: replacement string
|
* @replacement: replacement string
|
||||||
|
* @has_references: location for information about references
|
||||||
* @error: location to store error
|
* @error: location to store error
|
||||||
*/
|
*/
|
||||||
gboolean
|
gboolean
|
||||||
egg_regex_check_replacement (const gchar *replacement,
|
egg_regex_check_replacement (const gchar *replacement,
|
||||||
GError **error)
|
gboolean *has_references,
|
||||||
|
GError **error)
|
||||||
{
|
{
|
||||||
GList *list;
|
GList *list, *l;
|
||||||
|
GError *tmp = NULL;
|
||||||
|
|
||||||
list = split_replacement (replacement, error);
|
list = split_replacement (replacement, &tmp);
|
||||||
|
|
||||||
if (!list) return FALSE;
|
if (tmp)
|
||||||
|
{
|
||||||
|
g_propagate_error (error, tmp);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (has_references)
|
||||||
|
{
|
||||||
|
*has_references = FALSE;
|
||||||
|
|
||||||
|
for (l = list; l != NULL; l = l->next)
|
||||||
|
{
|
||||||
|
InterpolationData *data = l->data;
|
||||||
|
|
||||||
|
if (data->type == REPL_TYPE_SYMBOLIC_REFERENCE ||
|
||||||
|
data->type == REPL_TYPE_NUMERIC_REFERENCE)
|
||||||
|
{
|
||||||
|
*has_references = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
g_list_foreach (list, (GFunc)free_interpolation_data, NULL);
|
g_list_foreach (list, (GFunc)free_interpolation_data, NULL);
|
||||||
g_list_free (list);
|
g_list_free (list);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
gchar*
|
||||||
|
egg_regex_try_eval_replacement (EggRegex *regex,
|
||||||
|
const gchar *replacement,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
GList *list, *l;
|
||||||
|
GError *tmp = NULL;
|
||||||
|
GString *string;
|
||||||
|
gboolean result = TRUE;
|
||||||
|
InterpolationData *idata;
|
||||||
|
|
||||||
|
g_return_val_if_fail (regex != NULL, NULL);
|
||||||
|
g_return_val_if_fail (replacement != NULL, NULL);
|
||||||
|
|
||||||
|
if (!*replacement)
|
||||||
|
return g_strdup ("");
|
||||||
|
|
||||||
|
list = split_replacement (replacement, &tmp);
|
||||||
|
|
||||||
|
if (tmp)
|
||||||
|
{
|
||||||
|
g_propagate_error (error, tmp);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!list)
|
||||||
|
return g_strdup ("");
|
||||||
|
|
||||||
|
string = g_string_new (NULL);
|
||||||
|
|
||||||
|
for (l = list; l && result; l = l->next)
|
||||||
|
{
|
||||||
|
idata = l->data;
|
||||||
|
|
||||||
|
switch (idata->type)
|
||||||
|
{
|
||||||
|
case REPL_TYPE_STRING:
|
||||||
|
g_string_append (string, idata->text);
|
||||||
|
break;
|
||||||
|
case REPL_TYPE_CHARACTER:
|
||||||
|
g_string_append_c (string, idata->c);
|
||||||
|
break;
|
||||||
|
case REPL_TYPE_NUMERIC_REFERENCE:
|
||||||
|
case REPL_TYPE_SYMBOLIC_REFERENCE:
|
||||||
|
result = FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g_list_foreach (list, (GFunc) free_interpolation_data, NULL);
|
||||||
|
g_list_free (list);
|
||||||
|
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
return g_string_free (string, FALSE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_string_free (string, TRUE);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -109,7 +109,8 @@ EggRegex *egg_regex_new (const gchar *pattern,
|
||||||
GError **error);
|
GError **error);
|
||||||
void egg_regex_optimize (EggRegex *regex,
|
void egg_regex_optimize (EggRegex *regex,
|
||||||
GError **error);
|
GError **error);
|
||||||
void egg_regex_ref (EggRegex *regex);
|
/* ref() and unref() accept NULL */
|
||||||
|
EggRegex *egg_regex_ref (EggRegex *regex);
|
||||||
void egg_regex_unref (EggRegex *regex);
|
void egg_regex_unref (EggRegex *regex);
|
||||||
void egg_regex_free (EggRegex *regex);
|
void egg_regex_free (EggRegex *regex);
|
||||||
/* FIXME */
|
/* FIXME */
|
||||||
|
@ -169,8 +170,12 @@ gchar *egg_regex_eval_replacement (EggRegex *regex,
|
||||||
const gchar *string,
|
const gchar *string,
|
||||||
const gchar *replacement,
|
const gchar *replacement,
|
||||||
GError **error);
|
GError **error);
|
||||||
gboolean egg_regex_check_replacement (const gchar *replacement,
|
gchar *egg_regex_try_eval_replacement (EggRegex *regex,
|
||||||
GError **error);
|
const gchar *replacement,
|
||||||
|
GError **error);
|
||||||
|
gboolean egg_regex_check_replacement (const gchar *replacement,
|
||||||
|
gboolean *has_references,
|
||||||
|
GError **error);
|
||||||
|
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
|
@ -33,6 +33,8 @@ struct _MooEntryPrivate {
|
||||||
gboolean enable_undo_menu;
|
gboolean enable_undo_menu;
|
||||||
guint user_action_stack;
|
guint user_action_stack;
|
||||||
guint use_ctrl_u : 1;
|
guint use_ctrl_u : 1;
|
||||||
|
guint grab_selection : 1;
|
||||||
|
guint fool_entry : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -50,6 +52,9 @@ static void moo_entry_get_property (GObject *object,
|
||||||
GValue *value,
|
GValue *value,
|
||||||
GParamSpec *pspec);
|
GParamSpec *pspec);
|
||||||
|
|
||||||
|
static gboolean moo_entry_button_release (GtkWidget *widget,
|
||||||
|
GdkEventButton *event);
|
||||||
|
|
||||||
static void moo_entry_delete_to_start (MooEntry *entry);
|
static void moo_entry_delete_to_start (MooEntry *entry);
|
||||||
|
|
||||||
static void moo_entry_populate_popup (GtkEntry *entry,
|
static void moo_entry_populate_popup (GtkEntry *entry,
|
||||||
|
@ -78,6 +83,13 @@ static void moo_entry_insert_text (GtkEditable *editable,
|
||||||
static void moo_entry_delete_text (GtkEditable *editable,
|
static void moo_entry_delete_text (GtkEditable *editable,
|
||||||
gint start_pos,
|
gint start_pos,
|
||||||
gint end_pos);
|
gint end_pos);
|
||||||
|
static void moo_entry_set_selection_bounds (GtkEditable *editable,
|
||||||
|
gint start_pos,
|
||||||
|
gint end_pos);
|
||||||
|
static gboolean moo_entry_get_selection_bounds (GtkEditable *editable,
|
||||||
|
gint *start_pos,
|
||||||
|
gint *end_pos);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GType
|
GType
|
||||||
|
@ -120,7 +132,8 @@ enum {
|
||||||
PROP_0,
|
PROP_0,
|
||||||
PROP_UNDO_MANAGER,
|
PROP_UNDO_MANAGER,
|
||||||
PROP_ENABLE_UNDO,
|
PROP_ENABLE_UNDO,
|
||||||
PROP_ENABLE_UNDO_MENU
|
PROP_ENABLE_UNDO_MENU,
|
||||||
|
PROP_GRAB_SELECTION
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
@ -140,6 +153,7 @@ static void
|
||||||
moo_entry_class_init (MooEntryClass *klass)
|
moo_entry_class_init (MooEntryClass *klass)
|
||||||
{
|
{
|
||||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||||
|
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||||
GtkEntryClass *entry_class = GTK_ENTRY_CLASS (klass);
|
GtkEntryClass *entry_class = GTK_ENTRY_CLASS (klass);
|
||||||
GtkBindingSet *binding_set;
|
GtkBindingSet *binding_set;
|
||||||
|
|
||||||
|
@ -147,6 +161,8 @@ moo_entry_class_init (MooEntryClass *klass)
|
||||||
gobject_class->set_property = moo_entry_set_property;
|
gobject_class->set_property = moo_entry_set_property;
|
||||||
gobject_class->get_property = moo_entry_get_property;
|
gobject_class->get_property = moo_entry_get_property;
|
||||||
|
|
||||||
|
widget_class->button_release_event = moo_entry_button_release;
|
||||||
|
|
||||||
entry_class->populate_popup = moo_entry_populate_popup;
|
entry_class->populate_popup = moo_entry_populate_popup;
|
||||||
entry_class->insert_at_cursor = moo_entry_insert_at_cursor;
|
entry_class->insert_at_cursor = moo_entry_insert_at_cursor;
|
||||||
entry_class->delete_from_cursor = moo_entry_delete_from_cursor;
|
entry_class->delete_from_cursor = moo_entry_delete_from_cursor;
|
||||||
|
@ -184,6 +200,14 @@ moo_entry_class_init (MooEntryClass *klass)
|
||||||
TRUE,
|
TRUE,
|
||||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
|
G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
|
||||||
|
|
||||||
|
g_object_class_install_property (gobject_class,
|
||||||
|
PROP_GRAB_SELECTION,
|
||||||
|
g_param_spec_boolean ("grab-selection",
|
||||||
|
"grab-selection",
|
||||||
|
"grab-selection",
|
||||||
|
FALSE,
|
||||||
|
G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
|
||||||
|
|
||||||
signals[UNDO] =
|
signals[UNDO] =
|
||||||
g_signal_new ("undo",
|
g_signal_new ("undo",
|
||||||
G_OBJECT_CLASS_TYPE (klass),
|
G_OBJECT_CLASS_TYPE (klass),
|
||||||
|
@ -249,6 +273,8 @@ moo_entry_editable_init (GtkEditableClass *klass)
|
||||||
klass->do_delete_text = moo_entry_do_delete_text;
|
klass->do_delete_text = moo_entry_do_delete_text;
|
||||||
klass->insert_text = moo_entry_insert_text;
|
klass->insert_text = moo_entry_insert_text;
|
||||||
klass->delete_text = moo_entry_delete_text;
|
klass->delete_text = moo_entry_delete_text;
|
||||||
|
klass->set_selection_bounds = moo_entry_set_selection_bounds;
|
||||||
|
klass->get_selection_bounds = moo_entry_get_selection_bounds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -281,6 +307,11 @@ moo_entry_set_property (GObject *object,
|
||||||
g_object_notify (object, "enable-undo-menu");
|
g_object_notify (object, "enable-undo-menu");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PROP_GRAB_SELECTION:
|
||||||
|
entry->priv->grab_selection = g_value_get_boolean (value) ? TRUE : FALSE;
|
||||||
|
g_object_notify (object, "grab-selection");
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
@ -310,6 +341,10 @@ moo_entry_get_property (GObject *object,
|
||||||
g_value_set_object (value, entry->priv->undo_mgr);
|
g_value_set_object (value, entry->priv->undo_mgr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PROP_GRAB_SELECTION:
|
||||||
|
g_value_set_boolean (value, entry->priv->grab_selection ? TRUE : FALSE);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
@ -518,3 +553,48 @@ moo_entry_delete_to_start (MooEntry *entry)
|
||||||
gtk_editable_delete_text (GTK_EDITABLE (entry),
|
gtk_editable_delete_text (GTK_EDITABLE (entry),
|
||||||
0, gtk_editable_get_position (GTK_EDITABLE (entry)));
|
0, gtk_editable_get_position (GTK_EDITABLE (entry)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*********************************************************************/
|
||||||
|
/* Working around gtk idiotic selection business
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* GtkEdiatble::delete_text and GtkWidget::realize might also require this hack */
|
||||||
|
|
||||||
|
static void
|
||||||
|
moo_entry_set_selection_bounds (GtkEditable *editable,
|
||||||
|
gint start_pos,
|
||||||
|
gint end_pos)
|
||||||
|
{
|
||||||
|
if (!MOO_ENTRY(editable)->priv->grab_selection)
|
||||||
|
MOO_ENTRY(editable)->priv->fool_entry = TRUE;
|
||||||
|
|
||||||
|
parent_editable_iface->set_selection_bounds (editable, start_pos, end_pos);
|
||||||
|
MOO_ENTRY(editable)->priv->fool_entry = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
moo_entry_get_selection_bounds (GtkEditable *editable,
|
||||||
|
gint *start_pos,
|
||||||
|
gint *end_pos)
|
||||||
|
{
|
||||||
|
if (MOO_ENTRY(editable)->priv->fool_entry)
|
||||||
|
return FALSE;
|
||||||
|
else
|
||||||
|
return parent_editable_iface->get_selection_bounds (editable, start_pos, end_pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
moo_entry_button_release (GtkWidget *widget,
|
||||||
|
GdkEventButton *event)
|
||||||
|
{
|
||||||
|
gboolean result;
|
||||||
|
|
||||||
|
if (!MOO_ENTRY(widget)->priv->grab_selection)
|
||||||
|
MOO_ENTRY(widget)->priv->fool_entry = TRUE;
|
||||||
|
|
||||||
|
result = GTK_WIDGET_CLASS(moo_entry_parent_class)->button_release_event (widget, event);
|
||||||
|
MOO_ENTRY(widget)->priv->fool_entry = FALSE;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue