Added events for diffviewer

Signed-off-by: Slava Zanko <slavazanko@gmail.com>
This commit is contained in:
Slava Zanko 2014-04-11 16:16:04 +03:00
parent e67562edb6
commit 5dbb548479
17 changed files with 4031 additions and 3099 deletions

View File

@ -1,10 +1,19 @@
noinst_LTLIBRARIES = libdiffviewer.la noinst_LTLIBRARIES = libdiffviewer.la
libdiffviewer_la_SOURCES = \ libdiffviewer_la_SOURCES = \
events.c \
execute.c execute.h \
internal.h \ internal.h \
options.c options.h \
search.c \ search.c \
tools.c \
ydiff.c ydiff.h ydiff.c ydiff.h
if CHARSET
libdiffviewer_la_SOURCES += charset.c charset.h
endif
AM_CPPFLAGS = -I$(top_srcdir) $(GLIB_CFLAGS) $(PCRE_CPPFLAGS) AM_CPPFLAGS = -I$(top_srcdir) $(GLIB_CFLAGS) $(PCRE_CPPFLAGS)
libdiffviewer_la_LIBADD = ../../lib/libmc.la libdiffviewer_la_LIBADD = ../../lib/libmc.la

105
src/diffviewer/charset.c Normal file
View File

@ -0,0 +1,105 @@
/*
Search functions for diffviewer.
Copyright (C) 2010-2014
Free Software Foundation, Inc.
Written by:
Slava Zanko <slavazanko@gmail.com>, 2010.
Andrew Borodin <aborodin@vmail.ru>, 2012
This file is part of the Midnight Commander.
The Midnight Commander 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 3 of the License,
or (at your option) any later version.
The Midnight Commander is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <config.h>
#include <stdio.h>
#include "lib/global.h"
#include "lib/strutil.h"
#include "lib/tty/key.h"
#include "lib/widget.h"
#include "lib/charsets.h"
#include "src/history.h"
#include "src/selcodepage.h"
#include "internal.h"
#include "charset.h"
/*** global variables ****************************************************************************/
/*** file scope macro definitions ****************************************************************/
/*** file scope type declarations ****************************************************************/
/*** file scope variables ************************************************************************/
/* --------------------------------------------------------------------------------------------- */
/*** file scope functions ************************************************************************/
/* --------------------------------------------------------------------------------------------- */
/* --------------------------------------------------------------------------------------------- */
/*** public functions ****************************************************************************/
/* --------------------------------------------------------------------------------------------- */
void
mc_diffviewer_set_codeset (WDiff * dview)
{
const char *encoding_id = NULL;
dview->utf8 = TRUE;
encoding_id =
get_codepage_id (mc_global.source_codepage >=
0 ? mc_global.source_codepage : mc_global.display_codepage);
if (encoding_id != NULL)
{
GIConv conv;
conv = str_crt_conv_from (encoding_id);
if (conv != INVALID_CONV)
{
if (dview->converter != str_cnv_from_term)
str_close_conv (dview->converter);
dview->converter = conv;
}
dview->utf8 = (gboolean) str_isutf8 (encoding_id);
}
}
/* --------------------------------------------------------------------------------------------- */
/* event callback */
gboolean
mc_diffviewer_cmd_select_encoding_show_dialog (const gchar * event_group_name,
const gchar * event_name, gpointer init_data,
gpointer data)
{
WDiff *dview = (WDiff *) data;
(void) event_group_name;
(void) event_name;
(void) init_data;
if (do_select_codepage ())
mc_diffviewer_set_codeset (dview);
mc_diffviewer_reread (dview);
tty_touch_screen ();
repaint_screen ();
return TRUE;
}
/* --------------------------------------------------------------------------------------------- */

22
src/diffviewer/charset.h Normal file
View File

@ -0,0 +1,22 @@
#ifndef MC__DIFFVIEW_CHARSET_H
#define MC__DIFFVIEW_CHARSET_H
/*** typedefs(not structures) and defined constants **********************************************/
/*** enums ***************************************************************************************/
/*** structures declarations (and typedefs of structures)*****************************************/
/*** global variables defined in .c file *********************************************************/
/*** declarations of public functions ************************************************************/
gboolean mc_diffviewer_cmd_select_encoding_show_dialog (const gchar * event_group_name,
const gchar * event_name,
gpointer init_data, gpointer data);
void mc_diffviewer_set_codeset (WDiff * dview);
/*** inline functions ****************************************************************************/
#endif /* MC__DIFFVIEW_CHARSET_H */

683
src/diffviewer/events.c Normal file
View File

