1
1

Viewer works; Entry widgets are synced with selection;

panel fills properly (fixes a bunch of file operations); more dialog
boxes exported to the gnome edition -mig
Этот коммит содержится в:
Miguel de Icaza 1998-03-12 03:29:45 +00:00
родитель 11099ee712
Коммит ad1610c2e3
17 изменённых файлов: 574 добавлений и 394 удалений

Просмотреть файл

@ -1,3 +1,15 @@
Wed Mar 11 15:28:45 1998 Miguel de Icaza <miguel@nuclecu.unam.mx>
* gwidget.c (entry_release): Now the WEntrys track the current
selection.p
(x_update_input): Repaint the widget after changing the position.
* gscreen.c (x_fill_panel): Remember the selected item on the
panel before filling it up, as gtk_clist emits a select_item
signal when filling it up, which changes the current selection
(and thus some routines that invoke the reload panel option
fail).
1998-03-11 Federico Mena Quintero <federico@nuclecu.unam.mx>
* gmc-chargrid.c (gmc_char_grid_get_size): New public function.
@ -16,8 +28,6 @@
Tue Mar 10 23:46:29 1998 Miguel de Icaza <miguel@nuclecu.unam.mx>
* glayout.c
* gscreen.c (x_adjust_top_file): We no longer adjust the top
displayed filename.

Просмотреть файл

@ -27,6 +27,7 @@ GNOMESRCS = \
gdesktop.c \
gutil.c \
gtrans.c \
gview.c \
gmc-chargrid.c
GNOMEHDRS = \
@ -54,7 +55,7 @@ OOBJS = main.o dlg.o screen.o widget.o wtools.o info.o boxes.o \
OBJS = $(LOBJS) $(OOBJS) \
gkey.o gmain.o gscreen.o gwidget.o gmenu.o ghelp.o ginfo.o \
glayout.o gtools.o gdesktop.o gtrans.o gutil.o gmc-chargrid.o
glayout.o gtools.o gdesktop.o gtrans.o gutil.o gmc-chargrid.o gview.o
#
# Distribution variables

Просмотреть файл

@ -20,6 +20,8 @@
#define PORT_HAS_BACKTAB_CHAR 1
#define PORT_NOT_FOCUS_SELECT_ITEM 1
#define PORT_NOT_UNFOCUS_UNSELECT_ITEM 1
#define PORT_WANTS_VIEW 1
#define PORT_HAS_VIEW_FREEZE 1
#define mi_getch() fprintf (stderr, "mi_getch is not implemented in this port\n")
#define frontend_run_dlg(x) gtkrundlg_event (x)

Просмотреть файл

@ -29,6 +29,8 @@ struct gmc_color_pairs_s gmc_color_pairs [MAX_COLOR_PAIRS];
char *default_edition_colors =
"normal=black:"
"selected=red:"
"viewunderline=brightred,blue:"
"directory=blue:"
"marked=white,seagreen:"
"execute=slateblue:"

Просмотреть файл

