xed/xedit/xedit-commands-search.c

794 lines
20 KiB
C
Raw Permalink Normal View History

2011-11-07 13:46:58 -06:00
/*
2016-01-25 08:13:49 -06:00
* xedit-search-commands.c
* This file is part of xedit
2011-11-07 13:46:58 -06:00
*
* Copyright (C) 1998, 1999 Alex Roberts, Evan Lawrence
* Copyright (C) 2000, 2001 Chema Celorio, Paolo Maggi
* Copyright (C) 2002-2006 Paolo Maggi
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
2012-11-18 19:54:49 -06:00
* Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
2011-11-07 13:46:58 -06:00
*/
/*
2016-01-25 08:13:49 -06:00
* Modified by the xedit Team, 1998-2006. See the AUTHORS file for a
* list of people on the xedit Team.
2011-11-07 13:46:58 -06:00
* See the ChangeLog files for a list of changes.
*
* $Id$
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <string.h>
#include <glib/gi18n.h>
2013-10-29 18:56:56 -05:00
#include <gtk/gtk.h>
2011-11-07 13:46:58 -06:00
#include <gdk/gdkkeysyms.h>
2013-10-29 18:56:56 -05:00
#if GTK_CHECK_VERSION (3, 0, 0)
#define GTK_OBJECT G_OBJECT
#endif
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
#include "xedit-commands.h"
#include "xedit-debug.h"
#include "xedit-statusbar.h"
#include "xedit-window.h"
#include "xedit-window-private.h"
#include "xedit-utils.h"
#include "dialogs/xedit-search-dialog.h"
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
#define XEDIT_SEARCH_DIALOG_KEY "xedit-search-dialog-key"
#define XEDIT_LAST_SEARCH_DATA_KEY "xedit-last-search-data-key"
2011-11-07 13:46:58 -06:00
typedef struct _LastSearchData LastSearchData;
struct _LastSearchData
{
gint x;
gint y;
};
static void
last_search_data_free (LastSearchData *data)
{
g_slice_free (LastSearchData, data);
}
static void
2016-01-25 08:13:49 -06:00
last_search_data_restore_position (XeditSearchDialog *dlg)
2011-11-07 13:46:58 -06:00
{
LastSearchData *data;
2016-01-25 08:13:49 -06:00
data = g_object_get_data (G_OBJECT (dlg), XEDIT_LAST_SEARCH_DATA_KEY);
2011-11-07 13:46:58 -06:00
if (data != NULL)
{
gtk_window_move (GTK_WINDOW (dlg),
data->x,
data->y);
}
}
static void
2016-01-25 08:13:49 -06:00
last_search_data_store_position (XeditSearchDialog *dlg)
2011-11-07 13:46:58 -06:00
{
LastSearchData *data;
2016-01-25 08:13:49 -06:00
data = g_object_get_data (G_OBJECT (dlg), XEDIT_LAST_SEARCH_DATA_KEY);
2011-11-07 13:46:58 -06:00
if (data == NULL)
{
data = g_slice_new (LastSearchData);
g_object_set_data_full (G_OBJECT (dlg),
2016-01-25 08:13:49 -06:00
XEDIT_LAST_SEARCH_DATA_KEY,
2011-11-07 13:46:58 -06:00
data,
(GDestroyNotify) last_search_data_free);
}
gtk_window_get_position (GTK_WINDOW (dlg),
&data->x,
&data->y);
}
/* Use occurrences only for Replace All */
2011-11-07 13:46:58 -06:00
static void
2016-01-25 08:13:49 -06:00
text_found (XeditWindow *window,
2011-11-07 13:46:58 -06:00
gint occurrences)
{
if (occurrences > 1)
{
2016-01-25 08:13:49 -06:00
xedit_statusbar_flash_message (XEDIT_STATUSBAR (window->priv->statusbar),
2011-11-07 13:46:58 -06:00
window->priv->generic_message_cid,
ngettext("Found and replaced %d occurrence",
"Found and replaced %d occurrences",
occurrences),
occurrences);
}
else
{
if (occurrences == 1)
2016-01-25 08:13:49 -06:00
xedit_statusbar_flash_message (XEDIT_STATUSBAR (window->priv->statusbar),
2011-11-07 13:46:58 -06:00
window->priv->generic_message_cid,
_("Found and replaced one occurrence"));
else
2016-01-25 08:13:49 -06:00
xedit_statusbar_flash_message (XEDIT_STATUSBAR (window->priv->statusbar),
2011-11-07 13:46:58 -06:00
window->priv->generic_message_cid,
" ");
}
}
#define MAX_MSG_LENGTH 40
static void
2016-01-25 08:13:49 -06:00
text_not_found (XeditWindow *window,
2011-11-07 13:46:58 -06:00
const gchar *text)
{
gchar *searched;
2016-01-25 08:13:49 -06:00
searched = xedit_utils_str_end_truncate (text, MAX_MSG_LENGTH);
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
xedit_statusbar_flash_message (XEDIT_STATUSBAR (window->priv->statusbar),
2011-11-07 13:46:58 -06:00
window->priv->generic_message_cid,
/* Translators: %s is replaced by the text
entered by the user in the search box */
_("\"%s\" not found"), searched);
g_free (searched);
}
static gboolean
2016-01-25 08:13:49 -06:00
run_search (XeditView *view,
2011-11-07 13:46:58 -06:00
gboolean wrap_around,
gboolean search_backwards)
{
2016-01-25 08:13:49 -06:00
XeditDocument *doc;
2011-11-07 13:46:58 -06:00
GtkTextIter start_iter;
GtkTextIter match_start;
GtkTextIter match_end;
gboolean found = FALSE;
2016-01-25 08:13:49 -06:00
doc = XEDIT_DOCUMENT (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)));
2011-11-07 13:46:58 -06:00
if (!search_backwards)
{
gtk_text_buffer_get_selection_bounds (GTK_TEXT_BUFFER (doc),
NULL,
&start_iter);
2016-01-25 08:13:49 -06:00
found = xedit_document_search_forward (doc,
2011-11-07 13:46:58 -06:00
&start_iter,
NULL,
&match_start,
&match_end);
}
else
{
gtk_text_buffer_get_selection_bounds (GTK_TEXT_BUFFER (doc),
&start_iter,
NULL);
2016-01-25 08:13:49 -06:00
found = xedit_document_search_backward (doc,
2011-11-07 13:46:58 -06:00
NULL,
&start_iter,
&match_start,
&match_end);
}
if (!found && wrap_around)
{
if (!search_backwards)
2016-01-25 08:13:49 -06:00
found = xedit_document_search_forward (doc,
2011-11-07 13:46:58 -06:00
NULL,
NULL, /* FIXME: set the end_inter */
&match_start,
&match_end);
else
2016-01-25 08:13:49 -06:00
found = xedit_document_search_backward (doc,
2011-11-07 13:46:58 -06:00
NULL, /* FIXME: set the start_inter */
NULL,
&match_start,
&match_end);
}
if (found)
{
gtk_text_buffer_place_cursor (GTK_TEXT_BUFFER (doc),
&match_start);
gtk_text_buffer_move_mark_by_name (GTK_TEXT_BUFFER (doc),
"selection_bound",
&match_end);
2016-01-25 08:13:49 -06:00
xedit_view_scroll_to_cursor (view);
2011-11-07 13:46:58 -06:00
}
else
{
gtk_text_buffer_place_cursor (GTK_TEXT_BUFFER (doc),
&start_iter);
}
return found;
}
static void
2016-01-25 08:13:49 -06:00
do_find (XeditSearchDialog *dialog,
XeditWindow *window)
2011-11-07 13:46:58 -06:00
{
2016-01-25 08:13:49 -06:00
XeditView *active_view;
XeditDocument *doc;
2011-11-07 13:46:58 -06:00
gchar *search_text;
const gchar *entry_text;
gboolean match_case;
gboolean entire_word;
gboolean wrap_around;
gboolean search_backwards;
gboolean parse_escapes;
2011-11-07 13:46:58 -06:00
guint flags = 0;
guint old_flags = 0;
gboolean found;
/* TODO: make the dialog insensitive when all the tabs are closed
* and assert here that the view is not NULL */
2016-01-25 08:13:49 -06:00
active_view = xedit_window_get_active_view (window);
2011-11-07 13:46:58 -06:00
if (active_view == NULL)
return;
2016-01-25 08:13:49 -06:00
doc = XEDIT_DOCUMENT (gtk_text_view_get_buffer (GTK_TEXT_VIEW (active_view)));
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
match_case = xedit_search_dialog_get_match_case (dialog);
entire_word = xedit_search_dialog_get_entire_word (dialog);
search_backwards = xedit_search_dialog_get_backwards (dialog);
wrap_around = xedit_search_dialog_get_wrap_around (dialog);
parse_escapes = xedit_search_dialog_get_parse_escapes (dialog);
if (!parse_escapes) {
2016-01-25 08:13:49 -06:00
entry_text = xedit_utils_escape_search_text (xedit_search_dialog_get_search_text (dialog));
} else {
2016-01-25 08:13:49 -06:00
entry_text = xedit_search_dialog_get_search_text (dialog);
}
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
XEDIT_SEARCH_SET_CASE_SENSITIVE (flags, match_case);
XEDIT_SEARCH_SET_ENTIRE_WORD (flags, entire_word);
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
search_text = xedit_document_get_search_text (doc, &old_flags);
2011-11-07 13:46:58 -06:00
if ((search_text == NULL) ||
(strcmp (search_text, entry_text) != 0) ||
(flags != old_flags))
{
2016-01-25 08:13:49 -06:00
xedit_document_set_search_text (doc, entry_text, flags);
2011-11-07 13:46:58 -06:00
}
g_free (search_text);
found = run_search (active_view,
wrap_around,
search_backwards);
if (found)
text_found (window, 0);
else {
if (!parse_escapes) {
2016-01-25 08:13:49 -06:00
text_not_found (window, xedit_utils_unescape_search_text (entry_text));
} else {
text_not_found (window, entry_text);
}
}
2011-11-07 13:46:58 -06:00
gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog),
2016-01-25 08:13:49 -06:00
XEDIT_SEARCH_DIALOG_REPLACE_RESPONSE,
2011-11-07 13:46:58 -06:00
found);
}
2016-01-25 08:13:49 -06:00
/* FIXME: move in xedit-document.c and share it with xedit-view */
2011-11-07 13:46:58 -06:00
static gboolean
get_selected_text (GtkTextBuffer *doc,
gchar **selected_text,
gint *len)
{
GtkTextIter start, end;
g_return_val_if_fail (selected_text != NULL, FALSE);
g_return_val_if_fail (*selected_text == NULL, FALSE);
if (!gtk_text_buffer_get_selection_bounds (doc, &start, &end))
{
if (len != NULL)
len = 0;
return FALSE;
}
*selected_text = gtk_text_buffer_get_slice (doc, &start, &end, TRUE);
if (len != NULL)
*len = g_utf8_strlen (*selected_text, -1);
return TRUE;
}
static void
replace_selected_text (GtkTextBuffer *buffer,
const gchar *replace)
{
g_return_if_fail (gtk_text_buffer_get_selection_bounds (buffer, NULL, NULL));
g_return_if_fail (replace != NULL);
gtk_text_buffer_begin_user_action (buffer);
gtk_text_buffer_delete_selection (buffer, FALSE, TRUE);
gtk_text_buffer_insert_at_cursor (buffer, replace, strlen (replace));
gtk_text_buffer_end_user_action (buffer);
}
static void
2016-01-25 08:13:49 -06:00
do_replace (XeditSearchDialog *dialog,
XeditWindow *window)
2011-11-07 13:46:58 -06:00
{
2016-01-25 08:13:49 -06:00
XeditDocument *doc;
2011-11-07 13:46:58 -06:00
const gchar *search_entry_text;
const gchar *replace_entry_text;
gchar *unescaped_search_text;
gchar *unescaped_replace_text;
gchar *selected_text = NULL;
gboolean match_case;
gboolean parse_escapes;
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
doc = xedit_window_get_active_document (window);
2011-11-07 13:46:58 -06:00
if (doc == NULL)
return;
2016-01-25 08:13:49 -06:00
parse_escapes = xedit_search_dialog_get_parse_escapes (dialog);
if (!parse_escapes) {
2016-01-25 08:13:49 -06:00
search_entry_text = xedit_utils_escape_search_text (xedit_search_dialog_get_search_text (dialog));
} else {
2016-01-25 08:13:49 -06:00
search_entry_text = xedit_search_dialog_get_search_text (dialog);
}
2011-11-07 13:46:58 -06:00
g_return_if_fail ((search_entry_text) != NULL);
g_return_if_fail ((*search_entry_text) != '\0');
/* replace text may be "", we just delete */
if (!parse_escapes) {
2016-01-25 08:13:49 -06:00
replace_entry_text = xedit_utils_escape_search_text (xedit_search_dialog_get_replace_text (dialog));
} else {
2016-01-25 08:13:49 -06:00
replace_entry_text = xedit_search_dialog_get_replace_text (dialog);
}
2011-11-07 13:46:58 -06:00
g_return_if_fail ((replace_entry_text) != NULL);
2016-01-25 08:13:49 -06:00
unescaped_search_text = xedit_utils_unescape_search_text (search_entry_text);
2011-11-07 13:46:58 -06:00
get_selected_text (GTK_TEXT_BUFFER (doc),
&selected_text,
NULL);
2016-01-25 08:13:49 -06:00
match_case = xedit_search_dialog_get_match_case (dialog);
2011-11-07 13:46:58 -06:00
if ((selected_text == NULL) ||
(match_case && (strcmp (selected_text, unescaped_search_text) != 0)) ||
(!match_case && !g_utf8_caselessnmatch (selected_text,
unescaped_search_text,
strlen (selected_text),
strlen (unescaped_search_text)) != 0))
{
do_find (dialog, window);
g_free (unescaped_search_text);
g_free (selected_text);
return;
}
2016-01-25 08:13:49 -06:00
unescaped_replace_text = xedit_utils_unescape_search_text (replace_entry_text);
2011-11-07 13:46:58 -06:00
replace_selected_text (GTK_TEXT_BUFFER (doc), unescaped_replace_text);
g_free (unescaped_search_text);
g_free (selected_text);
g_free (unescaped_replace_text);
do_find (dialog, window);
}
static void
2016-01-25 08:13:49 -06:00
do_replace_all (XeditSearchDialog *dialog,
XeditWindow *window)
2011-11-07 13:46:58 -06:00
{
2016-01-25 08:13:49 -06:00
XeditView *active_view;
XeditDocument *doc;
2011-11-07 13:46:58 -06:00
const gchar *search_entry_text;
const gchar *replace_entry_text;
gboolean match_case;
gboolean entire_word;
gboolean parse_escapes;
2011-11-07 13:46:58 -06:00
guint flags = 0;
gint count;
2016-01-25 08:13:49 -06:00
active_view = xedit_window_get_active_view (window);
2011-11-07 13:46:58 -06:00
if (active_view == NULL)
return;
2016-01-25 08:13:49 -06:00
doc = XEDIT_DOCUMENT (gtk_text_view_get_buffer (GTK_TEXT_VIEW (active_view)));
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
parse_escapes = xedit_search_dialog_get_parse_escapes (dialog);
if (!parse_escapes) {
2016-01-25 08:13:49 -06:00
search_entry_text = xedit_utils_escape_search_text(xedit_search_dialog_get_search_text (dialog));
} else {
2016-01-25 08:13:49 -06:00
search_entry_text = xedit_search_dialog_get_search_text (dialog);
}
2011-11-07 13:46:58 -06:00
g_return_if_fail ((search_entry_text) != NULL);
g_return_if_fail ((*search_entry_text) != '\0');
/* replace text may be "", we just delete all occurrencies */
if (!parse_escapes) {
2016-01-25 08:13:49 -06:00
replace_entry_text = xedit_utils_escape_search_text (xedit_search_dialog_get_replace_text (dialog));
} else {
2016-01-25 08:13:49 -06:00
replace_entry_text = xedit_search_dialog_get_replace_text (dialog);
}
2011-11-07 13:46:58 -06:00
g_return_if_fail ((replace_entry_text) != NULL);
2016-01-25 08:13:49 -06:00
match_case = xedit_search_dialog_get_match_case (dialog);
entire_word = xedit_search_dialog_get_entire_word (dialog);
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
XEDIT_SEARCH_SET_CASE_SENSITIVE (flags, match_case);
XEDIT_SEARCH_SET_ENTIRE_WORD (flags, entire_word);
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
count = xedit_document_replace_all (doc,
2011-11-07 13:46:58 -06:00
search_entry_text,
replace_entry_text,
flags);
if (count > 0)
{
text_found (window, count);
}
else
{
if (!parse_escapes) {
2016-01-25 08:13:49 -06:00
text_not_found (window, xedit_utils_unescape_search_text (search_entry_text));
} else {
text_not_found (window, search_entry_text);
}
2011-11-07 13:46:58 -06:00
}
gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog),
2016-01-25 08:13:49 -06:00
XEDIT_SEARCH_DIALOG_REPLACE_RESPONSE,
2011-11-07 13:46:58 -06:00
FALSE);
}
static void
2016-01-25 08:13:49 -06:00
search_dialog_response_cb (XeditSearchDialog *dialog,
2011-11-07 13:46:58 -06:00
gint response_id,
2016-01-25 08:13:49 -06:00
XeditWindow *window)
2011-11-07 13:46:58 -06:00
{
2016-01-25 08:13:49 -06:00
xedit_debug (DEBUG_COMMANDS);
2011-11-07 13:46:58 -06:00
switch (response_id)
{
2016-01-25 08:13:49 -06:00
case XEDIT_SEARCH_DIALOG_FIND_RESPONSE:
2011-11-07 13:46:58 -06:00
do_find (dialog, window);
break;
2016-01-25 08:13:49 -06:00
case XEDIT_SEARCH_DIALOG_REPLACE_RESPONSE:
2011-11-07 13:46:58 -06:00
do_replace (dialog, window);
break;
2016-01-25 08:13:49 -06:00
case XEDIT_SEARCH_DIALOG_REPLACE_ALL_RESPONSE:
2011-11-07 13:46:58 -06:00
do_replace_all (dialog, window);
break;
default:
last_search_data_store_position (dialog);
gtk_widget_hide (GTK_WIDGET (dialog));
}
}
static gboolean
search_dialog_delete_event_cb (GtkWidget *widget,
GdkEventAny *event,
gpointer user_data)
{
2016-01-25 08:13:49 -06:00
xedit_debug (DEBUG_COMMANDS);
2011-11-07 13:46:58 -06:00
/* prevent destruction */
return TRUE;
}
static void
2016-01-25 08:13:49 -06:00
search_dialog_destroyed (XeditWindow *window,
XeditSearchDialog *dialog)
2011-11-07 13:46:58 -06:00
{
2016-01-25 08:13:49 -06:00
xedit_debug (DEBUG_COMMANDS);
2011-11-07 13:46:58 -06:00
g_object_set_data (G_OBJECT (window),
2016-01-25 08:13:49 -06:00
XEDIT_SEARCH_DIALOG_KEY,
2011-11-07 13:46:58 -06:00
NULL);
g_object_set_data (G_OBJECT (dialog),
2016-01-25 08:13:49 -06:00
XEDIT_LAST_SEARCH_DATA_KEY,
2011-11-07 13:46:58 -06:00
NULL);
}
static GtkWidget *
2016-01-25 08:13:49 -06:00
create_dialog (XeditWindow *window, gboolean show_replace)
2011-11-07 13:46:58 -06:00
{
GtkWidget *dialog;
2016-01-25 08:13:49 -06:00
dialog = xedit_search_dialog_new (GTK_WINDOW (window), show_replace);
2011-11-07 13:46:58 -06:00
g_signal_connect (dialog,
"response",
G_CALLBACK (search_dialog_response_cb),
window);
g_signal_connect (dialog,
"delete-event",
G_CALLBACK (search_dialog_delete_event_cb),
NULL);
g_object_set_data (G_OBJECT (window),
2016-01-25 08:13:49 -06:00
XEDIT_SEARCH_DIALOG_KEY,
2011-11-07 13:46:58 -06:00
dialog);
g_object_weak_ref (G_OBJECT (dialog),
(GWeakNotify) search_dialog_destroyed,
window);
return dialog;
}
void
2016-01-25 08:13:49 -06:00
_xedit_cmd_search_find (GtkAction *action,
XeditWindow *window)
2011-11-07 13:46:58 -06:00
{
gpointer data;
GtkWidget *search_dialog;
2016-01-25 08:13:49 -06:00
XeditDocument *doc;
2011-11-07 13:46:58 -06:00
gboolean selection_exists;
gboolean parse_escapes;
2011-11-07 13:46:58 -06:00
gchar *find_text = NULL;
const gchar *search_text = NULL;
2011-11-07 13:46:58 -06:00
gint sel_len;
2016-01-25 08:13:49 -06:00
xedit_debug (DEBUG_COMMANDS);
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
data = g_object_get_data (G_OBJECT (window), XEDIT_SEARCH_DIALOG_KEY);
2011-11-07 13:46:58 -06:00
if (data == NULL)
{
search_dialog = create_dialog (window, FALSE);
}
else
{
2016-01-25 08:13:49 -06:00
g_return_if_fail (XEDIT_IS_SEARCH_DIALOG (data));
2011-11-07 13:46:58 -06:00
search_dialog = GTK_WIDGET (data);
/* turn the dialog into a find dialog if needed */
2016-01-25 08:13:49 -06:00
if (xedit_search_dialog_get_show_replace (XEDIT_SEARCH_DIALOG (search_dialog)))
xedit_search_dialog_set_show_replace (XEDIT_SEARCH_DIALOG (search_dialog),
2011-11-07 13:46:58 -06:00
FALSE);
}
2016-01-25 08:13:49 -06:00
doc = xedit_window_get_active_document (window);
2011-11-07 13:46:58 -06:00
g_return_if_fail (doc != NULL);
selection_exists = get_selected_text (GTK_TEXT_BUFFER (doc),
&find_text,
&sel_len);
if (selection_exists && find_text != NULL && sel_len < 80)
{
/*
* Special case: if the currently selected text
* is the same as the unescaped search text and
* escape sequence parsing is activated, use the
* same old search text. (Without this, if you e.g.
* search for '\n' in escaped mode and then open
* the search dialog again, you'll get an unprintable
* single-character literal '\n' in the "search for"
* box).
*/
2016-01-25 08:13:49 -06:00
parse_escapes = xedit_search_dialog_get_parse_escapes (XEDIT_SEARCH_DIALOG (search_dialog));
search_text = xedit_search_dialog_get_search_text (XEDIT_SEARCH_DIALOG (search_dialog));
if (!(search_text != NULL
2016-01-25 08:13:49 -06:00
&& !strcmp(xedit_utils_unescape_search_text(search_text), find_text)
&& parse_escapes)) {
/* General case */
2016-01-25 08:13:49 -06:00
xedit_search_dialog_set_search_text (XEDIT_SEARCH_DIALOG (search_dialog),
find_text);
}
2011-11-07 13:46:58 -06:00
g_free (find_text);
}
else
{
g_free (find_text);
}
gtk_widget_show (search_dialog);
2016-01-25 08:13:49 -06:00
last_search_data_restore_position (XEDIT_SEARCH_DIALOG (search_dialog));
xedit_search_dialog_present_with_time (XEDIT_SEARCH_DIALOG (search_dialog),
2011-11-07 13:46:58 -06:00
GDK_CURRENT_TIME);
}
void
2016-01-25 08:13:49 -06:00
_xedit_cmd_search_replace (GtkAction *action,
XeditWindow *window)
2011-11-07 13:46:58 -06:00
{
gpointer data;
GtkWidget *replace_dialog;
2016-01-25 08:13:49 -06:00
XeditDocument *doc;
2011-11-07 13:46:58 -06:00
gboolean selection_exists;
gboolean parse_escapes;
2011-11-07 13:46:58 -06:00
gchar *find_text = NULL;
const gchar *search_text = NULL;
2011-11-07 13:46:58 -06:00
gint sel_len;
2016-01-25 08:13:49 -06:00
xedit_debug (DEBUG_COMMANDS);
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
data = g_object_get_data (G_OBJECT (window), XEDIT_SEARCH_DIALOG_KEY);
2011-11-07 13:46:58 -06:00
if (data == NULL)
{
replace_dialog = create_dialog (window, TRUE);
}
else
{
2016-01-25 08:13:49 -06:00
g_return_if_fail (XEDIT_IS_SEARCH_DIALOG (data));
2011-11-07 13:46:58 -06:00
replace_dialog = GTK_WIDGET (data);
/* turn the dialog into a find dialog if needed */
2016-01-25 08:13:49 -06:00
if (!xedit_search_dialog_get_show_replace (XEDIT_SEARCH_DIALOG (replace_dialog)))
xedit_search_dialog_set_show_replace (XEDIT_SEARCH_DIALOG (replace_dialog),
2011-11-07 13:46:58 -06:00
TRUE);
}
2016-01-25 08:13:49 -06:00
doc = xedit_window_get_active_document (window);
2011-11-07 13:46:58 -06:00
g_return_if_fail (doc != NULL);
selection_exists = get_selected_text (GTK_TEXT_BUFFER (doc),
&find_text,
&sel_len);
if (selection_exists && find_text != NULL && sel_len < 80)
{
/*
* Special case: if the currently selected text
* is the same as the unescaped search text and
* escape sequence parsing is activated, use the
* same old search text. (Without this, if you e.g.
* search for '\n' in escaped mode and then open
* the search dialog again, you'll get an unprintable
* single-character literal '\n' in the "search for"
* box).
*/
2016-01-25 08:13:49 -06:00
parse_escapes = xedit_search_dialog_get_parse_escapes (XEDIT_SEARCH_DIALOG (replace_dialog));
search_text = xedit_search_dialog_get_search_text (XEDIT_SEARCH_DIALOG (replace_dialog));
if (!(search_text != NULL
2016-01-25 08:13:49 -06:00
&& !strcmp(xedit_utils_unescape_search_text(search_text), find_text)
&& parse_escapes)) {
/* General case */
2016-01-25 08:13:49 -06:00
xedit_search_dialog_set_search_text (XEDIT_SEARCH_DIALOG (replace_dialog),
find_text);
}
2011-11-07 13:46:58 -06:00
g_free (find_text);
}
else
{
g_free (find_text);
}
gtk_widget_show (replace_dialog);
2016-01-25 08:13:49 -06:00
last_search_data_restore_position (XEDIT_SEARCH_DIALOG (replace_dialog));
xedit_search_dialog_present_with_time (XEDIT_SEARCH_DIALOG (replace_dialog),
2011-11-07 13:46:58 -06:00
GDK_CURRENT_TIME);
}
static void
2016-01-25 08:13:49 -06:00
do_find_again (XeditWindow *window,
2011-11-07 13:46:58 -06:00
gboolean backward)
{
2016-01-25 08:13:49 -06:00
XeditView *active_view;
2011-11-07 13:46:58 -06:00
gboolean wrap_around = TRUE;
gpointer data;
2016-01-25 08:13:49 -06:00
active_view = xedit_window_get_active_view (window);
2011-11-07 13:46:58 -06:00
g_return_if_fail (active_view != NULL);
2016-01-25 08:13:49 -06:00
data = g_object_get_data (G_OBJECT (window), XEDIT_SEARCH_DIALOG_KEY);
2011-11-07 13:46:58 -06:00
if (data != NULL)
2016-01-25 08:13:49 -06:00
wrap_around = xedit_search_dialog_get_wrap_around (XEDIT_SEARCH_DIALOG (data));
2011-11-07 13:46:58 -06:00
run_search (active_view,
wrap_around,
backward);
}
void
2016-01-25 08:13:49 -06:00
_xedit_cmd_search_find_next (GtkAction *action,
XeditWindow *window)
2011-11-07 13:46:58 -06:00
{
2016-01-25 08:13:49 -06:00
xedit_debug (DEBUG_COMMANDS);
2011-11-07 13:46:58 -06:00
do_find_again (window, FALSE);
}
void
2016-01-25 08:13:49 -06:00
_xedit_cmd_search_find_prev (GtkAction *action,
XeditWindow *window)
2011-11-07 13:46:58 -06:00
{
2016-01-25 08:13:49 -06:00
xedit_debug (DEBUG_COMMANDS);
2011-11-07 13:46:58 -06:00
do_find_again (window, TRUE);
}
void
2016-01-25 08:13:49 -06:00
_xedit_cmd_search_clear_highlight (GtkAction *action,
XeditWindow *window)
2011-11-07 13:46:58 -06:00
{
2016-01-25 08:13:49 -06:00
XeditDocument *doc;
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
xedit_debug (DEBUG_COMMANDS);
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
doc = xedit_window_get_active_document (window);
xedit_document_set_search_text (XEDIT_DOCUMENT (doc),
2011-11-07 13:46:58 -06:00
"",
2016-01-25 08:13:49 -06:00
XEDIT_SEARCH_DONT_SET_FLAGS);
2011-11-07 13:46:58 -06:00
}
void
2016-01-25 08:13:49 -06:00
_xedit_cmd_search_goto_line (GtkAction *action,
XeditWindow *window)
2011-11-07 13:46:58 -06:00
{
2016-01-25 08:13:49 -06:00
XeditView *active_view;
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
xedit_debug (DEBUG_COMMANDS);
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
active_view = xedit_window_get_active_view (window);
2011-11-07 13:46:58 -06:00
if (active_view == NULL)
return;
/* Focus the view if needed: we need to focus the view otherwise
activating the binding for goto line has no effect */
gtk_widget_grab_focus (GTK_WIDGET (active_view));
2016-01-25 08:13:49 -06:00
/* goto line is builtin in XeditView, just activate
2011-11-07 13:46:58 -06:00
* the corrisponding binding.
*/
gtk_bindings_activate (GTK_OBJECT (active_view),
GDK_KEY_i,
2011-11-07 13:46:58 -06:00
GDK_CONTROL_MASK);
}
void
2016-01-25 08:13:49 -06:00
_xedit_cmd_search_incremental_search (GtkAction *action,
XeditWindow *window)
2011-11-07 13:46:58 -06:00
{
2016-01-25 08:13:49 -06:00
XeditView *active_view;
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
xedit_debug (DEBUG_COMMANDS);
2011-11-07 13:46:58 -06:00
2016-01-25 08:13:49 -06:00
active_view = xedit_window_get_active_view (window);
2011-11-07 13:46:58 -06:00
if (active_view == NULL)
return;
/* Focus the view if needed: we need to focus the view otherwise
activating the binding for incremental search has no effect */
gtk_widget_grab_focus (GTK_WIDGET (active_view));
2016-01-25 08:13:49 -06:00
/* incremental search is builtin in XeditView, just activate
2011-11-07 13:46:58 -06:00
* the corrisponding binding.
*/
gtk_bindings_activate (GTK_OBJECT (active_view),
GDK_KEY_k,
2011-11-07 13:46:58 -06:00
GDK_CONTROL_MASK);
}