@ -0,0 +1,683 @@
/*
Events diffviewer.
Copyright (C) 2010-2014
Free Software Foundation, Inc.
Written by:
Slava Zanko <slavazanko@gmail.com>, 2010.
Andrew Borodin <aborodin@vmail.ru>, 2012
This file is part of the Midnight Commander.
The Midnight Commander 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 3 of the License,
or (at your option) any later version.
The Midnight Commander is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <config.h>
#include <stdio.h>
#include <errno.h>
#include "lib/global.h"
#include "lib/event.h"
#include "lib/strutil.h"
#include "lib/vfs/vfs.h" /* mc_opendir, mc_readdir, mc_closedir, */
#include "lib/tty/key.h"
#include "lib/widget.h"
#include "src/filemanager/cmd.h" /* edit_file_at_line(), view_other_cmd() */
#include "src/history.h"
#include "src/setup.h"
#include "internal.h"
#include "options.h"
#ifdef HAVE_CHARSET
#include "charset.h"
#endif
/*** global variables ****************************************************************************/
/*** file scope macro definitions ****************************************************************/
typedef enum
{
MC_DVIEW_SPLIT_EQUAL = 1,
MC_DVIEW_SPLIT_FULL,
MC_DVIEW_SPLIT_MORE,
MC_DVIEW_SPLIT_LESS,
} mc_diffviewer_split_type_t;
/*** file scope type declarations ****************************************************************/
/*** file scope variables ************************************************************************/
/* --------------------------------------------------------------------------------------------- */
/*** file scope functions ************************************************************************/
/* --------------------------------------------------------------------------------------------- */
/* event callback */
static gboolean
mc_diffviewer_cmd_show_symbols (const gchar * event_group_name, const gchar * event_name,
gpointer init_data, gpointer data)
{
WDiff *dview = (WDiff *) data;
(void) event_group_name;
(void) event_name;
(void) init_data;
dview->display_symbols ^= 1;
dview->new_frame = 1;
return TRUE;
}
/* --------------------------------------------------------------------------------------------- */
/* event callback */
static gboolean
mc_diffviewer_cmd_show_numbers (const gchar * event_group_name, const gchar * event_name,
gpointer init_data, gpointer data)
{
WDiff *dview = (WDiff *) data;
(void) event_group_name;
(void) event_name;
(void) init_data;
dview->display_numbers ^= mc_diffviewer_calc_nwidth ((const GArray ** const) dview->a);
dview->new_frame = 1;
return TRUE;
}
/* --------------------------------------------------------------------------------------------- */
/* event callback */
static gboolean
mc_diffviewer_cmd_split_views (const gchar * event_group_name, const gchar * event_name,
gpointer init_data, gpointer data)
{
WDiff *dview = (WDiff *) data;
mc_diffviewer_split_type_t split_type;
(void) event_group_name;
(void) event_name;
(void) init_data;
if (init_data == NULL)
return TRUE;
split_type = (mc_diffviewer_split_type_t) init_data;
if (split_type == MC_DVIEW_SPLIT_FULL)
{
dview->full ^= 1;
dview->new_frame = 1;
}
else if (!dview->full)
{
switch (split_type)
{
case MC_DVIEW_SPLIT_EQUAL:
dview->bias = 0;
break;
case MC_DVIEW_SPLIT_MORE:
mc_diffviewer_compute_split (dview, 1);
break;
case MC_DVIEW_SPLIT_LESS:
mc_diffviewer_compute_split (dview, -1);
break;
default:
return TRUE;
}
dview->new_frame = 1;
}
return TRUE;
}
/* --------------------------------------------------------------------------------------------- */
/* event callback */
static gboolean
mc_diffviewer_cmd_set_tab_size (const gchar * event_group_name, const gchar * event_name,
gpointer init_data, gpointer data)
{
WDiff *dview = (WDiff *) data;
(void) event_group_name;
(void) event_name;
if (init_data != NULL)
dview->tab_size = (int) (intptr_t) init_data;
return TRUE;
}
/* --------------------------------------------------------------------------------------------- */
/* event callback */
static gboolean
mc_diffviewer_cmd_swap (const gchar * event_group_name, const gchar * event_name,
gpointer init_data, gpointer data)
{
WDiff *dview = (WDiff *) data;
(void) event_group_name;
(void) event_name;
(void) init_data;
dview->ord ^= 1;
return TRUE;
}
/* --------------------------------------------------------------------------------------------- */
/* event callback */
static gboolean
mc_diffviewer_cmd_redo (const gchar * event_group_name, const gchar * event_name,
gpointer init_data, gpointer data)
{
WDiff *dview = (WDiff *) data;
(void) event_group_name;
(void) event_name;
(void) init_data;
if (dview->display_numbers)
{
int old;
old = dview->display_numbers;
dview->display_numbers = mc_diffviewer_calc_nwidth ((const GArray **) dview->a);
dview->new_frame = (old != dview->display_numbers);
}
mc_diffviewer_reread (dview);
return TRUE;
}
/* --------------------------------------------------------------------------------------------- */
/* event callback */
static gboolean
mc_diffviewer_cmd_hunk_next (const gchar * event_group_name, const gchar * event_name,
gpointer init_data, gpointer data)
{
WDiff *dview = (WDiff *) data;
const GArray *a;
diff_place_t diff_place;
(void) event_group_name;
(void) event_name;
diff_place = (diff_place_t) init_data;
a = dview->a[diff_place];
while ((size_t) dview->skip_rows < a->len
&& ((DIFFLN *) & g_array_index (a, DIFFLN, dview->skip_rows))->ch != EQU_CH)
dview->skip_rows++;
while ((size_t) dview->skip_rows < a->len
&& ((DIFFLN *) & g_array_index (a, DIFFLN, dview->skip_rows))->ch == EQU_CH)
dview->skip_rows++;
dview->search.last_accessed_num_line = dview->skip_rows;
return TRUE;
}
/* --------------------------------------------------------------------------------------------- */
/* event callback */
static gboolean
mc_diffviewer_cmd_hunk_prev (const gchar * event_group_name, const gchar * event_name,
gpointer init_data, gpointer data)
{
WDiff *dview = (WDiff *) data;
const GArray *a;
diff_place_t diff_place;
(void) event_group_name;
(void) event_name;
diff_place = (diff_place_t) init_data;
a = dview->a[diff_place];
while (dview->skip_rows > 0
&& ((DIFFLN *) & g_array_index (a, DIFFLN, dview->skip_rows))->ch != EQU_CH)
dview->skip_rows--;
while (dview->skip_rows > 0
&& ((DIFFLN *) & g_array_index (a, DIFFLN, dview->skip_rows))->ch == EQU_CH)
dview->skip_rows--;
while (dview->skip_rows > 0
&& ((DIFFLN *) & g_array_index (a, DIFFLN, dview->skip_rows))->ch != EQU_CH)
dview->skip_rows--;
if (dview->skip_rows > 0 && (size_t) dview->skip_rows < a->len)
dview->skip_rows++;
dview->search.last_accessed_num_line = dview->skip_rows;
return TRUE;
}
/* --------------------------------------------------------------------------------------------- */
/* event callback */
static gboolean
mc_diffviewer_cmd_goto_line (const gchar * event_group_name, const gchar * event_name,
gpointer init_data, gpointer data)
{
WDiff *dview = (WDiff *) data;
diff_place_t ord = (diff_place_t) init_data;
/* *INDENT-OFF* */
static const char *title[2] = {
N_("Goto line (left)"),
N_("Goto line (right)")
};
/* *INDENT-ON* */
static char prev[256];
/* XXX some statics here, to be remembered between runs */
int newline;
char *input;
(void) event_group_name;
(void) event_name;
input =
input_dialog (_(title[ord]), _("Enter line:"), MC_HISTORY_YDIFF_GOTO_LINE, prev,
INPUT_COMPLETE_NONE);
if (input != NULL)
{
const char *s = input;
if (mc_diffviewer_scan_deci (&s, &newline) == 0 && *s == '\0')
{
size_t i = 0;
if (newline > 0)
{
for (; i < dview->a[ord]->len; i++)
{
const DIFFLN *p;
p = &g_array_index (dview->a[ord], DIFFLN, i);
if (p->line == newline)
break;
}
}
dview->skip_rows = dview->search.last_accessed_num_line = (ssize_t) i;
g_snprintf (prev, sizeof (prev), "%d", newline);
}
g_free (input);
}
return TRUE;
}
/* --------------------------------------------------------------------------------------------- */
/* event callback */
static gboolean
mc_diffviewer_cmd_edit (const gchar * event_group_name, const gchar * event_name,
gpointer init_data, gpointer data)
{
WDiff *dview = (WDiff *) data;
diff_place_t diff_place = (diff_place_t) init_data;
WDialog *h;
gboolean h_modal;
int linenum, lineofs;
(void) event_group_name;
(void) event_name;
(void) init_data;
switch (diff_place)
{
case DIFF_CURRENT:
diff_place = dview->ord;
break;
case DIFF_OTHER:
diff_place = dview->ord ^ 1;
break;
case DIFF_LEFT:
case DIFF_RIGHT:
break;
default:
return FALSE;
}
if (dview->dsrc == DATA_SRC_TMP)
{
error_dialog (_("Edit"), _("Edit is disabled"));
return TRUE;
}
h = WIDGET (dview)->owner;
h_modal = h->modal;
mc_diffviewer_get_line_numbers (dview->a[diff_place], dview->skip_rows, &linenum, &lineofs);
h->modal = TRUE; /* not allow edit file in several editors */
{
vfs_path_t *tmp_vpath;
tmp_vpath = vfs_path_from_str (dview->file[diff_place]);
edit_file_at_line (tmp_vpath, use_internal_edit != 0, linenum);
vfs_path_free (tmp_vpath);
}
h->modal = h_modal;
mc_event_raise (MCEVENT_GROUP_DIFFVIEWER, "redo", dview);
mc_diffviewer_update (dview);
return TRUE;
}
/* --------------------------------------------------------------------------------------------- */
/* event callback */
static gboolean
mc_diffviewer_cmd_goto_top (const gchar * event_group_name, const gchar * event_name,
gpointer init_data, gpointer data)
{
WDiff *dview = (WDiff *) data;
(void) event_group_name;
(void) event_name;
(void) init_data;
dview->skip_rows = dview->search.last_accessed_num_line = 0;
return TRUE;
}
/* --------------------------------------------------------------------------------------------- */
/* event callback */
static gboolean
mc_diffviewer_cmd_goto_bottom (const gchar * event_group_name, const gchar * event_name,
gpointer init_data, gpointer data)
{
WDiff *dview = (WDiff *) data;
(void) event_group_name;
(void) event_name;
(void) init_data;
dview->skip_rows = dview->search.last_accessed_num_line = dview->a[DIFF_LEFT]->len - 1;
return TRUE;
}
/* --------------------------------------------------------------------------------------------- */
/* event callback */
static gboolean
mc_diffviewer_cmd_goto_up (const gchar * event_group_name, const gchar * event_name,
gpointer init_data, gpointer data)
{
WDiff *dview = (WDiff *) data;
(void) event_group_name;
(void) event_name;
(void) init_data;
if (dview->skip_rows > 0)
{
dview->skip_rows--;
dview->search.last_accessed_num_line = dview->skip_rows;
}
return TRUE;
}
/* --------------------------------------------------------------------------------------------- */
/* event callback */
static gboolean
mc_diffviewer_cmd_goto_down (const gchar * event_group_name, const gchar * event_name,
gpointer init_data, gpointer data)
{
WDiff *dview = (WDiff *) data;
(void) event_group_name;
(void) event_name;
(void) init_data;
dview->skip_rows++;
dview->search.last_accessed_num_line = dview->skip_rows;
return TRUE;
}
/* --------------------------------------------------------------------------------------------- */
/* event callback */
static gboolean
mc_diffviewer_cmd_goto_page_up (const gchar * event_group_name, const gchar * event_name,
gpointer init_data, gpointer data)
{
WDiff *dview = (WDiff *) data;
(void) event_group_name;
(void) event_name;
(void) init_data;
if (dview->height > 2)
{
dview->skip_rows -= dview->height - 2;
dview->search.last_accessed_num_line = dview->skip_rows;
}
return TRUE;
}
/* --------------------------------------------------------------------------------------------- */
/* event callback */
static gboolean
mc_diffviewer_cmd_goto_page_down (const gchar * event_group_name, const gchar * event_name,
gpointer init_data, gpointer data)
{
WDiff *dview = (WDiff *) data;
(void) event_group_name;
(void) event_name;
(void) init_data;
if (dview->height > 2)
{
dview->skip_rows += dview->height - 2;
dview->search.last_accessed_num_line = dview->skip_rows;
}
return TRUE;
}
/* --------------------------------------------------------------------------------------------- */
/* event callback */
static gboolean
mc_diffviewer_cmd_goto_left (const gchar * event_group_name, const gchar * event_name,
gpointer init_data, gpointer data)
{
WDiff *dview = (WDiff *) data;
(void) event_group_name;
(void) event_name;
(void) init_data;
dview->skip_cols -= (int) (intptr_t) init_data;
return TRUE;
}
/* --------------------------------------------------------------------------------------------- */
/* event callback */
static gboolean
mc_diffviewer_cmd_goto_right (const gchar * event_group_name, const gchar * event_name,
gpointer init_data, gpointer data)
{
WDiff *dview = (WDiff *) data;
(void) event_group_name;
(void) event_name;
(void) init_data;
dview->skip_cols += (int) (intptr_t) init_data;
return TRUE;
}
/* --------------------------------------------------------------------------------------------- */
/* event callback */
static gboolean
mc_diffviewer_cmd_goto_start_of_line (const gchar * event_group_name, const gchar * event_name,
gpointer init_data, gpointer data)
{
WDiff *dview = (WDiff *) data;
(void) event_group_name;
(void) event_name;
(void) init_data;
dview->skip_cols = 0;
return TRUE;
}
/* --------------------------------------------------------------------------------------------- */
/* event callback */
static gboolean
mc_diffviewer_cmd_quit (const gchar * event_group_name, const gchar * event_name,
gpointer init_data, gpointer data)
{
WDiff *dview = (WDiff *) data;
(void) event_group_name;
(void) event_name;
(void) init_data;
dview->view_quit = 1;
return TRUE;
}
/* --------------------------------------------------------------------------------------------- */
/* event callback */
static gboolean
mc_diffviewer_cmd_save_changes (const gchar * event_group_name, const gchar * event_name,
gpointer init_data, gpointer data)
{
WDiff *dview = (WDiff *) data;
gboolean res;
(void) event_group_name;
(void) event_name;
(void) init_data;
if (dview->merged[DIFF_LEFT])
{
res = mc_util_unlink_backup_if_possible (dview->file[DIFF_LEFT], "~~~");
dview->merged[DIFF_LEFT] = !res;
}
if (dview->merged[DIFF_RIGHT])
{
res = mc_util_unlink_backup_if_possible (dview->file[DIFF_RIGHT], "~~~");
dview->merged[DIFF_RIGHT] = !res;
}
return TRUE;
}
/* --------------------------------------------------------------------------------------------- */
/*** public functions ****************************************************************************/
/* --------------------------------------------------------------------------------------------- */
void
mc_diffviewer_init_events (GError ** error)
{
/* *INDENT-OFF* */
event_init_group_t core_group_events[] =
{
{"run", mc_diffviewer_cmd_run, NULL},
{"show_symbols", mc_diffviewer_cmd_show_symbols, NULL},
{"show_numbers", mc_diffviewer_cmd_show_numbers, NULL},
{"split_full", mc_diffviewer_cmd_split_views, (void *) MC_DVIEW_SPLIT_FULL},
{"split_equal", mc_diffviewer_cmd_split_views, (void *) MC_DVIEW_SPLIT_EQUAL},
{"split_more", mc_diffviewer_cmd_split_views, (void *) MC_DVIEW_SPLIT_MORE},
{"split_less", mc_diffviewer_cmd_split_views, (void *) MC_DVIEW_SPLIT_LESS},
{"tab_size_2", mc_diffviewer_cmd_set_tab_size, (void *) 2},
{"tab_size_3", mc_diffviewer_cmd_set_tab_size, (void *) 3},
{"tab_size_4", mc_diffviewer_cmd_set_tab_size, (void *) 4},
{"tab_size_8", mc_diffviewer_cmd_set_tab_size, (void *) 8},
{"swap", mc_diffviewer_cmd_swap, NULL},
{"redo", mc_diffviewer_cmd_redo, NULL},
{"hunk_next", mc_diffviewer_cmd_hunk_next, (void *) DIFF_LEFT},
{"hunk_prev", mc_diffviewer_cmd_hunk_prev, (void *) DIFF_LEFT},
{"goto_line", mc_diffviewer_cmd_goto_line, (void *) DIFF_RIGHT},
{"edit_current", mc_diffviewer_cmd_edit, (void *) DIFF_CURRENT},
{"edit_other", mc_diffviewer_cmd_edit, (void *) DIFF_OTHER},
{"edit_left", mc_diffviewer_cmd_edit, (void *) DIFF_LEFT},
{"edit_right", mc_diffviewer_cmd_edit, (void *) DIFF_RIGHT},
{"merge_from_left_to_right", mc_diffviewer_cmd_merge, (void *) DIFF_LEFT},
{"merge_from_right_to_left", mc_diffviewer_cmd_merge, (void *) DIFF_RIGHT},
{"merge_from_current_to_other", mc_diffviewer_cmd_merge, (void *) DIFF_CURRENT},
{"merge_from_other_to_current", mc_diffviewer_cmd_merge, (void *) DIFF_OTHER},
{"search", mc_diffviewer_cmd_search, NULL},
{"continue_search", mc_diffviewer_cmd_continue_search, NULL},
{"goto_top", mc_diffviewer_cmd_goto_top, NULL},
{"goto_bottom", mc_diffviewer_cmd_goto_bottom, NULL},
{"goto_up", mc_diffviewer_cmd_goto_up, NULL},
{"goto_down", mc_diffviewer_cmd_goto_down, NULL},
{"goto_page_up", mc_diffviewer_cmd_goto_page_up, NULL},
{"goto_page_down", mc_diffviewer_cmd_goto_page_down, NULL},
{"goto_left", mc_diffviewer_cmd_goto_left, (void *) 1},
{"goto_left_quick", mc_diffviewer_cmd_goto_left, (void *) 8},
{"goto_right", mc_diffviewer_cmd_goto_right, (void *) 1},
{"goto_right_quick", mc_diffviewer_cmd_goto_right, (void *) 8},
{"goto_start_of_line", mc_diffviewer_cmd_goto_start_of_line, (void *) 8},
{"quit", mc_diffviewer_cmd_quit, (void *) 8},
{"save_changes", mc_diffviewer_cmd_save_changes, (void *) 8},
{"options_show_dialog", mc_diffviewer_cmd_options_show_dialog, NULL},
{"options_save", mc_diffviewer_cmd_options_save, NULL},
{"options_load", mc_diffviewer_cmd_options_load, NULL},
#ifdef HAVE_CHARSET
{"select_encoding_show_dialog", mc_diffviewer_cmd_select_encoding_show_dialog, NULL},
#endif /* HAVE_CHARSET */
{NULL, NULL, NULL}
};
/* *INDENT-ON* */
/* *INDENT-OFF* */
event_init_t standard_events[] =
{
{MCEVENT_GROUP_DIFFVIEWER, core_group_events},
{NULL, NULL}
};
/* *INDENT-ON* */
mc_event_mass_add (standard_events, error);
}
/* --------------------------------------------------------------------------------------------- */