@ -19,8 +19,8 @@
#define ATTRS(cgrid) ((struct attr *) cgrid->attrs)
struct attr {
gulong fg;
gulong bg;
GdkColor *fg;
GdkColor *bg;
};
@ -256,6 +256,7 @@ update_strip (GmcCharGrid *cgrid, int x, int y, int width)
struct attr *attrs;
int first;
gulong color;
gulong ocolor;
GdkColor gcolor;
chars = CHARS (cgrid) + (cgrid->width * y + x);
@ -269,11 +270,12 @@ update_strip (GmcCharGrid *cgrid, int x, int y, int width)
while (i < width) {
first = i;
color = attrs[i].bg;
ocolor = attrs[i].bg ? attrs[i].bg->pixel : GTK_WIDGET (cgrid)->style->bg[GTK_STATE_NORMAL].pixel;
color = ocolor;
do {
i++;
} while ((i < width) && (color == attrs[i].bg));
} while ((i < width) && (color == ocolor));
gcolor.pixel = color;
gdk_gc_set_foreground (cgrid->gc, &gcolor);
@ -293,11 +295,12 @@ update_strip (GmcCharGrid *cgrid, int x, int y, int width)
while (i < width) {
first = i;
color = attrs[i].fg;
ocolor = attrs[i].fg ? attrs[i].fg->pixel : GTK_WIDGET (cgrid)->style->fg[GTK_STATE_NORMAL].pixel;
color = ocolor;
do {
i++;
} while ((i < width) && (color == attrs[i].fg));
} while ((i < width) && (color == ocolor));
gcolor.pixel = color;
gdk_gc_set_foreground (cgrid->gc, &gcolor);
@ -343,18 +346,19 @@ gmc_char_grid_expose (GtkWidget *widget, GdkEventExpose *event)
x2 = (event->area.x + event->area.width) / cgrid->char_width;
y2 = (event->area.y + event->area.height) / cgrid->char_height;
update_region (cgrid, x1, y1, (x2 - x1) + 1, (y2 - y1) + 1);
update_region (cgrid, x1, y1, (x2 - x1) + 1, (y2 - y1));
}
return FALSE;
}
void
gmc_char_grid_clear (GmcCharGrid *cgrid, int x, int y, int width, int height)
gmc_char_grid_clear (GmcCharGrid *cgrid, int x, int y, int width, int height, GdkColor *bg)
{
int x1, y1, x2, y2;
int xx, yy;
char *ch;
struct attr *attrs;
g_return_if_fail (cgrid != NULL);
g_return_if_fail (GMC_IS_CHAR_GRID (cgrid));
@ -364,13 +368,28 @@ gmc_char_grid_clear (GmcCharGrid *cgrid, int x, int y, int width, int height)
x2 = MIN (x + width, cgrid->width);
y2 = MIN (y + height, cgrid->height);
ch = CHARS (cgrid) + (y1 * cgrid->width + x1);
ch = CHARS (cgrid) + (y1 * cgrid->width);
attrs = ATTRS (cgrid) + (y1 * cgrid->width);
for (yy = y1; yy < y2; yy++) {
for (xx = x1; xx < x2; xx++)
for (xx = x1; xx < x2; xx++) {
ch[xx] = ' ';
if (bg) {
if (!attrs[xx].bg)
attrs[xx].bg = g_new (GdkColor, 1);
*attrs[xx].bg = *bg;
} else {
if (attrs[xx].bg)
g_free (attrs[xx].bg);
attrs[xx].bg = NULL;
}
}
ch += cgrid->width;
attrs += cgrid->width;
}
if (GTK_WIDGET_DRAWABLE (cgrid) && !cgrid->frozen)
@ -378,10 +397,11 @@ gmc_char_grid_clear (GmcCharGrid *cgrid, int x, int y, int width, int height)
}
void
gmc_char_grid_put_char (GmcCharGrid *cgrid, int x, int y, gulong fg_pixel, gulong bg_pixel, char ch)
gmc_char_grid_put_char (GmcCharGrid *cgrid, int x, int y, GdkColor *fg, GdkColor *bg, char ch)
{
char *chars;
struct attr *attrs;
int idx;
g_return_if_fail (cgrid != NULL);
g_return_if_fail (GMC_IS_CHAR_GRID (cgrid));
@ -390,31 +410,55 @@ gmc_char_grid_put_char (GmcCharGrid *cgrid, int x, int y, gulong fg_pixel, gulon
|| (y < 0) || (y >= cgrid->height))
return;
chars = CHARS (cgrid);
attrs = ATTRS (cgrid);
idx = y * cgrid->width + x;
chars[y * cgrid->width + x] = ch;
attrs[y * cgrid->width + x].fg = fg_pixel;
attrs[y * cgrid->width + x].bg = bg_pixel;
chars = CHARS (cgrid) + idx;
attrs = ATTRS (cgrid) + idx;
*chars = ch;
if (fg) {
if (!attrs->fg)
attrs->fg = g_new (GdkColor, 1);
*attrs->fg = *fg;
} else {
if (attrs->fg)
g_free (attrs->fg);
attrs->fg = NULL;
}
if (bg) {
if (!attrs->bg)
attrs->bg = g_new (GdkColor, 1);
*attrs->bg = *bg;
} else {
if (attrs->bg)
g_free (attrs->bg);
attrs->bg = NULL;
}
if (GTK_WIDGET_DRAWABLE (cgrid) && !cgrid->frozen)
update_region (cgrid, x, y, 1, 1);
}
void
gmc_char_grid_put_string (GmcCharGrid *cgrid, int x, int y, gulong fg_pixel, gulong bg_pixel, char *str)
gmc_char_grid_put_string (GmcCharGrid *cgrid, int x, int y, GdkColor *fg, GdkColor *bg, char *str)
{
g_return_if_fail (str != NULL);
gmc_char_grid_put_text (cgrid, x, y, fg_pixel, bg_pixel, str, strlen (str));
gmc_char_grid_put_text (cgrid, x, y, fg, bg, str, strlen (str));
}
void
gmc_char_grid_put_text (GmcCharGrid *cgrid, int x, int y, gulong fg_pixel, gulong bg_pixel, char *text, int length)
gmc_char_grid_put_text (GmcCharGrid *cgrid, int x, int y, GdkColor *fg, GdkColor *bg, char *text, int length)
{
char *chars;
struct attr *attrs;
int i, pos;
int i, pos, idx;
g_return_if_fail (cgrid != NULL);
g_return_if_fail (GMC_IS_CHAR_GRID (cgrid));
@ -429,8 +473,31 @@ gmc_char_grid_put_text (GmcCharGrid *cgrid, int x, int y, gulong fg_pixel, gulon
for (i = 0, pos = x; (i < length) && (pos < cgrid->width); i++, pos++) {
*chars++ = *text++;
attrs->fg = fg_pixel;
attrs->bg = bg_pixel;
if (fg) {
if (!attrs->fg)
attrs->fg = g_new (GdkColor, 1);
*attrs->fg = *fg;
} else {
if (attrs->fg)
g_free (attrs->fg);
attrs->fg = NULL;
}
if (bg) {
if (!attrs->bg)
attrs->bg = g_new (GdkColor, 1);
*attrs->bg = *bg;
} else {
if (attrs->bg)
g_free (attrs->bg);
attrs->bg = NULL;
}
attrs++;
}
@ -540,8 +607,8 @@ gmc_char_grid_real_size_changed (GmcCharGrid *cgrid, guint width, guint height)
for (i = 0; i < (width * height); i++) {
chars[i] = ' ';
attrs[i].fg = 0;
attrs[i].bg = 0;
attrs[i].fg = NULL;
attrs[i].bg = NULL;
}
gtk_widget_queue_resize (GTK_WIDGET (cgrid));

Просмотреть файл

@ -9,6 +9,7 @@
#define GMC_CHARGRID_H
#include <gdk/gdk.h>
#include <gtk/gtkwidget.h>
#include <libgnome/gnome-defs.h>
@ -53,13 +54,10 @@ struct _GmcCharGridClass {
guint gmc_char_grid_get_type (void);
GtkWidget *gmc_char_grid_new (void);
void gmc_char_grid_clear (GmcCharGrid *cgrid, int x, int y, int width, int height);
void gmc_char_grid_put_char (GmcCharGrid *cgrid, int x, int y, gulong fg_pixel, gulong bg_pixel,
char ch);
void gmc_char_grid_put_string (GmcCharGrid *cgrid, int x, int y, gulong fg_pixel, gulong bg_pixel,
char *str);
void gmc_char_grid_put_text (GmcCharGrid *cgrid, int x, int y, gulong fg_pixel, gulong bg_pixel,
char *text, int length);
void gmc_char_grid_clear (GmcCharGrid *cgrid, int x, int y, int width, int height, GdkColor *bg);
void gmc_char_grid_put_char (GmcCharGrid *cgrid, int x, int y, GdkColor *fg, GdkColor *bg, char ch);
void gmc_char_grid_put_string (GmcCharGrid *cgrid, int x, int y, GdkColor *fg, GdkColor *bg, char *str);
void gmc_char_grid_put_text (GmcCharGrid *cgrid, int x, int y, GdkColor *fg, GdkColor *bg, char *text, int length);
void gmc_char_grid_set_font (GmcCharGrid *cgrid, const char *font_name);
void gmc_char_grid_set_size (GmcCharGrid *cgrid, guint width, guint height);

Просмотреть файл

@ -95,6 +95,7 @@ x_fill_panel (WPanel *panel)
{
const int top = panel->count;
const int items = panel->format->items;
const int selected = panel->selected;
GtkCList *cl = GTK_CLIST (panel->list);
int i, col, type_col, color;
char **texts;
@ -132,6 +133,9 @@ x_fill_panel (WPanel *panel)
if (type_col != -1)
panel_file_list_set_type_bitmap (cl, i, type_col, color, fe);
}
/* This is needed as the gtk_clist_append changes selected under us :-( */
panel->selected = selected;
select_item (panel);
gtk_clist_thaw (GTK_CLIST (cl));
free (texts);
}
@ -332,6 +336,8 @@ static struct {
{ "Rename/move..", (context_menu_callback) ren_cmd },
{ "Delete...", (context_menu_callback) delete_cmd },
{ "Link...", (context_menu_callback) link_cmd },
{ "Symlink...", (context_menu_callback) symlink_cmd },
{ "Edit symlink...", (context_menu_callback) edit_symlink_cmd },
{ NULL, NULL },
};
@ -738,10 +744,8 @@ panel_realized (GtkWidget *file_list, WPanel *panel)
if (drag_directory && drag_directory_ok){
gtk_widget_show (drag_directory_ok);
gtk_widget_show (drag_directory);
#if 0
gdk_dnd_set_drag_shape (drag_directory->window, &hotspot,
drag_directory_ok->window, &hotspot);
#endif
}
/* DND: Drag setup */

Просмотреть файл

@ -161,6 +161,14 @@ entry_click (GtkWidget *widget, GdkEvent *event, WInput *in)
dlg_select_widget (in->widget.parent, in);
}
static void
entry_release (GtkEditable *entry, GdkEvent *event, WInput *in)
{
in->point = entry->current_pos;
in->mark = (entry->current_pos == entry->selection_start_pos) ?
entry->selection_end_pos : entry->selection_start_pos;
}
int
x_create_input (Dlg_head *h, widget_data parent, WInput *in)
{
@ -171,8 +179,12 @@ x_create_input (Dlg_head *h, widget_data parent, WInput *in)
in->widget.wdata = (widget_data) entry;
gtk_entry_set_text (GTK_ENTRY (entry), in->buffer);
gtk_entry_set_position (GTK_ENTRY (entry), in->point);
gtk_signal_connect (GTK_OBJECT (entry), "button_press_event",
GTK_SIGNAL_FUNC (entry_click), in);
gtk_signal_connect (GTK_OBJECT (entry), "button_release_event",
GTK_SIGNAL_FUNC (entry_release), in);
return 1;
}
@ -186,7 +198,9 @@ x_update_input (WInput *in)
return;
gtk_entry_set_text (entry, in->buffer);
printf ("POniendo el putno en %d\n", in->point);
gtk_entry_set_position (entry, in->point);
gtk_widget_draw (GTK_WIDGET (entry), NULL);
}
/* Listboxes */