643
src/diffviewer/execute.c Normal file
View File

@ -0,0 +1,643 @@
/*
Search functions for diffviewer.
Copyright (C) 2010-2014
Free Software Foundation, Inc.
Written by:
Slava Zanko <slavazanko@gmail.com>, 2010.
Andrew Borodin <aborodin@vmail.ru>, 2012
This file is part of the Midnight Commander.
The Midnight Commander 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 3 of the License,
or (at your option) any later version.
The Midnight Commander is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <config.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include "lib/global.h"
#include "lib/strescape.h" /* strutils_glob_escape() */
#include "lib/vfs/vfs.h" /* mc_opendir, mc_readdir, mc_closedir, */
#include "lib/widget.h"
#include "lib/util.h"
#include "execute.h"
/*** global variables ****************************************************************************/
/*** file scope macro definitions ****************************************************************/
#define FILE_READ_BUF 4096
#define FILE_FLAG_TEMP (1 << 0)
#define FILE_DIRTY(fs) \
do \
{ \
(fs)->pos = 0; \
(fs)->len = 0; \
} \
while (0)
/*** file scope type declarations ****************************************************************/
/*** file scope variables ************************************************************************/
/* --------------------------------------------------------------------------------------------- */
/*** file scope functions ************************************************************************/
/* --------------------------------------------------------------------------------------------- */
/**
* Free file structure without closing the file.
*
* @param fs file structure
* @return 0 on success, non-zero on error
*/
static int
f_free (FBUF * fs)
{
int rv = 0;
if (fs->flags & FILE_FLAG_TEMP)
{
rv = unlink (fs->data);
g_free (fs->data);
}
g_free (fs->buf);
g_free (fs);
return rv;
}
/* --------------------------------------------------------------------------------------------- */
/**
* Create pipe stream to process.
*
* @param cmd shell command line
* @param flags open mode, either O_RDONLY or O_WRONLY
*
* @return file structure
*/
static FBUF *
p_open (const char *cmd, int flags)
{
FILE *f;
FBUF *fs;
const char *type = NULL;
if (flags == O_RDONLY)
type = "r";
else if (flags == O_WRONLY)
type = "w";
if (type == NULL)
return NULL;
fs = mc_diffviewer_file_dopen (0);
if (fs == NULL)
return NULL;
f = popen (cmd, type);
if (f == NULL)
{
f_free (fs);
return NULL;
}
fs->fd = fileno (f);
fs->data = f;
return fs;
}
/* --------------------------------------------------------------------------------------------- */
/* diff parse *************************************************************** */
/**
* Parse line for diff statement.
*
* @param p string to parse
* @param ops list of diff statements
* @return 0 if success, otherwise non-zero
*/
static int
scan_line (const char *p, GArray * ops)
{
DIFFCMD op;
int f1, f2;
int t1, t2;
int cmd;
int range;
/* handle the following cases:
* NUMaNUM[,NUM]
* NUM[,NUM]cNUM[,NUM]
* NUM[,NUM]dNUM
* where NUM is a positive integer
*/
if (mc_diffviewer_scan_deci (&p, &f1) != 0 || f1 < 0)
return -1;
f2 = f1;
range = 0;
if (*p == ',')
{
p++;
if (mc_diffviewer_scan_deci (&p, &f2) != 0 || f2 < f1)
return -1;
range = 1;
}
cmd = *p++;
if (cmd == 'a')
{
if (range != 0)
return -1;
}
else if (cmd != 'c' && cmd != 'd')
return -1;
if (mc_diffviewer_scan_deci (&p, &t1) != 0 || t1 < 0)
return -1;
t2 = t1;
range = 0;
if (*p == ',')
{
p++;
if (mc_diffviewer_scan_deci (&p, &t2) != 0 || t2 < t1)
return -1;
range = 1;
}
if (cmd == 'd' && range != 0)
return -1;
op.a[0][0] = f1;
op.a[0][1] = f2;
op.cmd = cmd;
op.a[1][0] = t1;
op.a[1][1] = t2;
g_array_append_val (ops, op);
return 0;
}
/* --------------------------------------------------------------------------------------------- */
/**
* Parse diff output and extract diff statements.
*
* @param f stream to read from
* @param ops list of diff statements to fill
* @return positive number indicating number of hunks, otherwise negative
*/
static int
scan_diff (FBUF * f, GArray * ops)
{
int sz;
char buf[BUFSIZ];
while ((sz = mc_diffviewer_file_gets (buf, sizeof (buf) - 1, f)) != 0)
{
if (isdigit (buf[0]))
{
if (buf[sz - 1] != '\n')
return -1;
buf[sz] = '\0';
if (scan_line (buf, ops) != 0)
return -1;
continue;
}
while (buf[sz - 1] != '\n' && (sz = mc_diffviewer_file_gets (buf, sizeof (buf), f)) != 0)
;
}
return ops->len;
}
/* --------------------------------------------------------------------------------------------- */
/**
* Close pipe stream.
*
* @param fs structure
* @return 0 on success, non-zero on error
*/
static int
p_close (FBUF * fs)
{
int rv = -1;
if (fs != NULL)
{
rv = pclose (fs->data);
f_free (fs);
}
return rv;
}
/* --------------------------------------------------------------------------------------------- */
/*** public functions ****************************************************************************/
/* --------------------------------------------------------------------------------------------- */
/**
* Invoke diff and extract diff statements.
*
* @param args extra arguments to be passed to diff
* @param extra more arguments to be passed to diff
* @param file1 first file to compare
* @param file2 second file to compare
* @param ops list of diff statements to fill
*
* @return positive number indicating number of hunks, otherwise negative
*/
int
mc_diffviewer_execute (const char *args, const char *extra, const char *file1, const char *file2,
GArray * ops)
{
static const char *opt =
" --old-group-format='%df%(f=l?:,%dl)d%dE\n'"
" --new-group-format='%dea%dF%(F=L?:,%dL)\n'"
" --changed-group-format='%df%(f=l?:,%dl)c%dF%(F=L?:,%dL)\n'"
" --unchanged-group-format=''";
int rv;
FBUF *f;
char *cmd;
int code;
char *file1_esc, *file2_esc;
/* escape potential $ to avoid shell variable substitutions in popen() */
file1_esc = strutils_shell_escape (file1);
file2_esc = strutils_shell_escape (file2);
cmd = g_strdup_printf ("diff %s %s %s %s %s", args, extra, opt, file1_esc, file2_esc);
g_free (file1_esc);
g_free (file2_esc);
if (cmd == NULL)
return -1;
f = p_open (cmd, O_RDONLY);
g_free (cmd);
if (f == NULL)
return -1;
rv = scan_diff (f, ops);
code = p_close (f);
if (rv < 0 || code == -1 || !WIFEXITED (code) || WEXITSTATUS (code) == 2)
rv = -1;
return rv;
}
/* --------------------------------------------------------------------------------------------- */
/**
* Close file.
* @note if this is temporary file, it is deleted
*
* @param fs file structure
* @return 0 on success, non-zero on error
*/
int
mc_diffviewer_file_close (FBUF * fs)
{
int rv = -1;
if (fs != NULL)
{
rv = close (fs->fd);
f_free (fs);
}
return rv;
}
/* --------------------------------------------------------------------------------------------- */
/**
* Read decimal number from string.
*
* @param[in,out] str string to parse
* @param[out] n extracted number
* @return 0 if success, otherwise non-zero
*/
int
mc_diffviewer_scan_deci (const char **str, int *n)
{
const char *p = *str;
char *q;
errno = 0;
*n = strtol (p, &q, 10);
if (errno != 0 || p == q)
return -1;
*str = q;
return 0;
}
/* --------------------------------------------------------------------------------------------- */
/**
* Seek into file.
* @note avoids thrashing read cache when possible
*
* @param fs file structure
* @param off offset
* @param whence seek directive: SEEK_SET, SEEK_CUR or SEEK_END
*
* @return position in file, starting from begginning
*/
off_t
mc_diffviewer_file_seek (FBUF * fs, off_t off, int whence)
{
off_t rv;
if (fs->len && whence != SEEK_END)
{
rv = lseek (fs->fd, 0, SEEK_CUR);
if (rv != -1)
{
if (whence == SEEK_CUR)
{
whence = SEEK_SET;
off += rv - fs->len + fs->pos;
}
if (off - rv >= -fs->len && off - rv <= 0)
{
fs->pos = fs->len + off - rv;
return off;
}
}
}
rv = lseek (fs->fd, off, whence);
if (rv != -1)
FILE_DIRTY (fs);
return rv;
}
/* --------------------------------------------------------------------------------------------- */
/**
* Read a line of bytes from file until newline or EOF.
* @note does not stop on null-byte
* @note buf will not be null-terminated
*
* @param buf destination buffer
* @param size size of buffer
* @param fs file structure
*
* @return number of bytes read
*/
size_t
mc_diffviewer_file_gets (char *buf, size_t size, FBUF * fs)
{
size_t j = 0;
do
{
int i;
int stop = 0;
for (i = fs->pos; j < size && i < fs->len && !stop; i++, j++)
{
buf[j] = fs->buf[i];
if (buf[j] == '\n')
stop = 1;
}
fs->pos = i;
if (j == size || stop)
break;
fs->pos = 0;
fs->len = read (fs->fd, fs->buf, FILE_READ_BUF);
}
while (fs->len > 0);
return j;
}
/* --------------------------------------------------------------------------------------------- */
/**
* Seek to the beginning of file, thrashing read cache.
*
* @param fs file structure
*
* @return 0 if success, non-zero on error
*/
off_t
mc_diffviewer_file_reset (FBUF * fs)
{
off_t rv;
rv = lseek (fs->fd, 0, SEEK_SET);
if (rv != -1)
FILE_DIRTY (fs);
return rv;
}
/* --------------------------------------------------------------------------------------------- */
/**
* Open a binary file in specified mode.
*
* @param filename file name
* @param flags open mode, a combination of O_RDONLY, O_WRONLY, O_RDWR
*
* @return file structure
*/
FBUF *
mc_diffviewer_file_open (const char *filename, int flags)
{
int fd;
FBUF *fs;
fs = mc_diffviewer_file_dopen (0);
if (fs == NULL)
return NULL;
fd = open (filename, flags);
if (fd < 0)
{
f_free (fs);
return NULL;
}
fs->fd = fd;
return fs;
}
/* --------------------------------------------------------------------------------------------- */
/**
* Write bytes to file.
* @note thrashes read cache
*
* @param fs file structure
* @param buf source buffer
* @param size size of buffer
*
* @return number of written bytes, -1 on error
*/
ssize_t
mc_diffviewer_file_write (FBUF * fs, const char *buf, size_t size)
{
ssize_t rv;
rv = write (fs->fd, buf, size);
if (rv >= 0)
FILE_DIRTY (fs);
return rv;
}
/* --------------------------------------------------------------------------------------------- */
/**
* Truncate file to the current position.
* @note thrashes read cache
*
* @param fs file structure
*
* @return current file size on success, negative on error
*/
off_t
mc_diffviewer_file_trunc (FBUF * fs)
{
off_t off;
off = lseek (fs->fd, 0, SEEK_CUR);
if (off != -1)
{
int rv;
rv = ftruncate (fs->fd, off);
if (rv != 0)
off = -1;
else
FILE_DIRTY (fs);
}
return off;
}
/* --------------------------------------------------------------------------------------------- */
/**
* Alocate file structure and associate file descriptor to it.
*
* @param fd file descriptor
* @return file structure
*/
FBUF *
mc_diffviewer_file_dopen (int fd)
{
FBUF *fs;
if (fd < 0)
return NULL;
fs = g_try_malloc (sizeof (FBUF));
if (fs == NULL)
return NULL;
fs->buf = g_try_malloc (FILE_READ_BUF);
if (fs->buf == NULL)
{
g_free (fs);
return NULL;
}
fs->fd = fd;
FILE_DIRTY (fs);
fs->flags = 0;
fs->data = NULL;
return fs;
}
/* --------------------------------------------------------------------------------------------- */
/**
* Try to open a temporary file.
* @note the name is not altered if this function fails
*
* @param[out] name address of a pointer to store the temporary name
* @return file descriptor on success, negative on error
*/
static int
open_temp (void **name)
{
int fd;
vfs_path_t *diff_file_name = NULL;
fd = mc_mkstemps (&diff_file_name, "mcdiff", NULL);
if (fd == -1)
{
message (D_ERROR, MSG_ERROR,
_("Cannot create temporary diff file\n%s"), unix_error_string (errno));
return -1;
}
*name = g_strdup (vfs_path_as_str (diff_file_name));
vfs_path_free (diff_file_name);
return fd;
}
/* --------------------------------------------------------------------------------------------- */
/**
* Open a binary temporary file in R/W mode.
* @note the file will be deleted when closed
*
* @return file structure
*/
FBUF *
mc_diffviewer_file_temp (void)
{
int fd;
FBUF *fs;
fs = mc_diffviewer_file_dopen (0);
if (fs == NULL)
return NULL;
fd = open_temp (&fs->data);
if (fd < 0)
{
f_free (fs);
return NULL;
}
fs->fd = fd;
fs->flags = FILE_FLAG_TEMP;
return fs;
}
/* --------------------------------------------------------------------------------------------- */

45
src/diffviewer/execute.h Normal file
View File

@ -0,0 +1,45 @@
#ifndef MC__DIFFVIEW_EXECUTE_H
#define MC__DIFFVIEW_EXECUTE_H
/*** typedefs(not structures) and defined constants **********************************************/
/*** enums ***************************************************************************************/
/*** structures declarations (and typedefs of structures)*****************************************/
typedef struct
{
int fd;
int pos;
int len;
char *buf;
int flags;
void *data;
} FBUF;
typedef struct
{
int a[2][2];
int cmd;
} DIFFCMD;
/*** global variables defined in .c file *********************************************************/
/*** declarations of public functions ************************************************************/
int mc_diffviewer_scan_deci (const char **str, int *n);
int mc_diffviewer_file_close (FBUF * fs);
int mc_diffviewer_execute (const char *args, const char *extra, const char *file1,
const char *file2, GArray * ops);
off_t mc_diffviewer_file_seek (FBUF * fs, off_t off, int whence);
size_t mc_diffviewer_file_gets (char *buf, size_t size, FBUF * fs);
off_t mc_diffviewer_file_reset (FBUF * fs);
FBUF *mc_diffviewer_file_open (const char *filename, int flags);
ssize_t mc_diffviewer_file_write (FBUF * fs, const char *buf, size_t size);
off_t mc_diffviewer_file_trunc (FBUF * fs);
FBUF *mc_diffviewer_file_dopen (int fd);
FBUF *mc_diffviewer_file_temp (void);
/*** inline functions ****************************************************************************/
#endif /* MC__DIFFVIEW_EXECUTE_H */