Просмотреть файл

@ -591,3 +591,27 @@ flags=
[sort-Widget-radio-1]
geometry=1,1,1,6
flags=n
[quick_symlink-Widget-input-2]
geometry=0,2,7,1
flags=ew
[quick_symlink-Widget-input-1]
geometry=0,4,7,1
flags=ew
[quick_symlink-Widget-label-1]
geometry=0,1,7,1
flags=w
[quick_symlink-Widget-label-2]
geometry=0,3,7,1
flags=
[quick_symlink-Widget-ok]
geometry=2,6,1,1
flags=ew
[quick_symlink-Widget-cancel]
geometry=4,6,1,1
flags=

Просмотреть файл

@ -1,3 +1,20 @@
Wed Mar 11 19:02:48 1998 Miguel de Icaza <miguel@nuclecu.unam.mx>
* view.c: Lots of changes: Split the X11 code from the main view
program. This is needed to cleanly support the addition of the
Gnome version of the file viewer;
New names for old functions (just a view_ prefix):
view_add_character, view_add_string, view_gotoyx, view_set_color,
view_display_clean. Now all of them take a WView argument (which
is ignored in the macro for the text edition). This is to support
multiple open views at once.
* boxes.c (symlink_dialog): Enable ok/cancel buttons for the Gnome edition.
* cmd.c (link_cmd, symlink_cmd): Provide the filename to operate
on.
Tue Mar 10 20:41:45 1998 Miguel de Icaza <miguel@nuclecu.unam.mx>
* cmd.c (unselect_cmd_panel, select_cmd_panel): To avoid races on

Просмотреть файл