View File

@ -7,6 +7,8 @@
#include "lib/tty/color.h" #include "lib/tty/color.h"
#include "lib/widget.h" #include "lib/widget.h"
#include "execute.h"
/*** typedefs(not structures) and defined constants **********************************************/ /*** typedefs(not structures) and defined constants **********************************************/
typedef int (*DFUNC) (void *ctx, int ch, int line, off_t off, size_t sz, const char *str); typedef int (*DFUNC) (void *ctx, int ch, int line, off_t off, size_t sz, const char *str);
@ -14,6 +16,11 @@ typedef int PAIR[2];
#define error_dialog(h, s) query_dialog(h, s, D_ERROR, 1, _("&Dismiss")) #define error_dialog(h, s) query_dialog(h, s, D_ERROR, 1, _("&Dismiss"))
#define ADD_CH '+'
#define DEL_CH '-'
#define CHG_CH '*'
#define EQU_CH ' '
/*** enums ***************************************************************************************/ /*** enums ***************************************************************************************/
typedef enum typedef enum
@ -27,7 +34,9 @@ typedef enum
{ {
DIFF_LEFT = 0, DIFF_LEFT = 0,
DIFF_RIGHT = 1, DIFF_RIGHT = 1,
DIFF_COUNT = 2 DIFF_COUNT = 2,
DIFF_CURRENT = 3,
DIFF_OTHER = 4
} diff_place_t; } diff_place_t;
typedef enum typedef enum
@ -40,23 +49,6 @@ typedef enum
/*** structures declarations (and typedefs of structures)*****************************************/ /*** structures declarations (and typedefs of structures)*****************************************/
typedef struct
{
int fd;
int pos;
int len;
char *buf;
int flags;
void *data;
} FBUF;
typedef struct
{
int a[2][2];
int cmd;
} DIFFCMD;
typedef struct typedef struct
{ {
int off; int off;
@ -146,8 +138,32 @@ typedef struct WDiff
/*** declarations of public functions ************************************************************/ /*** declarations of public functions ************************************************************/
void mc_diffviewer_init_events (GError ** error);
/* search.c */ /* search.c */
void dview_search_cmd (WDiff * dview); gboolean mc_diffviewer_cmd_search (const gchar * event_group_name, const gchar * event_name,
void dview_continue_search_cmd (WDiff * dview); gpointer init_data, gpointer data);
gboolean mc_diffviewer_cmd_continue_search (const gchar * event_group_name,
const gchar * event_name, gpointer init_data,
gpointer data);
int mc_diffviewer_calc_nwidth (const GArray ** const a);
void mc_diffviewer_compute_split (WDiff * dview, int i);
int mc_diffviewer_get_line_numbers (const GArray * a, size_t pos, int *linenum, int *lineofs);
void mc_diffviewer_reread (WDiff * dview);
void mc_diffviewer_update (WDiff * dview);
void mc_diffviewer_destroy_hdiff (WDiff * dview);
void mc_diffviewer_deinit (WDiff * dview);
int mc_diffviewer_redo_diff (WDiff * dview);
gboolean mc_diffviewer_cmd_merge (const gchar * event_group_name, const gchar * event_name,
gpointer init_data, gpointer data);
gboolean mc_diffviewer_cmd_run (const gchar * event_group_name, const gchar * event_name,
gpointer init_data, gpointer data);
/*** inline functions ****************************************************************************/
#endif /* MC__DIFFVIEW_INTERNAL_H */ #endif /* MC__DIFFVIEW_INTERNAL_H */

183
src/diffviewer/options.c Normal file
View File

@ -0,0 +1,183 @@
/*
Search functions for diffviewer.
Copyright (C) 2010-2014
Free Software Foundation, Inc.
Written by:
Slava Zanko <slavazanko@gmail.com>, 2010.
Andrew Borodin <aborodin@vmail.ru>, 2012
This file is part of the Midnight Commander.
The Midnight Commander 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 3 of the License,
or (at your option) any later version.
The Midnight Commander is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <config.h>
#include <stdio.h>
#include "lib/global.h"
#include "lib/strutil.h"
#include "lib/tty/key.h"
#include "lib/widget.h"
#include "src/history.h"
#include "internal.h"
#include "options.h"
/*** global variables ****************************************************************************/
/*** file scope macro definitions ****************************************************************/
/*** file scope type declarations ****************************************************************/
/*** file scope variables ************************************************************************/
/* --------------------------------------------------------------------------------------------- */
/*** file scope functions ************************************************************************/
/* --------------------------------------------------------------------------------------------- */
/* --------------------------------------------------------------------------------------------- */
/*** public functions ****************************************************************************/
/* --------------------------------------------------------------------------------------------- */
/* event callback */
gboolean
mc_diffviewer_cmd_options_save (const gchar * event_group_name, const gchar * event_name,
gpointer init_data, gpointer data)
{
WDiff *dview = (WDiff *) data;
(void) event_group_name;
(void) event_name;
(void) init_data;
mc_config_set_bool (mc_main_config, "DiffView", "show_symbols",
dview->display_symbols != 0 ? TRUE : FALSE);
mc_config_set_bool (mc_main_config, "DiffView", "show_numbers",
dview->display_numbers != 0 ? TRUE : FALSE);
mc_config_set_int (mc_main_config, "DiffView", "tab_size", dview->tab_size);
mc_config_set_int (mc_main_config, "DiffView", "diff_quality", dview->opt.quality);
mc_config_set_bool (mc_main_config, "DiffView", "diff_ignore_tws",
dview->opt.strip_trailing_cr);
mc_config_set_bool (mc_main_config, "DiffView", "diff_ignore_all_space",
dview->opt.ignore_all_space);
mc_config_set_bool (mc_main_config, "DiffView", "diff_ignore_space_change",
dview->opt.ignore_space_change);
mc_config_set_bool (mc_main_config, "DiffView", "diff_tab_expansion",
dview->opt.ignore_tab_expansion);
mc_config_set_bool (mc_main_config, "DiffView", "diff_ignore_case", dview->opt.ignore_case);
return TRUE;
}
/* --------------------------------------------------------------------------------------------- */
/* event callback */
gboolean
mc_diffviewer_cmd_options_load (const gchar * event_group_name, const gchar * event_name,
gpointer init_data, gpointer data)
{
gboolean show_numbers, show_symbols;
int tab_size;
WDiff *dview = (WDiff *) data;
(void) event_group_name;
(void) event_name;
(void) init_data;
show_symbols = mc_config_get_bool (mc_main_config, "DiffView", "show_symbols", FALSE);
if (show_symbols)
dview->display_symbols = 1;
show_numbers = mc_config_get_bool (mc_main_config, "DiffView", "show_numbers", FALSE);
if (show_numbers)
dview->display_numbers = mc_diffviewer_calc_nwidth ((const GArray ** const) dview->a);
tab_size = mc_config_get_int (mc_main_config, "DiffView", "tab_size", 8);
if (tab_size > 0 && tab_size < 9)
dview->tab_size = tab_size;
else
dview->tab_size = 8;
dview->opt.quality = mc_config_get_int (mc_main_config, "DiffView", "diff_quality", 0);
dview->opt.strip_trailing_cr =
mc_config_get_bool (mc_main_config, "DiffView", "diff_ignore_tws", FALSE);
dview->opt.ignore_all_space =
mc_config_get_bool (mc_main_config, "DiffView", "diff_ignore_all_space", FALSE);
dview->opt.ignore_space_change =
mc_config_get_bool (mc_main_config, "DiffView", "diff_ignore_space_change", FALSE);
dview->opt.ignore_tab_expansion =
mc_config_get_bool (mc_main_config, "DiffView", "diff_tab_expansion", FALSE);
dview->opt.ignore_case =
mc_config_get_bool (mc_main_config, "DiffView", "diff_ignore_case", FALSE);
dview->new_frame = 1;
return TRUE;
}
/* --------------------------------------------------------------------------------------------- */
/* event callback */
gboolean
mc_diffviewer_cmd_options_show_dialog (const gchar * event_group_name, const gchar * event_name,
gpointer init_data, gpointer data)
{
WDiff *dview = (WDiff *) data;
const char *quality_str[] = {
N_("No&rmal"),
N_("&Fastest (Assume large files)"),
N_("&Minimal (Find a smaller set of change)")
};
quick_widget_t quick_widgets[] = {
/* *INDENT-OFF* */
QUICK_START_GROUPBOX (N_("Diff algorithm")),
QUICK_RADIO (3, (const char **) quality_str, (int *) &dview->opt.quality, NULL),
QUICK_STOP_GROUPBOX,
QUICK_START_GROUPBOX (N_("Diff extra options")),
QUICK_CHECKBOX (N_("&Ignore case"), &dview->opt.ignore_case, NULL),
QUICK_CHECKBOX (N_("Ignore tab &expansion"), &dview->opt.ignore_tab_expansion, NULL),
QUICK_CHECKBOX (N_("Ignore &space change"), &dview->opt.ignore_space_change, NULL),
QUICK_CHECKBOX (N_("Ignore all &whitespace"), &dview->opt.ignore_all_space, NULL),
QUICK_CHECKBOX (N_("Strip &trailing carriage return"), &dview->opt.strip_trailing_cr,
NULL),
QUICK_STOP_GROUPBOX,
QUICK_BUTTONS_OK_CANCEL,
QUICK_END
/* *INDENT-ON* */
};
quick_dialog_t qdlg = {
-1, -1, 56,
N_("Diff Options"), "[Diff Options]",
quick_widgets, NULL, NULL
};
(void) event_group_name;
(void) event_name;
(void) init_data;
if (quick_dialog (&qdlg) != B_CANCEL)
mc_diffviewer_reread (dview);
return TRUE;
}
/* --------------------------------------------------------------------------------------------- */

26
src/diffviewer/options.h Normal file
View File

@ -0,0 +1,26 @@
#ifndef MC__DIFFVIEW_OPTIONS_H
#define MC__DIFFVIEW_OPTIONS_H
/*** typedefs(not structures) and defined constants **********************************************/
/*** enums ***************************************************************************************/
/*** structures declarations (and typedefs of structures)*****************************************/
/*** global variables defined in .c file *********************************************************/
/*** declarations of public functions ************************************************************/
gboolean mc_diffviewer_cmd_options_save (const gchar * event_group_name, const gchar * event_name,
gpointer init_data, gpointer data);
gboolean mc_diffviewer_cmd_options_load (const gchar * event_group_name, const gchar * event_name,
gpointer init_data, gpointer data);
gboolean mc_diffviewer_cmd_options_show_dialog (const gchar * event_group_name,
const gchar * event_name, gpointer init_data,
gpointer data);
/*** inline functions ****************************************************************************/
#endif /* MC__DIFFVIEW_OPTIONS_H */

View File

@ -236,18 +236,26 @@ mcdiffview_do_search (WDiff * dview)
/* --------------------------------------------------------------------------------------------- */ /* --------------------------------------------------------------------------------------------- */
/*** public functions ****************************************************************************/ /*** public functions ****************************************************************************/
/* --------------------------------------------------------------------------------------------- */ /* --------------------------------------------------------------------------------------------- */
/* event callback */
void gboolean
dview_search_cmd (WDiff * dview) mc_diffviewer_cmd_search (const gchar * event_group_name, const gchar * event_name,
gpointer init_data, gpointer data)
{ {
WDiff *dview = (WDiff *) data;
(void) event_group_name;
(void) event_name;
(void) init_data;
if (dview->dsrc != DATA_SRC_MEM) if (dview->dsrc != DATA_SRC_MEM)
{ {
error_dialog (_("Search"), _("Search is disabled")); error_dialog (_("Search"), _("Search is disabled"));
return; return FALSE;
} }
if (!mcdiffview_dialog_search (dview)) if (!mcdiffview_dialog_search (dview))
return; return TRUE;
mc_search_free (dview->search.handle); mc_search_free (dview->search.handle);
#ifdef HAVE_CHARSET #ifdef HAVE_CHARSET
@ -257,7 +265,7 @@ dview_search_cmd (WDiff * dview)
#endif #endif
if (dview->search.handle == NULL) if (dview->search.handle == NULL)
return; return TRUE;
dview->search.handle->search_type = mcdiffview_search_options.type; dview->search.handle->search_type = mcdiffview_search_options.type;
#ifdef HAVE_CHARSET #ifdef HAVE_CHARSET
@ -267,19 +275,27 @@ dview_search_cmd (WDiff * dview)
dview->search.handle->whole_words = mcdiffview_search_options.whole_words; dview->search.handle->whole_words = mcdiffview_search_options.whole_words;
mcdiffview_do_search (dview); mcdiffview_do_search (dview);
return TRUE;
} }
/* --------------------------------------------------------------------------------------------- */ /* --------------------------------------------------------------------------------------------- */
/* event callback */
void gboolean
dview_continue_search_cmd (WDiff * dview) mc_diffviewer_cmd_continue_search (const gchar * event_group_name, const gchar * event_name,
gpointer init_data, gpointer data)
{ {
WDiff *dview = (WDiff *) data;
if (dview->dsrc != DATA_SRC_MEM) if (dview->dsrc != DATA_SRC_MEM)
error_dialog (_("Search"), _("Search is disabled")); error_dialog (_("Search"), _("Search is disabled"));
else if (dview->search.handle == NULL) else if (dview->search.handle == NULL)
dview_search_cmd (dview); return mc_diffviewer_cmd_search (event_group_name, event_name, init_data, data);
else else
mcdiffview_do_search (dview); mcdiffview_do_search (dview);
return TRUE;
} }
/* --------------------------------------------------------------------------------------------- */ /* --------------------------------------------------------------------------------------------- */

2002
src/diffviewer/tools.c Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,16 +1,40 @@
#ifndef MC__DIFFVIEW_YDIFF_H #ifndef MC__DIFFVIEW_YDIFF_H
#define MC__DIFFVIEW_YDIFF_H #define MC__DIFFVIEW_YDIFF_H
#include "src/filemanager/panel.h"
/*** typedefs(not structures) and defined constants **********************************************/ /*** typedefs(not structures) and defined constants **********************************************/
/*** enums ***************************************************************************************/ /*** enums ***************************************************************************************/
/*** structures declarations (and typedefs of structures)*****************************************/ /*** structures declarations (and typedefs of structures)*****************************************/
typedef struct
{
mc_run_mode_t run_mode;
gboolean ret_value;
union
{
struct
{
WPanel *first;
WPanel *second;
} panel;
struct
{
const char *first;
const char *second;
} file;
} data;
} ev_diffviewer_run_t;
/*** global variables defined in .c file *********************************************************/ /*** global variables defined in .c file *********************************************************/
/*** declarations of public functions ************************************************************/ /*** declarations of public functions ************************************************************/
gboolean dview_diff_cmd (const void *f0, const void *f1); void mc_diffviewer_init (GError ** error);
/*** inline functions ****************************************************************************/
#endif /* MC__DIFFVIEW_YDIFF_H */ #endif /* MC__DIFFVIEW_YDIFF_H */

View File

@ -1181,14 +1181,17 @@ compare_dirs_cmd (void)
void void
diff_view_cmd (void) diff_view_cmd (void)
{ {
ev_diffviewer_run_t event_info;
/* both panels must be in the list mode */ /* both panels must be in the list mode */
if (get_current_type () != view_listing || get_other_type () != view_listing) if (get_current_type () != view_listing || get_other_type () != view_listing)
return; return;
if (get_current_index () == 0) event_info.run_mode = mc_global.mc_run_mode;
dview_diff_cmd (current_panel, other_panel); event_info.data.panel.first = current_panel;
else event_info.data.panel.second = other_panel;
dview_diff_cmd (other_panel, current_panel);
mc_event_raise (MCEVENT_GROUP_DIFFVIEWER, "run", &event_info);
if (mc_global.mc_run_mode == MC_RUN_FULL) if (mc_global.mc_run_mode == MC_RUN_FULL)
update_panels (UP_OPTIMIZE, UP_KEEPSEL); update_panels (UP_OPTIMIZE, UP_KEEPSEL);

View File

@ -1007,7 +1007,16 @@ mc_maybe_editor_or_viewer (void)
} }
#ifdef USE_DIFF_VIEW #ifdef USE_DIFF_VIEW
case MC_RUN_DIFFVIEWER: case MC_RUN_DIFFVIEWER:
ret = dview_diff_cmd (mc_run_param0, mc_run_param1); {
ev_diffviewer_run_t event_info;
event_info.run_mode = mc_global.mc_run_mode;
event_info.data.file.first = mc_run_param0;
event_info.data.file.second = mc_run_param1;
mc_event_raise (MCEVENT_GROUP_DIFFVIEWER, "run", &event_info);
ret = event_info.ret_value;
}
break; break;
#endif /* USE_DIFF_VIEW */ #endif /* USE_DIFF_VIEW */
default: default:
@ -1736,7 +1745,7 @@ quiet_quit_cmd (void)
/** Run the main dialog that occupies the whole screen */ /** Run the main dialog that occupies the whole screen */
gboolean gboolean
do_nc (void) do_nc (GError ** error)
{ {
gboolean ret; gboolean ret;
@ -1744,6 +1753,10 @@ do_nc (void)
edit_stack_init (); edit_stack_init ();
#endif #endif
#ifdef USE_DIFF_VIEW
mc_diffviewer_init (error);
#endif
midnight_dlg = dlg_create (FALSE, 0, 0, LINES, COLS, dialog_colors, midnight_callback, midnight_dlg = dlg_create (FALSE, 0, 0, LINES, COLS, dialog_colors, midnight_callback,
midnight_event, "[main]", NULL, DLG_NONE); midnight_event, "[main]", NULL, DLG_NONE);

View File

@ -45,7 +45,7 @@ void load_hint (gboolean force);
void change_panel (void); void change_panel (void);
void save_cwds_stat (void); void save_cwds_stat (void);
gboolean quiet_quit_cmd (void); gboolean quiet_quit_cmd (void);
gboolean do_nc (void); gboolean do_nc (GError **);
/*** inline functions ****************************************************************************/ /*** inline functions ****************************************************************************/

View File

@ -415,7 +415,14 @@ main (int argc, char *argv[])
if (mc_global.midnight_shutdown) if (mc_global.midnight_shutdown)
exit_code = EXIT_SUCCESS; exit_code = EXIT_SUCCESS;
else else
exit_code = do_nc ()? EXIT_SUCCESS : EXIT_FAILURE; exit_code = do_nc (&error) ? EXIT_SUCCESS : EXIT_FAILURE;
if (error != NULL)
{
message (D_ERROR, _("Warning"), "%s", error->message);
g_error_free (error);
error = NULL;
}
/* Save the tree store */ /* Save the tree store */
(void) tree_store_save (); (void) tree_store_save ();