@ -685,7 +685,8 @@ void symlink_dialog (char *existing, char *new, char **ret_existing,
{
QuickDialog Quick_input;
QuickWidget quick_widgets [] = {
#ifdef HAVE_TK
#undef INPUT_INDEX
#if defined(HAVE_TK) || defined(HAVE_GNOME)
#define INPUT_INDEX 2
{ quick_button, 0, 1, 0, 1, "&Cancel", 0, B_CANCEL, 0, 0,
XV_WLAY_DONTCARE, "cancel" },
@ -694,10 +695,10 @@ void symlink_dialog (char *existing, char *new, char **ret_existing,
#else
#define INPUT_INDEX 0
#endif
{ quick_input, 4, 80, 5, 8, "", 58, 0, 0, 0, XV_WLAY_BELOWCLOSE, "input-1" },
{ quick_label, 4, 80, 4, 8, "", 0, 0, 0, 0, XV_WLAY_BELOWOF, "label-1" },
{ quick_input, 4, 80, 3, 8, "", 58, 0, 0, 0, XV_WLAY_BELOWCLOSE, "input-2" },
{ quick_label, 4, 80, 2, 8, "", 0, 0, 0, 0, XV_WLAY_DONTCARE, "label-2" },
{ quick_input, 6, 80, 5, 8, "", 58, 0, 0, 0, XV_WLAY_BELOWCLOSE, "input-1" },
{ quick_label, 6, 80, 4, 8, "", 0, 0, 0, 0, XV_WLAY_BELOWOF, "label-1" },
{ quick_input, 6, 80, 3, 8, "", 58, 0, 0, 0, XV_WLAY_BELOWCLOSE, "input-2" },
{ quick_label, 6, 80, 2, 8, "", 0, 0, 0, 0, XV_WLAY_DONTCARE, "label-2" },
{ 0 } };
Quick_input.xlen = 64;

Просмотреть файл

@ -969,17 +969,18 @@ view_other_cmd (void)
}
#ifndef OS2_NT
static void do_link (int symbolic_link)
static void
do_link (int symbolic_link, char *fname)
{
struct stat s;
char *dest, *src;
int stat_r;
if (!symbolic_link){
stat_r = mc_stat (selection (cpanel)->fname, &s);
stat_r = mc_stat (fname, &s);
if (stat_r != 0){
message (1, " Error ", " Couldn't stat %s \n %s ",
selection (cpanel)->fname, unix_error_string (errno));
fname, unix_error_string (errno));
return;
}
if (!S_ISREG (s.st_mode))
@ -987,7 +988,7 @@ static void do_link (int symbolic_link)
}
if (!symbolic_link){
src = copy_strings (" Link ", name_trunc (selection (cpanel)->fname, 46),
src = copy_strings (" Link ", name_trunc (fname, 46),
" to:", NULL);
dest = input_expand_dialog (" Link ", src, "");
free (src);
@ -998,11 +999,11 @@ static void do_link (int symbolic_link)
return;
}
save_cwds_stat ();
if (-1 == mc_link (selection (cpanel)->fname, dest))
if (-1 == mc_link (fname, dest))
message (1, " Error ", " link: %s ", unix_error_string (errno));
} else {
#ifdef OLD_SYMLINK_VERSION
symlink_dialog (selection (cpanel)->fname, "", &dest, &src);
symlink_dialog (fname, "", &dest, &src);
#else
/* suggest the full path for symlink */
char s[MC_MAXPATHLEN];
@ -1011,7 +1012,7 @@ static void do_link (int symbolic_link)
strcpy(s, cpanel->cwd);
if ( ! ((s[0] == '/') && (s[1] == 0)))
strcat(s, "/");
strcat(s, selection (cpanel)->fname);
strcat(s, fname);
if (get_other_type () == view_listing)
strcpy(d, opanel->cwd);
else
@ -1045,12 +1046,12 @@ static void do_link (int symbolic_link)
void link_cmd (void)
{
do_link (0);
do_link (0, selection (cpanel)->fname);
}
void symlink_cmd (void)
{
do_link (1);
do_link (1, selection (cpanel)->fname);
}
void edit_symlink_cmd (void)

Просмотреть файл

@ -2060,7 +2060,6 @@ static key_map panel_keymap [] = {
{ '\\', unselect_cmd },
{ '-', unselect_cmd },
{ XCTRL('r'), reread_cmd },
{ ALT('o'), view_other_cmd },
#endif
#ifndef HAVE_X

Просмотреть файл

@ -25,6 +25,7 @@
/* }}} */
/* {{{ Declarations */
#include <config.h>
#include "x.h"
#include <stdio.h>
#ifdef __os2__
# include <io.h>
@ -49,7 +50,6 @@
#include <errno.h>
#include <limits.h>
#include <sys/param.h>
#include "mem.h"
#include "mad.h"
#include "util.h"
@ -212,10 +212,7 @@ view_destroy (WView *view)
view_done (view);
if (view->have_frame)
delete_hook (&select_file_hook, view_hook);
#ifdef HAVE_TK
free (view->cache);
free (view->color_cache);
#endif
x_destroy_view (view);
}
static int
@ -500,13 +497,6 @@ static char *load_view_file (WView *view, char *filename)
return set_view_init_error (view, " Can't view: not a regular file ");
}
#ifdef JUST_FOR_CULTURAL_INFORMATION
/* #ifed out because now we have growing buffers :-) */
if (view->s.st_size < 1) {
close_view_file (view);
return set_view_init_error (view, " Can't view empty file ");
}
#endif
if (view->s.st_size == 0){
/* Must be one of those nice files that grow (/proc) */
close_view_file (view);
@ -675,77 +665,9 @@ view_init (WView *view, char *_command, char *_file, int start_line)
/* }}} */
/* {{{ X Window code */
#ifdef HAVE_TK
#include "tkmain.h"
/* Accepts the dim command with the width and the height in characters */
static int
tk_viewer_callback (ClientData cd, Tcl_Interp *interp, int ac, char *av[])
{
WView *view = (WView *) cd;
if (av [1][0] != 'd')
return TCL_OK;
view->widget.cols = atoi (av [2]);
view->widget.lines = atoi (av [3]);
return TCL_OK;
}
void
x_create_viewer (WView *view)
{
char *cmd;
widget_data parent;
/* First, check if our parent is ".", if this is the case, then
* create a stand alone viewer, otherwise, we create a paneled
* version of the viewer
*/
if (view->have_frame){
parent = view->widget.wcontainer;
} else {
parent = view->widget.parent->wdata;
}
cmd = tk_new_command (parent, view, tk_viewer_callback, 'v');
tk_evalf ("newview %d %s %s %s", view->have_frame,
view->have_frame ? (char *) view->widget.wcontainer : "{}",
cmd+1, cmd);
}
#else
# define x_create_viewer(x)
#endif
/* }}} */
/* {{{ Screen update functions */
#ifdef HAVE_TK
static void
view_status (WView *view)
{
char *window = wtk_win (view->widget);
if (!view->status_shown){
view->status_shown = 0;
tk_evalf ("view_update_info %s {%s} {%d} {%s} {%s}",
window, name_trunc (view->filename ? view->filename:
view->command ? view->command:"", 20),
-view->start_col, size_trunc (view->s.st_size),
view->growing_buffer ? "[grow]":"[]");
}
}
static void
view_percent (WView *view, int p, int w)
{
fprintf (stderr, "Missing tk view_percent\n");
}
#else /* HAVE_TK */
#ifndef HAVE_X
static void
view_percent (WView *view, int p, int w)
{
@ -784,7 +706,7 @@ view_status (WView *view)
if (view->hex_mode)
printw ("Offset 0x%08x", view->edit_cursor);
else
printw ("Col %d", -view->start_col);
printw ("Col %d", -view->start_col);
}
if (w > 60){
widget_move (view, view->have_frame, 42);
@ -799,182 +721,15 @@ view_status (WView *view)
if (view->hex_mode)
view_percent (view, view->edit_cursor - view->first, w);
else
view_percent (view, view->start_display - view->first, w);
view_percent (view, view->start_display - view->first, w);
}
attrset (SELECTED_COLOR);
}
#endif HAVE_TK
#ifdef HAVE_TK
#define DEF_COLOR 0
#define BOLD_COLOR 1
#define UNDERLINE_COLOR 2
#define MARK_COLOR 3
/* The major part of the Tk code deals with caching a line (the
* current one) of text to avoid expensive calls to the Tk text widget
* callback.
*
* We cache all this information on view->cache and the colors on
* view->color_cache.
*
* FIXME: the cache does not know about the contents of the physical
* text widget (depends on your concept of physical), so if we happen
* to hit the case where row is decremented in the void display () routine,
* we will end up with a clean line.
*/
static int current_color;
static void
set_color (int font)
{
current_color = font;
}
#define view_set_color(view,font) attrset (font)
static inline void
display_clean(WView *view, int h, int w)
{
char *win = wtk_win (view->widget);
tk_evalf ("cleanview %s.v.view", win);
}
static void
add_character (WView *view, int c)
{
view->cache [view->dest] = c;
view->color_cache [view->dest] = current_color;
}
static inline void
add_string (WView *view, char *s)
{
while (*s)
add_character (view, *s++);
}
static char *
get_tk_tag_name (int color)
{
/* Those names are the names of the tags in the Tk source */
static char *color_tag_names [] = {
"normal", "bold", "underline", "mark"
};
return color_tag_names [color];
}
/*
* Tk: Flushes the contents of view->cache to the Tk text widget
*
* We get the command information and call the command directly
* to avoid escaping the view->cache contents.
*/
static void
flush_line (WView *view)
{
char *win = wtk_win (view->widget);
int row = view->current_line;
char *text_name;
Tcl_CmdInfo info;
int i, prev_color;
char str_row [30];
char *av [5];
int len = strlen (view->cache);
/* Fetch the address and clientData for the view */
text_name = copy_strings (win, ".v.view", 0);
Tcl_GetCommandInfo (interp, text_name, &info);
/* Setup arguments to the command:
* $win.v.view insert @$row,0 $view->cache
*/
sprintf (str_row, "%d.0", row);
i = 0;
av [i++] = text_name;
av [i++] = "insert";
av [i++] = str_row;
av [i++] = view->cache;
/* Call the callback :-) */
(*info.proc) (info.clientData, interp, i, av);
bzero (view->cache, view->cache_len);
/* Colorize the line */
for (prev_color = 0, i = 0; i < len; i++){
int new_color_start;
char *color_name;
if (view->color_cache [i] == prev_color)
continue;
new_color_start = i;
prev_color = view->color_cache [i];
for (;i < len && view->color_cache [i] == prev_color; i++)
;
color_name = get_tk_tag_name (prev_color);
tk_evalf ("%s tag add %s %d.%d %d.%d",
text_name, color_name,
row, new_color_start-1,
row, i);
}
bzero (view->color_cache, view->cache_len);
view->last_col = 0;
free (text_name);
}
/* Tk: Mantains the line cache */
void
view_gotoyx (WView *view, int row, int col)
{
if (row != view->current_line){
flush_line (view);
}
view->current_line = row;
/* In case the user has resized the viewer */
if (col > view->cache_len){
char *new;
new = xmalloc (col + 1, "cache");
strcpy (new, view->cache);
free (view->cache);
view->cache = new;
new = xmalloc (col + 1, "cache");
strcpy (new, view->color_cache);
free (view->color_cache);
view->color_cache = new;
view->cache_len = col;
}
view->dest = col;
for (; view->last_col+1 < col; view->last_col++){
view->cache [view->last_col] = ' ';
view->color_cache [view->last_col] = current_color;
}
view->last_col = col;
}
#else
#define BOLD_COLOR MARKED_COLOR
#define UNDERLINE_COLOR VIEW_UNDERLINED_COLOR
#define MARK_COLOR SELECTED_COLOR
#define DEF_COLOR NORMAL_COLOR
#define set_color(font) attrset (font)
static inline void
display_clean (WView *view, int height, int width)
view_display_clean (WView *view, int height, int width)
{
/* FIXME: Should I use widget_erase only and repaint the box? */
if (view->have_frame){
@ -990,10 +745,22 @@ display_clean (WView *view, int height, int width)
widget_erase ((Widget *) view);
}
#define add_character(view,c) addch (c)
#define add_string(view,s) addstr (s)
#define view_gotoyx(v,r,c) widget_move (v,r,c)
#define view_add_character(view,c) addch (c)
#define view_add_string(view,s) addstr (s)
#define view_gotoyx(v,r,c) widget_move (v,r,c)
#endif
#ifndef HAVE_TK
/* Both the text mode and gnome editions use this */
#define BOLD_COLOR MARKED_COLOR
#define UNDERLINE_COLOR VIEW_UNDERLINED_COLOR
#define MARK_COLOR SELECTED_COLOR
#define DEF_COLOR NORMAL_COLOR
#endif
#ifndef PORT_HAS_VIEW_FREEZE
# define view_freeze(view)
# define view_thaw(view)
#endif
/* Shows the file pointed to by *start_display on view_win */
@ -1001,12 +768,14 @@ static long
display (WView *view)
{
#ifdef HAVE_X
# define frame_shift 0
# define frame_shift 0
# define STATUS_LINES 0
#else
const int frame_shift = view->have_frame;
# define STATUS_LINES 1
#endif
int col = 0 + frame_shift;
int row = 1 + frame_shift;
int row = STATUS_LINES + frame_shift;
int height, width;
long from;
int c;
@ -1016,16 +785,17 @@ display (WView *view)
height = view->widget.lines - frame_shift;
width = view->widget.cols - frame_shift;
from = view->start_display;
set_color (DEF_COLOR);
view_set_color (view, DEF_COLOR);
display_clean (view, height, width);
view_freeze (view);
view_display_clean (view, height, width);
/* Optionally, display a ruler */
if ((!view->hex_mode) && (ruler)){
char r_buff[4];
int cl;
set_color (BOLD_COLOR);
view_set_color (view, BOLD_COLOR);
for (c = frame_shift; c < width; c++) {
cl = c-view->start_col;
if (ruler == 1)
@ -1038,17 +808,17 @@ display (WView *view)
else
if ((cl % 5) == 0)
r_buff[0] = '*';
add_character (view, r_buff[0]);
view_add_character (view, r_buff[0]);
if ((cl != 0) && (cl % 10) == 0){
sprintf(r_buff, "%03d", cl);
if (ruler == 1)
widget_move (view, row + 1, c - 1);
else
widget_move (view, row + height - 3, c - 1);
add_string (view, r_buff);
view_add_string (view, r_buff);
}
}
set_color (DEF_COLOR);
view_set_color (view, DEF_COLOR);
if (ruler == 1)
row += 2;
else
@ -1073,7 +843,7 @@ display (WView *view)
/* Print the hex offset */
sprintf (hex_buff, "%05X", (int) (from - view->first));
widget_move (view, row, frame_shift);
add_string (view, hex_buff);
view_add_string (view, hex_buff);
/* Hex dump starts from column seven */
col = 7;
@ -1087,14 +857,14 @@ display (WView *view)
c = curr->value;
curr = curr->next;
boldflag = 3;
set_color (7);
view_set_color (view, 7);
} else
c = (unsigned char) get_byte (view, from);
if (view->found_len && from >= view->search_start
&& from < view->search_start + view->found_len){
boldflag = 1;
set_color (BOLD_COLOR);
view_set_color (view, BOLD_COLOR);
}
/* Display the navigation cursor */
if (from == view->edit_cursor) {
@ -1103,39 +873,39 @@ display (WView *view)
view->cursor_col = col;
}
boldflag = 2;
set_color (view->view_side == view_side_left ? 15 : 31);
view_set_color (view, view->view_side == view_side_left ? 15 : 31);
}
/* Print a hex number (sprintf is too slow) */
hex_buff [0] = hex_char [(c >> 4)];
hex_buff [1] = hex_char [c & 15];
view_gotoyx (view, row, col);
add_string (view, hex_buff);
view_add_string (view, hex_buff);
col += 3;
/* Turn off the cursor or changed byte highlighting here */
if (boldflag > 1)
set_color (DEF_COLOR);
view_set_color (view, DEF_COLOR);
if ((bytes & 3) == 3 && bytes + 1 < view->bytes_per_line){
/* Turn off the search highlighting */
if (boldflag == 1 &&
from == view->search_start + view->found_len - 1)
set_color (DEF_COLOR);
view_set_color (view, DEF_COLOR);
/* Hex numbers are printed in the groups of four */
/* Groups are separated by a vline */
add_character (view, ' ');
view_add_character (view, ' ');
one_vline ();
view_gotoyx (view, row, col + 1);
col += 2;
if (boldflag && from==view->search_start+view->found_len-1)
set_color (BOLD_COLOR);
view_set_color (view, BOLD_COLOR);
}
if (boldflag && from < view->search_start + view->found_len - 1
&& bytes != view->bytes_per_line - 1)
add_character (view, ' ');
view_add_character (view, ' ');
/* Print the corresponding ascii character */
view_gotoyx (view, row, text_start + bytes);
@ -1146,13 +916,13 @@ display (WView *view)
default:
break;
case 1:
set_color (BOLD_COLOR);
view_set_color (view, BOLD_COLOR);
goto setcursor;
case 2:
set_color (view->view_side == view_side_left ? 31 : 15);
view_set_color (view, view->view_side == view_side_left ? 31 : 15);
goto setcursor;
case 3:
set_color (7);
view_set_color (view, 7);
setcursor:
if (view->view_side == view_side_right){
@ -1160,11 +930,11 @@ display (WView *view)
view->cursor_row = row;
}
}
add_character (view, c);
view_add_character (view, c);
if (boldflag){
boldflag = 0;
set_color (DEF_COLOR);
view_set_color (view, DEF_COLOR);
}
}
}
@ -1204,16 +974,16 @@ display (WView *view)
col--;
boldflag = 1;
if (get_byte (view, from - 1) == '_' && get_byte (view, from + 1) != '_')
set_color (UNDERLINE_COLOR);
view_set_color (view, UNDERLINE_COLOR);
else
set_color (BOLD_COLOR);
view_set_color (view, BOLD_COLOR);
continue;
}
}
if (view->found_len && from >= view->search_start
&& from < view->search_start + view->found_len){
boldflag = 1;
set_color (MARK_COLOR);
view_set_color (view, MARK_COLOR);
}
if (col >= frame_shift-view->start_col
&& col < width-view->start_col)
@ -1222,12 +992,12 @@ display (WView *view)
if (!is_printable (c))
c = '.';
add_character (view, c);
view_add_character (view, c);
}
col++;
if (boldflag){
boldflag = 0;
set_color (DEF_COLOR);
view_set_color (view, DEF_COLOR);
}
/* Very last thing */
@ -1235,11 +1005,11 @@ display (WView *view)
get_byte (view, from+1);
}
#ifdef HAVE_TK
/* Tk: This flushes the last line */
view_gotoyx (view, view->current_line+1, 0);
#endif
}
view->last = from;
view_thaw (view);
return from;
}
@ -1709,11 +1479,11 @@ search (WView *view, char *text, int (*search)(WView *, char *, char *, int))
update_activate = 0;
for (; ; isatbeg = 1, free (s)){
#ifdef HAVE_TK
#ifdef HAVE_X
static int count;
if ((count++ % 32) == 0)
tk_dispatch_all ();
x_flush_events ();
if (!d->running)
break;
#endif
@ -2532,9 +2302,9 @@ view (char *_command, char *_file, int *move_dir_p, int start_line)
*move_dir_p = 0;
return !error;
}
#else
Dlg_head *view_dlg;
#endif
#ifndef PORT_WANTS_VIEW
void
view_adjust_size (Dlg_head *h)
{
@ -2548,6 +2318,9 @@ view_adjust_size (Dlg_head *h)
widget_set_size (&bar->widget, LINES-1, 0, 1, COLS);
}
/* Only the text mode edition uses this */
Dlg_head *view_dlg;
/* Real view only */
int
view (char *_command, char *_file, int *move_dir_p, int start_line)
@ -2556,20 +2329,23 @@ view (char *_command, char *_file, int *move_dir_p, int start_line)
int error;
WView *wview;
WButtonBar *bar;
Dlg_head *our_dlg;
/* Create dialog and widgets, put them on the dialog */
view_dlg = create_dlg (0, 0, LINES, COLS, midnight_colors,
our_dlg = create_dlg (0, 0, LINES, COLS, midnight_colors,
view_mode_callback, "[Internal File Viewer]",
"view",
DLG_NONE);
#ifndef HAVE_X
view_dlg = our_dlg;
#endif
wview = view_new (0, 0, COLS, LINES-1, 0);
bar = buttonbar_new (1);
add_widget (view_dlg, wview);
add_widget (view_dlg, bar);
add_widget (our_dlg, wview);
add_widget (our_dlg, bar);
error = view_init (wview, _command, _file, start_line);
if (move_dir_p)
@ -2580,11 +2356,11 @@ view (char *_command, char *_file, int *move_dir_p, int start_line)
* be aware of it
*/
if (!error){
run_dlg (view_dlg);
run_dlg (our_dlg);
if (move_dir_p)
*move_dir_p = wview->move_dir;
}
destroy_dlg (view_dlg);
destroy_dlg (our_dlg);
return !error;
}
@ -2673,9 +2449,7 @@ view_callback (Dlg_head *h, WView *v, int msg, int par)
return 1;
case WIDGET_FOCUS:
#ifdef HAVE_TK
tk_evalf ("focus %s.v.view", wtk_win (view->widget));
#endif
x_focus_view (view);
view_labels (view);
return 1;
@ -2707,17 +2481,9 @@ view_new (int y, int x, int cols, int lines, int is_panel)
view->have_frame = is_panel;
view->last_byte = -1;
view->monitor = 0;
#ifdef HAVE_TK
view->status_shown = 0;
view->current_line = 1;
view->cache_len = 80;
view->last_col = 0;
view->cache = xmalloc (81, "view->cache");
view->color_cache = xmalloc (81, "view->cache");
view->direction = 1;
bzero (view->cache, 81);
view->dest = 0;
#endif
x_init_view (view);
widget_want_cursor (view->widget, 0);
return view;

Просмотреть файл

@ -88,6 +88,11 @@ typedef struct {
int status_shown; /* Have we show the file information? */
#endif
#ifdef HAVE_GNOME
int current_x, current_y; /* Current x,y position */
int color; /* Current color */
#endif
int move_dir; /* return value from widget:
* 0 do nothing
* -1 view previous file
@ -141,4 +146,32 @@ struct hexedit_change_node {
unsigned char value;
};
#ifdef HAVE_TK
#define DEF_COLOR 0
#define BOLD_COLOR 1
#define UNDERLINE_COLOR 2
#define MARK_COLOR 3
#endif
#ifdef HAVE_X
#ifdef WANT_WIDGETS
void view_add_character (WView *view, int c);
void view_add_string (WView *view, char *s);
void view_gotoyx (WView *view, int r, int c);
void view_set_color (WView *view, int font);
void view_display_clean (WView *view, int h, int w);
#ifdef PORT_HAS_VIEW_FREEZE
void view_freeze (WView *view);
void view_thaw (WView *view);
#endif
#endif
#else
# define x_init_view(x)
# define x_destroy_view(x)
# define x_create_viewer(x)
# define x_focus_view(x)
#endif
#endif /* __VIEW_H */

Просмотреть файл

@ -1425,41 +1425,41 @@ static struct {
void (*fn)(WInput *in);
} input_map [] = {
/* Motion */
{ XCTRL('a'), beginning_of_line },
{ KEY_HOME, beginning_of_line },
{ KEY_A1, beginning_of_line },
{ XCTRL('e'), end_of_line },
{ KEY_END, end_of_line },
{ KEY_C1, end_of_line },
{ KEY_LEFT, key_left },
{ XCTRL('b'), backward_char },
{ ALT('b'), backward_word },
{ KEY_RIGHT, key_right },
{ XCTRL('f'), forward_char },
{ ALT('f'), forward_word },
{ XCTRL('a'), beginning_of_line },
{ KEY_HOME, beginning_of_line },
{ KEY_A1, beginning_of_line },
{ XCTRL('e'), end_of_line },
{ KEY_END, end_of_line },
{ KEY_C1, end_of_line },
{ KEY_LEFT, key_left },
{ XCTRL('b'), backward_char },
{ ALT('b'), backward_word },
{ KEY_RIGHT, key_right },
{ XCTRL('f'), forward_char },
{ ALT('f'), forward_word },
/* Editing */
{ 0177, backward_delete },
{ KEY_BACKSPACE,backward_delete },
{ XCTRL('h'), backward_delete },
{ KEY_DC, delete_char },
{ XCTRL('d'), delete_char },
{ ALT('d'), kill_word },
{ 0177, backward_delete },
{ KEY_BACKSPACE, backward_delete },
{ XCTRL('h'), backward_delete },
{ KEY_DC, delete_char },
{ XCTRL('d'), delete_char },
{ ALT('d'), kill_word },
{ ALT(KEY_BACKSPACE), back_kill_word },
{ ALT(XCTRL('h')), back_kill_word },
{ ALT(127), back_kill_word },
{ ALT(XCTRL('h')), back_kill_word },
{ ALT(127), back_kill_word },
/* Region manipulation */
{ 0, set_mark },
{ XCTRL('w'), kill_region },
{ ALT('w'), kill_save },
{ XCTRL('y'), yank },
{ XCTRL('k'), kill_line },
{ 0, set_mark },
{ XCTRL('w'), kill_region },
{ ALT('w'), kill_save },
{ XCTRL('y'), yank },
{ XCTRL('k'), kill_line },
/* History */
{ ALT('p'), hist_prev },
{ ALT('n'), hist_next },
{ ALT('h'), show_hist },
{ ALT('p'), hist_prev },
{ ALT('n'), hist_next },
{ ALT('h'), show_hist },
/* Completion */
{ ALT('\t'), complete },

Просмотреть файл

@ -22,3 +22,244 @@
smaller than a complete tkview.c program, and it's just interface
code so that the code knows about the window resize.
*/
#include "dlg.h"
#include "view.h"
#include "tkmain.h"
x_init_view (WView *view)
{
view->status_shown = 0;
view->current_line = 1;
view->cache_len = 80;
view->last_col = 0;
view->cache = xmalloc (81, "view->cache");
view->color_cache = xmalloc (81, "view->cache");
view->direction = 1;
bzero (view->cache, 81);
view->dest = 0;
}
void
x_destroy_view (WView *view)
{
free (view->cache);
free (view->color_cache);
}
/* Accepts the dim command with the width and the height in characters */
static int
tk_viewer_callback (ClientData cd, Tcl_Interp *interp, int ac, char *av[])
{
WView *view = (WView *) cd;
if (av [1][0] != 'd')
return TCL_OK;
view->widget.cols = atoi (av [2]);
view->widget.lines = atoi (av [3]);
return TCL_OK;
}
void
x_create_viewer (WView *view)
{
char *cmd;
widget_data parent;
/* First, check if our parent is ".", if this is the case, then
* create a stand alone viewer, otherwise, we create a paneled
* version of the viewer
*/
if (view->have_frame){
parent = view->widget.wcontainer;
} else {
parent = view->widget.parent->wdata;
}
cmd = tk_new_command (parent, view, tk_viewer_callback, 'v');
tk_evalf ("newview %d %s %s %s", view->have_frame,
view->have_frame ? (char *) view->widget.wcontainer : "{}",
cmd+1, cmd);
}
void
x_focus_view (WView *view)
{
tk_evalf ("focus %s.v.view", wtk_win (view->widget));
}
void
view_status (WView *view)
{
char *window = wtk_win (view->widget);
if (!view->status_shown){
view->status_shown = 0;
tk_evalf ("view_update_info %s {%s} {%d} {%s} {%s}",
window, name_trunc (view->filename ? view->filename:
view->command ? view->command:"", 20),
-view->start_col, size_trunc (view->s.st_size),
view->growing_buffer ? "[grow]":"[]");
}
}
void
view_percent (WView *view, int p, int w)
{
fprintf (stderr, "Missing tk view_percent\n");
}
/* The major part of the Tk code deals with caching a line (the
* current one) of text to avoid expensive calls to the Tk text widget
* callback.
*
* We cache all this information on view->cache and the colors on
* view->color_cache.
*
* FIXME: the cache does not know about the contents of the physical
* text widget (depends on your concept of physical), so if we happen
* to hit the case where row is decremented in the void display () routine,
* we will end up with a clean line.
*/
static int current_color;
void
view_set_color (int font)
{
current_color = font;
}
void
view_display_clean(WView *view, int h, int w)
{
char *win = wtk_win (view->widget);
tk_evalf ("cleanview %s.v.view", win);
}
void
view_add_character (WView *view, int c)
{
view->cache [view->dest] = c;
view->color_cache [view->dest] = current_color;
}
void
view_add_string (WView *view, char *s)
{
while (*s)
add_character (view, *s++);
}
static char *
get_tk_tag_name (int color)
{
/* Those names are the names of the tags in the Tk source */
static char *color_tag_names [] = {
"normal", "bold", "underline", "mark"
};
return color_tag_names [color];
}
/*
* Tk: Flushes the contents of view->cache to the Tk text widget
*
* We get the command information and call the command directly
* to avoid escaping the view->cache contents.
*/
static void
flush_line (WView *view)
{
char *win = wtk_win (view->widget);
int row = view->current_line;
char *text_name;
Tcl_CmdInfo info;
int i, prev_color;
char str_row [30];
char *av [5];
int len = strlen (view->cache);
/* Fetch the address and clientData for the view */
text_name = copy_strings (win, ".v.view", 0);
Tcl_GetCommandInfo (interp, text_name, &info);
/* Setup arguments to the command:
* $win.v.view insert @$row,0 $view->cache
*/
sprintf (str_row, "%d.0", row);
i = 0;
av [i++] = text_name;
av [i++] = "insert";
av [i++] = str_row;
av [i++] = view->cache;
/* Call the callback :-) */
(*info.proc) (info.clientData, interp, i, av);
bzero (view->cache, view->cache_len);
/* Colorize the line */
for (prev_color = 0, i = 0; i < len; i++){
int new_color_start;
char *color_name;
if (view->color_cache [i] == prev_color)
continue;
new_color_start = i;
prev_color = view->color_cache [i];
for (;i < len && view->color_cache [i] == prev_color; i++)
;
color_name = get_tk_tag_name (prev_color);
tk_evalf ("%s tag add %s %d.%d %d.%d",
text_name, color_name,
row, new_color_start-1,
row, i);
}
bzero (view->color_cache, view->cache_len);
view->last_col = 0;
free (text_name);
}
/* Tk: Mantains the line cache */
void
view_gotoyx (WView *view, int row, int col)
{
if (row != view->current_line){
flush_line (view);
}
view->current_line = row;
/* In case the user has resized the viewer */
if (col > view->cache_len){
char *new;
new = xmalloc (col + 1, "cache");
strcpy (new, view->cache);
free (view->cache);
view->cache = new;
new = xmalloc (col + 1, "cache");
strcpy (new, view->color_cache);
free (view->color_cache);
view->color_cache = new;
view->cache_len = col;
}
view->dest = col;
for (; view->last_col+1 < col; view->last_col++){
view->cache [view->last_col] = ' ';
view->color_cache [view->last_col] = current_color;
}
view->last_col = col;
}
#endif