campo-sirio/include/viswin.cpp

2852 lines
68 KiB
C++
Executable File

#include <browfile.h>
#include <colors.h>
#include <config.h>
#include <controls.h>
#include <execp.h>
#include <golem.h>
#include <image.h>
#include <mailbox.h>
#include <printapp.h>
#include <spotlite.h>
#include <urldefid.h>
#include <utility.h>
#include <viswin.h>
#include <bagn005.h>
const char* const PRINT_FONT = XVT_FFN_FIXED;
int PRINT_HEIGHT = 10;
#define BUTTONROW_SIZE (_showbuts ? 4 : 0)
#define X_OFFSET (_rulers ? 6 : 1)
#define Y_OFFSET (_rulers ? 1 : 0)
#define TEXTROWS (rows() - Y_OFFSET - BUTTONROW_SIZE)
#define TEXTCOLUMNS (columns() - X_OFFSET)
#define BACKGROUND MASK_BACK_COLOR
#define FOREGROUND NORMAL_COLOR
#define K_CTRL_DOWN (K_CTRL + K_DOWN)
#define K_CTRL_UP (K_CTRL + K_UP)
#define K_SHIFT_UP (K_SHIFT + K_UP)
#define K_SHIFT_DOWN (K_SHIFT + K_DOWN)
#define K_SHIFT_LEFT (K_SHIFT + K_LEFT)
#define K_SHIFT_RIGHT (K_SHIFT + K_RIGHT)
#define K_ALT_RIGHT (K_CTRL + 'K')
#define K_ALT_LEFT (K_CTRL + 'L')
#define CTRL_C (K_CTRL + 'C')
#define CTRL_G (K_CTRL + 'G')
#define CTRL_E (K_CTRL + 'E')
#define CTRL_S (K_CTRL + 'S')
#define CTRL_R (K_CTRL + 'R')
#define CTRL_P (K_CTRL + 'P')
class _BkMenuItem : public TObject
{
public:
TString _txt;
TArray* _arr;
int _id; // per comodita'
_BkMenuItem(const char* t = "")
{ _txt = t; _arr = NULL; }
virtual ~_BkMenuItem()
{ if (_arr != NULL) delete _arr; }
};
class _BkMenuDesc : public TObject
{
public:
TString_array _menu;
int _father_id;
_BkMenuDesc() {}
virtual ~_BkMenuDesc() {}
};
int TViswin::tabx(int x) const
{
return char2pixel(x);
}
int TViswin::taby(int y) const
{
return y * CHARY;
}
// @doc INTERNAL
// @mfunc Abilita/Disabilita una voce di menu'
void TViswin::check_menu_item(
MENU_TAG item, // @parm Voce del menu' da abilitare
bool on) // @parm Operazione da svolgere sulla voce di menu':
// @flag TRUE | Viene abilitata la voce
// @flag TRUE | Viene disabilitata la voce
{
ignore_xvt_errors(TRUE);
xvt_menu_set_item_checked(win(), item, on);
xvt_menu_update(win());
ignore_xvt_errors(FALSE);
}
void TViswin::enable_menu_item(MENU_TAG item, bool on)
{
ignore_xvt_errors(TRUE);
xvt_menu_set_item_enabled(win(), item, on);
xvt_menu_update(win());
ignore_xvt_errors(FALSE);
}
HIDDEN _BkMenuItem* find_menu_node(TArray& tree, int id)
{
_BkMenuItem* fnd = NULL;
for (int m = 0; m < tree.items(); m++)
{
_BkMenuItem& bkit = (_BkMenuItem&) tree[m];
if (bkit._id == id)
return &bkit;
else if (bkit._arr != NULL)
{
if ((fnd = find_menu_node(*(bkit._arr), id)) != NULL)
break;
}
}
return fnd;
}
HIDDEN void build_menu_tree(TArray& flat, TArray& tree, int level)
{
// find ID in flat array
_BkMenuDesc* bds = NULL;
int i;
for (i = 0; i < flat.items(); i++)
{
_BkMenuDesc& bdss = (_BkMenuDesc&)flat[i];
if (bdss._father_id == 1000 + level)
{
bds = &bdss;
break;
}
}
if (bds == NULL)
{
bds = new _BkMenuDesc;
bds->_father_id = 1000 + level;
flat.add(bds);
}
for (i = 0; i < tree.items(); i++)
{
_BkMenuItem& bki = (_BkMenuItem&)tree[i];
bds->_menu.add(bki._txt);
if (bki._arr != NULL)
build_menu_tree(flat, *(bki._arr), bki._id);
}
}
void TViswin::build_index_menu()
{
if (_menu_present) return;
// builds bk_menu tree and index menu
TArray bk_tree;
TToken_string tt(128);
int i;
// build tree
for (i = 0; i < _bookmarks->items(); i++)
{
BkDef& bkd = (BkDef&)(*_bookmarks)[i];
tt.format("%d", bkd._id + 1000);
tt.add(bkd._txt);
_BkMenuItem* bkit = new _BkMenuItem((const char*)tt);
bkit->_id = bkd._id;
int father_id = bkd._father_id == -1 ? 0 : bkd._father_id;
if (father_id == 0) // toplevel
bk_tree.add(bkit);
else
{
_BkMenuItem* father = find_menu_node(bk_tree, father_id);
if (father != NULL)
{
if (father->_arr == NULL)
father->_arr = new TArray(4);
father->_arr->add(bkit);
}
}
}
// build menu
if (bk_tree.items() > 0)
{
TString_array top(1); top.add("1000|Indice");
add_menu(top);
}
TArray flat(4);
build_menu_tree(flat, bk_tree, 0);
for (i = 0; i < flat.items(); i++)
{
_BkMenuDesc& bds = (_BkMenuDesc&)flat[i];
if (bds._menu.items() > 0)
add_menu(bds._menu, bds._father_id);
}
_menu_present = TRUE;
}
void TViswin::exec_link()
{
if (_linkID != -1)
{
if (!_toplevel)
{
// link da browsefile_field
MASK_LINKHANDLER pl = _brwfld->_lh;
if (pl != NULL)
pl(_brwfld->mask(), _linkID,
_multiple ? (const char*)_multiple_link : (const char*)_linktxt, TRUE);
}
else
{
bool reload = false;
LINKHANDLER pl = printer().getlinkhandler();
if (pl)
reload = pl(_linkID, _multiple ? (const char*)_multiple_link : (const char*)_linktxt);
if (main_app().class_id() == CLASS_PRINT_APPLICATION)
{
if (!reload)
{ // Backward compatibility mode
// dai opzione per rifare la stampa se e' arrivato un messaggio dall'applicazione chiamata
TMailbox m;
reload = m.next_s(MSG_LN) != NULL;
}
if (reload && yesno_box(TR("Si desidera riaggiornare la stampa?")))
{
TPrint_application& papp = (TPrint_application&)main_app();
papp.repeat_print();
papp.current_cursor()->update();
xvtil_statbar_refresh ();
stop_run(K_ENTER);
}
}
} // _toplevel
if (_toplevel)
{
set_focus();
_inside_linkexec = TRUE;
check_link();
force_update();
do_events();
check_link (&_point);
_inside_linkexec = FALSE;
}
} // linkID != -1
else beep();
}
void TViswin::display_link (long y, long x1, long x2, const char *d)
{
if (!_link_displayed)
{
paint_link (y, x1, x2);
_link_displayed = TRUE;
if (_in_update) return;
TString80 dd; dd.strncpy(d, 50);
xvtil_statbar_set(dd);
if (_showbuts)
enable_button(DLG_LINK);
if (_toplevel)
enable_menu_item(M_VISWIN_LINK, true);
if (!_toplevel && !_inside_linkexec)
{
// chiama l'handler per maschere con FALSE come terzo parametro
MASK_LINKHANDLER pl = _brwfld->_lh;
if (pl != NULL)
pl(_brwfld->mask(), _linkID,
_multiple ? (const char*)_multiple_link : (const char*)_linktxt, FALSE);
}
}
}
// @doc INTERNAL
// @mfunc Cancella il link
void TViswin::erase_link (
long y, // @parm Altezza del link da disegnare
long x1, // @parm Prima coordinata x del link da cancellare
long x2) // @parm Seconda coordinata x del link da cancellare
{
if (_link_displayed)
{
paint_link (y, x1, x2);
_link_displayed = FALSE;
if (!_in_update)
{
xvtil_statbar_set("");
xvtil_statbar_refresh();
if (_showbuts)
disable_button(DLG_LINK);
if (_toplevel)
enable_menu_item(M_VISWIN_LINK, FALSE);
}
}
}
// @doc INTERNAL
// @mfunc Disegna il link
void TViswin::paint_link (
long y, // @parm Altezza del link da disegnare
long x1, // @parm Prima coordinata x del link da disegnare
long x2) // @parm Seconda coordinata x del link da disegnare
{
if (adjust_box (x1, x2, y))
invert_bar ((int)(x1 + (long)X_OFFSET), (int)(y + (long)Y_OFFSET),
(int)(x2 + (long)X_OFFSET), (int)(y + (long)Y_OFFSET+1l));
}
// @doc INTERNAL
// @mfunc Modifica le dimensione di un box
// @rdesc Ritorna se sono state modificate le dimensioni del box:
// @flag TRUE | Sono state riassegnate le coordinate a <p x1> e <p x2>
// @flag FALSE | Non sono state riassegnate le misure del box poiche' <p y> e' nel testo
bool TViswin::adjust_box (
long &x1, // @parm Prima coordinata da riassegnare
long &x2, // @parm Seconda coordinata da riassegnare
long y) // @parm Valore della riga che deve essere nel testo
// @comm Sistema <p x1> e <p x2> in modo che il minore sia il primo, e controlla che <p y> sia
// nel testo (box e' su una sola riga, usata solo per i link)
{
if (y < origin ().y || y > origin ().y + _textrows)
return FALSE;
if (origin ().x > x1)
x1 = origin ().x;
if (origin ().x + _textcolumns < x2)
x2 = origin ().x + _textcolumns;
return TRUE;
}
// @doc INTERNAL
// @mfunc Controlla se la posizione cursore <p where> cade su un link ipertestuale e si
// comporta di conseguenza
// @rdesc Ritorna se la posizione cade sul link
// @flag TRUE | Se ha constatato la corrispondenza
// @flag FALSE | Se non ha constatato la corrispondenza
bool TViswin::check_link (
TPoint* p) // @parm Posizione del cursore (default NULL)
// @comm Se <p p> e' NULL indica la posizione corrente del cursore
{
static int old_id = -1, plinkID = -1;
static long y, x1, x2;
static long py, px1, px2;
if (p == NULL) // erase and go
{
if (old_id != -1)
{
erase_link (y, x1, x2);
old_id = _linkID = plinkID = -1;
py = px1 = px2 = x1 = y = x2 = 0l;
}
return FALSE;
}
// poi se e' il caso lo si risistema
if (p == &_point)
plinkID = -1;
TArray & h = _txt.hotspots();
for (int i = 0; i < h.items (); i++)
{
TToken_string & t = (TToken_string &) h[i];
t.restart ();
long ty = t.get_long ();
long tx1 = t.get_long ();
long tx2 = t.get_long ();
if (p->y == ty && p->x < tx2 && p->x >= tx1)
{
// ci siamo
int id = (int) t.get_long (4);
if (ty != y || tx1 != x1 || tx2 != x2)
{
if (old_id != -1)
erase_link (y, x1, x2);
TToken_string & ttt = (TToken_string &) (*_links)[id];
ttt.restart ();
_descr = ttt.get ();
_linktxt = t.get(3);
if (_multiple)
{
// get all parts of the same color
const char *cp;
_txt.read_line (ty);
_multiple_link = "";
const char fg = *ttt.get(1);
const char bg = *ttt.get(2);
while ((cp = _txt.piece ()))
{
if (_txt.get_foreground() == fg && _txt.get_background() == bg)
{
_multiple_link.add (cp);
_descr << ' ' << cp;
}
}
}
else
_descr << _linktxt;
old_id = _linkID = id;
y = ty;
x1 = tx1;
x2 = tx2;
display_link (y, x1, x2, _descr);
}
if (p == &_point)
{
_pdescr = _descr;
plinkID = id;
px1 = x1;
px2 = x2;
py = y;
}
return TRUE;
}
}
// non sono su un bottone: puo' esserci il point
if (old_id != -1 && plinkID == -1)
{
old_id = _linkID = -1;
erase_link (y, x1, x2);
x1 = x2 = y = 0l;
}
// se point e' su un bottone, evidenzia quello
else if (plinkID != -1 && (x1 != px1 || x2 != px2 || y != py))
{
// erase old one
erase_link (y, x1, x2);
old_id = _linkID = plinkID;
x1 = px1;
x2 = px2;
y = py;
_descr = _pdescr;
display_link (y, x1, x2, _descr);
return TRUE;
}
return FALSE;
}
bool TViswin::in_text (const TPoint & p) const
{
if (p.x > (X_OFFSET - 1) && p.x < columns() &&
p.y > (Y_OFFSET - 1) && p.y < (rows() - BUTTONROW_SIZE))
return TRUE;
return FALSE;
}
// @doc INTERNAL
// @mfunc Indica se occorre ridisegnare la selezione
//
// @rdesc Ritorna se e' necessario ridipingere la selezione
bool TViswin::need_paint_sel (
bool smart) // @parm Indica se ridisegnarla in ogni caso
//
// @flag TRUE | Indica il ridisegno solamente se e' necessario
// @flag FALSE | Indica il ridisegno in ogni caso
{
TPoint p1, p2;
adjust_selection (p1, p2);
long end = origin ().y + _textrows;
bool r = _isselection;
if (smart)
r = r && (
(origin ().y >= p1.y - 1 && origin ().y <= p2.y + 1) ||
(end >= p1.y - 1 && end <= p2.y + 1));
return r;
}
void TViswin::erase_selection ()
{
if (_sel_displayed)
paint_selection ();
_sel_displayed = FALSE;
if (_toplevel)
{
enable_menu_item(M_VISWIN_COPY, FALSE);
enable_menu_item(M_VISWIN_CLEAR, FALSE);
}
}
void TViswin::display_selection ()
{
if (!_sel_displayed)
paint_selection ();
_sel_displayed = TRUE;
if (_toplevel)
{
enable_menu_item(M_VISWIN_COPY, TRUE);
enable_menu_item(M_VISWIN_CLEAR, TRUE);
}
}
// @doc INTERNAL
// @mfunc Riposizona inizio e fine della selezione
void TViswin::adjust_selection (
TPoint & p1, // @parm Primo punto per il riposizionamento della selezione
TPoint & p2) // @parm Secondo punto per il riposizionamento della selezione
// @comm Viene asseganto a <p p1> e <p p2> le coordinate di inizio e fine selezione
{
if (_sel_start.y < _sel_end.y)
{
p1 = _sel_start;
p2 = _sel_end;
}
else
{
p1 = _sel_end;
p2 = _sel_start;
}
}
void TViswin::shift_screen(scroll dir)
{
RCT r;
if (_scrolling)
return;
_scrolling = TRUE;
// origin() e' gia' stata modificata
switch (dir)
{
case up:
case down:
xvt_rect_set(&r, 0, taby(Y_OFFSET)/*+1*/,
tabx(int(_textcolumns) + X_OFFSET), taby(int(_textrows) + Y_OFFSET));
xvt_dwin_scroll_rect (win(), &r, 0, dir == down ? taby(1) : -taby(1));
paint_row (dir == up ? origin ().y + _textrows - 1 : origin ().y);
break;
case left:
case right:
xvt_rect_set(&r,
tabx(X_OFFSET), 0,
tabx(int(_textcolumns) + X_OFFSET)/* + 2*/,
taby(int(_textrows) + 1)/* - 2*/);
xvt_dwin_scroll_rect (win (), &r, dir == right ? tabx(1) : -tabx(1), 0);
paint_column (dir == left ? origin ().x + _textcolumns - 1 : origin ().x, dir == left);
break;
default:
break;
}
_scrolling = FALSE;
}
// @doc INTERNAL
// @mfunc Aggiunge un bottone alla finestra
//
// @rdesc Ritorna un puntatore al bottone (TControl) aggiunto
TPushbutton_control* TViswin::add_button (
short id, // @parm Identificatore del bottone da aggiungere
const char *caption, // @parm Testo del bottone da aggiungere
short bup, // @parm Identificatore della bitmap normale
short bdn) // @parm Identificatore della bitmap pramuta
// @comm Aggiunge i bottoni nella finestra
{
TPushbutton_control* b = new TPushbutton_control(win(), id, -11, -1, 12, 2, "",
caption, bup, bdn);
_button.add(b);
return b;
}
bool TViswin::enable_button(short id, bool on)
{
int i;
for (i = _button.last(); i >= 0; i--)
{
TPushbutton_control* b = (TPushbutton_control*)_button.objptr(i);
if (b->id() == id)
{
b->enable(on);
break;
}
}
return i >= 0;
}
void TViswin::repos_buttons ()
{
if (_toplevel)
{
RCT wr; xvt_vobj_get_client_rect(win(), &wr);
const int bar_h = BUTTONROW_SIZE * CHARY;
const int bar_y = wr.bottom - bar_h + 1;
for (int i = 0; i < _modules.items(); i++)
{
TImage& image = (TImage&)_modules[i];
const int iy = bar_y + (bar_h - image.height()) / 2;
image.set_pos(4, iy);
}
const int buttons = _button.items();
if (buttons > 0)
{
RCT br; ((TPushbutton_control&)_button[0]).get_rect(br);
const int width = br.right - br.left;
int space = ((wr.right - wr.left) - buttons * width) / (buttons + 1);
if (space < 0)
space = 0;
int x = space;
const int by = br.top;
for (int b = 0; b < buttons; b++)
{
const PNT p = { by, x };
xvt_rect_set_pos(&br, p);
((TPushbutton_control&)_button[b]).set_rect(br);
x += space + width;
}
}
}
}
void TViswin::open ()
{
set_scroll_max (MAXLEN - 1, _txt.lines () <= _textrows ? _txt.lines () : _txt.lines () - _textrows);
repos_buttons();
TScroll_window::open();
show_buttons(_showbuts);
force_update ();
}
// prints the window contents
void TViswin::paint_screen ()
{
RCT clip; get_clip_rect(clip);
clip.left = clip.top = 0;
xvt_dwin_set_clip(win(), &clip);
for (int j = 0; j < _textrows; j++)
{
const long rw = origin ().y + j;
if (rw < _txt.lines ())
paint_row (rw);
else
{
if (!_isopen)
{
autoscroll (FALSE);
set_mode (M_COPY);
set_pen (COLOR_BLACK);
PNT b, e;
b.h = tabx(X_OFFSET-1);
b.v = taby((int)(j + (long)Y_OFFSET - origin().y))/* -2 *****/;
e.h = tabx(columns());
e.v = b.v;
xvt_dwin_draw_set_pos(win(), b);
xvt_dwin_draw_line(win(), e);
set_pen (COLOR_LTGRAY);
e.v++;
b.v++;
xvt_dwin_draw_set_pos (win (), b);
xvt_dwin_draw_line (win (), e);
set_brush (COLOR_DKGRAY);
bar (X_OFFSET-1, (int)(j+(long)Y_OFFSET-origin().y),
(int)columns()+1, (int)(rows()-(long)BUTTONROW_SIZE));
autoscroll (TRUE);
}
break;
}
}
}
// @doc INTERNAL
// @mfunc Permette di stampare il background
void TViswin::paint_background(
long j, // @parm Numero della riga di cui stampare il background
int row) // @parm Numero della riga a video sulla quale viene stampato il background
{
TPrinter& pr = printer();
if (_toplevel)
{
const word page = word((j-1) / pr.formlen() + 1);
_bg = &pr.getbgdesc(page);
}
const bool isbackground = _bg->items() > 0 && pr.isgraphics();
const bool fink_mode = pr.get_fink_mode();
const int rw = (int)(j % (long)_formlen);
const int ox = (int)origin().x;
const int mx = ox + columns();
if (!fink_mode)
{
const char* line = pr.background_chars(rw);
set_color(COLOR_BLACK, COLOR_WHITE);
if (line != NULL && (int)strlen(line) > ox)
stringat (X_OFFSET, row, &line[ox]);
// return;
}
if (!isbackground)
return;
const TString& rwd = _bg->row(rw);
char curcol = 'n';
char curpen = 'n';
char curpat = 'n';
char curwid = '1';
int x1, x2, y1, y2, id;
PNT b, e;
int cnt = 0;
char ch;
bool isbeg = FALSE;
bool isend = FALSE;
while ((ch = rwd[cnt++]) != '\0')
{
if (!fink_mode && (ch == 'v' || ch == 'o' || ch == 'u' || ch == 'h' || ch == 'r'))
continue;
switch (ch)
{
case 'v': // verticale intera
x1 = (byte)rwd[cnt++];
if (x1 >= ox && x1 <= mx)
{
x1 += (X_OFFSET-1) - ox;
b.h = e.h = tabx(2*x1+1)/2;
b.v = taby(row);
e.v = taby(row+1);
xvt_dwin_draw_set_pos(win(), b);
xvt_dwin_draw_line(win(), e);
}
break;
case 'o': // verticale pezzo sopra
x1 = (byte)rwd[cnt++];
if (x1 >= ox && x1 <= mx)
{
x1 += (X_OFFSET -1) - ox;
b.h = e.h = tabx(2*x1+1) / 2;
b.v = taby(row);
e.v = taby(2*row+1)/2;
xvt_dwin_draw_set_pos (win(), b);
xvt_dwin_draw_line (win(), e);
}
break;
case 'u': // verticale pezzo sotto
x1 = (byte)rwd[cnt++];
if (x1 >= ox && x1 <= mx)
{
x1 += (X_OFFSET -1) - ox;
b.h = e.h = tabx(2*x1+1)/2;
b.v = taby(2*row+1)/2;
e.v = taby(row + 1);
xvt_dwin_draw_set_pos(win(), b);
xvt_dwin_draw_line(win(), e);
}
break;
case 'h': // orizzontale intera
// x1 = (byte) rwd[cnt++] + (X_OFFSET -1) - ox;
// x2 = (byte) rwd[cnt++] + (X_OFFSET -1) - ox;
x1 = (byte) rwd[cnt++];
x2 = (byte) rwd[cnt++];
if (x1 <= mx && x2 >= ox)
{
x1 += (X_OFFSET -1) - ox;
if (x1 < X_OFFSET) x1 = X_OFFSET;
x2 += (X_OFFSET -1) - ox;
b.v = e.v = taby(2*row+1) / 2;
b.h = tabx(x1);
e.h = tabx(x2 + 1);
xvt_dwin_draw_set_pos(win(), b);
xvt_dwin_draw_line(win(), e);
}
break;
case 'r': // orizzontale scorciata agli estremi
x1 = (byte) rwd[cnt++];
x2 = (byte) rwd[cnt++];
isbeg = ox <= (x1-1);
isend = mx >= (x2-1);
if (x1 <= mx && x2 >= ox)
{
x1 += (X_OFFSET -1) - ox;
if (x1 < X_OFFSET) x1 = X_OFFSET;
x2 += (X_OFFSET -1) - ox;
b.v = e.v = taby(2*row+1) / 2;
if (isbeg) b.h = tabx(2*x1+1) / 2;
else b.h = tabx(x1);
if (isend) e.h = tabx(2*x2+1) / 2;
else e.h = tabx(x2 +1);
xvt_dwin_draw_set_pos(win(), b);
xvt_dwin_draw_line(win(), e);
}
break;
case 'i':
id = (byte)(rwd[cnt++])-1; // Numero immagine
y1 = (byte)(rwd[cnt++])-1; // Riga sorgente
x1 = (byte)(rwd[cnt++])-1; // Colonna destinazione
x2 = (byte)(rwd[cnt++]); // Larghezza destinazione (in caratteri)
y2 = (byte)(rwd[cnt++]); // Altezza destinazione (in caratteri)
if (id >= 0)
{
TImage* i = (TImage*)_images.objptr(id);
if (i == NULL)
{
const TString_array& a = pr.image_names();
const TImage src(a.row(id));
if (src.ok())
{
i = new TImage(src, x2*CHARX, y2*CHARY);
_images.add(i, id);
}
}
if (i && i->ok())
{
RCT src; xvt_rect_set(&src, 0, y1*CHARY, i->width(), min((y1+1)*CHARY, i->height()));
RCT dst; xvt_rect_set(&dst, 0, 0, tabx(x2), taby(1));
xvt_rect_offset(&dst, tabx(x1-origin().x+X_OFFSET), taby(row));
i->draw(win(), dst, src);
}
}
break;
case 'W':
curwid = rwd[cnt++];
set_pen (trans_color (curcol), curwid - '0', trans_brush (curpat),
trans_pen (curpen));
break;
case 'P':
curpen = rwd[cnt++];
set_pen (trans_color (curcol), curwid - '0', trans_brush (curpat),
trans_pen (curpen));
break;
case 'B':
curpat = rwd[cnt++];
set_pen (trans_color (curcol), curwid - '0', trans_brush (curpat),
trans_pen (curpen));
break;
case 'C':
curcol = rwd[cnt++];
set_pen (trans_color (curcol), curwid - '0', trans_brush (curpat),
trans_pen (curpen));
break;
default:
break;
}
}
// restore default pen
set_pen (COLOR_BLACK);
}
void TViswin::get_clip_rect(RCT& clip) const
{
xvt_vobj_get_client_rect(win(), &clip);
if (_rulers)
{
clip.left += tabx(X_OFFSET);
clip.top += taby(1);
}
if (_showbuts)
clip.bottom = clip.top + taby(int(_textrows));
}
void TViswin::paint_image(int row, const char* cp)
{
TToken_string tok(cp+2, ',');
TImage img(tok.get(0));
RCT clip; get_clip_rect(clip);
xvt_dwin_set_clip(win(), &clip);
const int x = tabx(X_OFFSET+tok.get_int()-int(origin().x)-1);
const int y = taby(row);
int dx = tabx(tok.get_int(3)-tok.get_int(1)+1);
int dy = taby(tok.get_int(4)-tok.get_int(2)+1);
if (img.ok())
{
const double ratiox = double(img.width()) / dx;
const double ratioy = double(img.height()) / dy;
const double ratio = ratiox > ratioy ? ratiox : ratioy;
dx = int(img.width() / ratio);
dy = int(img.height() / ratio);
RCT dst; xvt_rect_set(&dst, x, y, x+dx, y+dy);
img.draw(win(), dst);
}
else
{
RCT dst; xvt_rect_set(&dst, x, y, x+dx, y+dy);
set_pen(COLOR_RED);
xvt_dwin_draw_rect(win(), &dst);
}
xvt_dwin_set_clip(win(), NULL);
}
void TViswin::paint_row (long j)
{
if (need_paint_sel (FALSE))
{
TPoint p1, p2;
adjust_selection (p1, p2);
}
const long y = origin ().y;
const int row = (int) (j + (long)Y_OFFSET - y);
autoscroll(FALSE);
set_font(PRINT_FONT, XVT_FS_NONE, PRINT_HEIGHT);
set_mode(M_COPY);
set_opaque_text(TRUE);
if (_rulers)
{
set_color(FOREGROUND, BACKGROUND);
set_brush(BACKGROUND);
printat(0, row, "%05ld", j + 1);
}
if (_scrolling)
{
hide_pen ();
set_brush (COLOR_WHITE);
RCT r;
r.top = row * CHARY;
r.left = tabx(X_OFFSET -1),
r.bottom = r.top + taby(1)/* + 1*/;
r.right = tabx(255);
xvt_dwin_draw_rect (win (), &r);
}
paint_background(j, row);
set_opaque_text(FALSE);
const char *cp;
int pos = 0;
_txt.read_line (j, origin().x);
while ((cp = _txt.piece ()) != NULL)
{
const int st = _txt.get_style();
const COLOR bg = trans_color(_txt.get_background());
const COLOR fg = trans_color(_txt.get_foreground());
if (bg == fg)
{
if (*cp == 'i')
paint_image(row, cp);
}
else
{
set_font(PRINT_FONT, st, PRINT_HEIGHT);
set_color(fg, bg);
stringat(X_OFFSET+pos, row, cp);
}
pos += strlen (cp);
}
if (_scrolling && (pos < _textcolumns))
{
set_color (COLOR_BLACK, COLOR_WHITE);
TString256 fill; fill.spaces(256);
stringat(X_OFFSET+pos, row, fill);
}
if ((j % _formlen) == (_formlen - 1) && _toplevel) // last row
{
PNT b, e;
b.h = tabx(X_OFFSET -1);
b.v = taby(row + Y_OFFSET) - 1;
e.h = tabx(164);
e.v = taby(row + Y_OFFSET) - 1;
set_pen (COLOR_LTGRAY, 2, PAT_SOLID, P_DASH);
xvt_dwin_draw_set_pos (win(), b);
xvt_dwin_draw_line (win(), e);
}
autoscroll (TRUE);
}
// @doc INTERNAL
// @mfunc Disegna una colonna
void TViswin::paint_column (
long j, // @parm Colonna da disegnare
bool end) // @parm Indica se si tratta dell'ultima colonna:
//
// @flag TRUE | E' l'ultima colonna ed implica uno scroll orizzonatle avvenuto
// @flag FALSE | Non e' l'ultima colonna
{
paint_header ();
set_opaque_text (FALSE);
set_mode (M_COPY);
TPoint p1, p2;
if (need_paint_sel (FALSE))
adjust_selection (p1, p2);
set_color (COLOR_BLACK, COLOR_WHITE);
autoscroll (FALSE);
RCT clipper;
xvt_rect_set(&clipper, tabx(X_OFFSET), 0, tabx(X_OFFSET+1), taby(int(_textrows + 1)));
if (end)
xvt_rect_offset(&clipper, tabx(int(_textcolumns-1)), 0);
xvt_dwin_set_clip(win(), &clipper);
const int col = end ? (int) (_textcolumns + X_OFFSET -1) : X_OFFSET;
set_brush(COLOR_WHITE);
bar(col, Y_OFFSET, col+1, int(_textrows + Y_OFFSET));
const long orig_y = origin().y;
const long last = min(_txt.lines() - orig_y, _textrows);
for (long l = 0L; l < last; l++)
{
const long riga_txt = orig_y + l;
const int riga_scr = (int)l+Y_OFFSET;
paint_background (riga_txt, riga_scr);
if ((riga_txt% _formlen) == (_formlen - 1) && _toplevel)
{
PNT b, e;
b.h = tabx(short(col));
b.v = taby(riga_scr+1) -1 ;
e.h = tabx(short(col+1));
e.v = taby(riga_scr+1) -1;
set_pen (COLOR_LTGRAY, 2, PAT_SOLID, P_DASH);
xvt_dwin_draw_set_pos (win(), b);
xvt_dwin_draw_line (win(), e);
}
const char *c = (const char *) _txt.line (riga_txt);
const int st = _txt.get_style ((int) j);
set_font (PRINT_FONT, st, PRINT_HEIGHT);
COLOR bg = trans_color (_txt.get_background ((int) j));
COLOR fg = trans_color (_txt.get_foreground ((int) j));
set_color (fg, bg);
char str[2] = { (unsigned int)j < strlen (c) ? c[(int)j] : ' ', '\0' };
stringat (col, riga_scr, str);
}
xvt_dwin_set_clip(win(), NULL);
autoscroll (TRUE);
}
void TViswin::draw_crossbars ()
// prints reference crossbars
{
if (_cross.v > taby(1) && _cross.v < taby(rows () - BUTTONROW_SIZE) &&
_cross.h > tabx (X_OFFSET - 1) && _cross.h < tabx(columns()) )
{
set_pen (COLOR_BLACK);
set_mode (M_XOR);
PNT b1, e1, b2, e2;
autoscroll (FALSE);
b1.h = _cross.h;
b1.v = taby(Y_OFFSET);
e1.h = _cross.h;
e1.v = taby((rows() - BUTTONROW_SIZE + (_rulers ? 0 : 1)));
b2.h = tabx(X_OFFSET -1);
b2.v = _cross.v;
e2.h = tabx(columns());
e2.v = _cross.v;
xvt_dwin_draw_set_pos (win (), b1);
xvt_dwin_draw_line (win (), e1);
xvt_dwin_draw_set_pos (win (), b2);
xvt_dwin_draw_line (win (), e2);
autoscroll (TRUE);
}
}
void TViswin::display_crossbar ()
{
if (!_cross_displayed)
draw_crossbars ();
_cross_displayed = TRUE;
}
void TViswin::erase_crossbar ()
{
if (_cross_displayed)
draw_crossbars ();
_cross_displayed = FALSE;
}
void TViswin::display_point()
{
if (!_point_displayed)
paint_point ();
_point_displayed = TRUE;
}
void TViswin::erase_point()
{
if (_point_displayed)
paint_point ();
_point_displayed = FALSE;
}
// @doc INTERNAL
// @mfunc Disegna il cursore in xor nello stile del momento
void TViswin::paint_point (
bool erase) // @parm Indica di cancellare il cursore precedente (default FALSE):
//
// @flag TRUE | Cancella il cursore precedente
// @flag FALSE | Mantiene il cursore precedente
{
autoscroll (FALSE);
const int x = int(_point.x - origin().x + X_OFFSET);
const int y = int(_point.y - origin().y + Y_OFFSET);
if (_isbar)
{
invert_bar (X_OFFSET, y, (int)columns(), y+1);
invert_bar (x, Y_OFFSET, x+1, (int)(rows() - BUTTONROW_SIZE));
}
else
{
invert_bar (x, y, x+1, y+1);
if (_rulers)
{
invert_bar (0, y, X_OFFSET-1, y+1);
invert_bar (x, 0, x+1, 1);
}
}
autoscroll (TRUE);
}
// draw screen header
void TViswin::paint_header ()
{
if (!_rulers)
return;
set_mode (M_COPY);
set_opaque_text (TRUE);
set_color (FOREGROUND, BACKGROUND);
set_font (PRINT_FONT, XVT_FS_NONE, PRINT_HEIGHT);
TString16 htmpst;
for (int i = 1; i < 26; i++)
{
htmpst.format ("%d", i);
htmpst.right_just (10, '.');
xvt_dwin_draw_text(win(), tabx(i*10 - 4 - int(origin().x)), CHARY-2, htmpst, 10);
}
autoscroll (FALSE);
set_color (COLOR_WHITE, BACKGROUND);
printat (0, 0, "P.%3ld", (origin().y / _formlen) + 1L);
autoscroll (TRUE);
}
void TViswin::paint_selection ()
{
TPoint p1, p2;
adjust_selection (p1, p2);
// paint rows
for (long l = p1.y; l <= p2.y; l++)
{
int top, left, right;
top = (int) (l - origin().y + Y_OFFSET);
if (top > 0 && top <= _textrows)
{
left = p1.y == l ? (int)(p1.x-origin().x + (long)X_OFFSET) : X_OFFSET;
right = p2.y == l ? (int)(p2.x-origin().x + (long)X_OFFSET) :
(int)(_textcolumns + (long)X_OFFSET);
autoscroll (FALSE);
invert_bar (left, top, right, top + 1);
autoscroll (TRUE);
}
}
}
// @doc INTERNAL
// @mfunc Disegna la pagina che scorre
void TViswin::paint_waitbar()
{
HIDDEN int pic = 0;
((TImage&)_modules[pic]).draw(win());
pic = (pic+1) & 0x3;
}
void TViswin::txt_clear(COLOR color)
{
autoscroll(FALSE);
set_brush(color);
set_mode(M_COPY);
bar ((X_OFFSET-1), Y_OFFSET -1, columns()+16, rows()-BUTTONROW_SIZE);
}
bool TViswin::can_be_closed() const
{
((TViswin*)this)->on_button(DLG_QUIT);
return FALSE;
}
void TViswin::update ()
{
if (_scrolling || _in_update)
return;
_in_update = TRUE;
erase_point();
autoscroll(FALSE);
set_mode(M_COPY);
if (!_toplevel)
TField_window::update();
check_link();
if (_isselection)
erase_selection ();
txt_clear(COLOR_WHITE);
set_brush (BACKGROUND);
if (_rulers)
{
bar (0, 0, columns() + 1, 1);
bar (0, 0, 5, rows() + 1);
}
if (_showbuts && _isopen)
paint_waitbar();
else
if (_showbuts) ((TImage&)_modules[4]).draw(win());
autoscroll (TRUE);
paint_screen();
paint_header();
if (_isselection)
display_selection();
display_point();
check_link(&_point);
autoscroll (TRUE);
_need_scroll = none;
_in_update = FALSE;
}
void TViswin::abort_print ()
{
if (yesno_box ("Interruzione della stampa su video?"))
{
_txt.freeze ();
freeze ();
printer().freeze();
set_focus ();
close_print();
}
}
void TViswin::scroll_error(long x, long y)
{
beep();
update_thumb(x, y);
}
void TViswin::on_button(short dlg)
{
switch (dlg)
{
case DLG_QUIT:
if (_isopen)
abort_print();
else
{
xvtil_statbar_set("");
xvtil_statbar_refresh();
stop_run(K_ENTER);
}
break;
case DLG_PRINT:
dispatch_e_menu(win(), M_VISWIN_PRINT);
break;
case DLG_PDF:
xvtil_statbar_set ("");
xvtil_statbar_refresh ();
stop_run(CTRL_P);
break;
case DLG_SAVEREC:
check_link();
call_editor();
update();
check_link(&_point);
break;
case DLG_LINK:
exec_link();
break;
default:
TWindow::on_button(dlg);
break;
}
}
long TViswin::handler (WINDOW win, EVENT * ep)
{
static bool ignore = FALSE;
int kdiff_x, kdiff_y;
PNT newcross;
TPoint p;
bool tlnk = FALSE;
int kdiff;
long new_origin;
switch (ep->type)
{
case E_USER:
if (ep->v.user.id == E_ADDLINE)
{
set_scroll_max (MAXLEN - 1, _txt.lines () <= _textrows ?
_txt.lines () : _txt.lines () - _textrows);
}
else if (ep->v.user.id == E_ADDLINE_ONSCREEN)
{
set_scroll_max (MAXLEN - 1, _txt.lines () <= _textrows ? _txt.lines () : _txt.lines () - _textrows);
erase_point ();
if (need_paint_sel (FALSE))
erase_selection ();
paint_row (_txt.lines () - 1l);
if (need_paint_sel (FALSE))
display_selection ();
display_point ();
force_update ();
}
autoscroll (FALSE);
_textrows = TEXTROWS;
_textcolumns = TEXTCOLUMNS;
autoscroll (TRUE);
break;
case E_COMMAND:
if (ep->v.cmd.tag > 1000 && ep->v.cmd.tag < 2000)
{
// bookmark
int index = ep->v.cmd.tag - 1001;
BkDef& bds = (BkDef&)(*_bookmarks)[index];
goto_pos(bds._row, 0l);
}
else switch(ep->v.cmd.tag)
{
case M_VISWIN_STOP: // interrompi
dispatch_e_char(win, K_ESC);
break;
case M_VISWIN_LINK: // collega
dispatch_e_char(win, CTRL_G);
break;
case M_VISWIN_EDIT: // esporta
dispatch_e_char(win, CTRL_E);
break;
case M_VISWIN_PRINT: // stampa
xvtil_statbar_set ("");
xvtil_statbar_refresh ();
stop_run(CTRL_S);
break;
case M_SHOW_RULERS: // mostra righelli
show_rulers(_rulers == 0);
check_menu_item(M_SHOW_RULERS, _rulers != 0);
break;
case M_SHOW_BUTTONS: // mostra bottoni
show_buttons(!_showbuts);
check_menu_item(M_SHOW_BUTTONS, _showbuts);
break;
case M_VISWIN_QUIT: // chiudi
xvtil_statbar_set ("");
xvtil_statbar_refresh ();
stop_run (K_ENTER);
break;
case M_VISWIN_COPY: // copia nella clipboard
dispatch_e_char(win, CTRL_C);
break;
case M_VISWIN_CLEAR: // annulla selezione
dispatch_e_char(win,K_ENTER);
break;
case M_VISWIN_SEARCH: // cerca
find();
break;
case M_VISWIN_NEXT: // cerca il prossimo
find_next();
break;
case M_VISWIN_REDRAW: // ridisegna
refresh();
break;
}
break;
case E_CONTROL:
break;
case E_TIMER:
if (ep->v.timer.id == _timer)
{
xvt_timer_destroy (_timer);
_timer = 0;
}
else if (ep->v.timer.id == _wtimer)
{
if (_showbuts)
paint_waitbar ();
if (!_isopen)
{
xvt_timer_destroy (_wtimer);
_wtimer = 0;
}
}
break;
case E_MOUSE_DBL:
break;
case E_MOUSE_DOWN:
autoscroll(FALSE);
p = dev2log(ep->v.mouse.where);
autoscroll(TRUE);
xvt_win_trap_pointer (win);
if (ep->v.mouse.button == 0) // left button: text selection
{
if (need_paint_sel (FALSE))
{
erase_selection ();
_isselection = FALSE;
}
if (!in_text (p) || (p.y + origin().y) >= _txt.lines ())
{
ignore = TRUE;
break;
}
erase_point ();
// _sel_start = ep->v.mouse.where;
_sel_start = p;
_sel_start.x += (origin ().x - X_OFFSET);
_sel_start.y += (origin ().y - Y_OFFSET);
_sel_end = _sel_start;
_selecting = TRUE;
}
else
{
// show crossbars
_cross = ep->v.mouse.where;
display_crossbar ();
_iscross = TRUE;
}
break;
case E_MOUSE_UP:
xvt_win_release_pointer ();
if (ep->v.mouse.button == 0) // left button: text selection/move
// point
{
autoscroll(FALSE);
p = dev2log(ep->v.mouse.where);
autoscroll(TRUE);
if (_isopen && _toplevel && (p.x >= 4 && p.x <= X_OFFSET) &&
(p.y >= (int)rows() - BUTTONROW_SIZE && p.y <= (int)rows() - Y_OFFSET))
{
abort_print ();
ignore = TRUE;
}
if (ignore)
{
ignore = FALSE;
_selecting = FALSE;
break;
}
// confirm selection & store
p.x += (origin ().x - X_OFFSET);
p.y += (origin ().y - Y_OFFSET);
if (_sel_start == p)
{
if (_isselection)
{
_isselection = FALSE;
erase_selection ();
}
if (_sel_start == _point && !_selecting)
{
dispatch_e_char (win, K_F5);
}
else
{
_point.x = p.x;
_point.y = p.y;
if (_point.y > _txt.lines ())
_point.y = _txt.lines () - 1l;
if (_point.y < 0)
_point.y = 0;
if (_point.x < 0)
_point.x = 0;
if (_point.x > 255)
_point.x = 255;
check_link (&_point);
display_point ();
}
}
else
{
_sel_end.x = p.x;
_sel_end.y = p.y;
if (_sel_end.y >= _txt.lines ())
_sel_end.y = _txt.lines () - 1l;
if (_sel_end.y < 0)
_sel_end.y = 0;
if (_sel_end.x < 0)
_sel_end.x = 0;
if (_sel_end.x > 255)
_sel_end.x = 255;
_point = _sel_end;
_isselection = _selecting;
check_link (&_point);
display_point ();
}
_selecting = FALSE;
}
else
{
erase_crossbar ();
_iscross = FALSE;
}
break;
case E_MOUSE_MOVE:
{
if (_selecting || _iscross)
{
autoscroll(FALSE);
p = dev2log(ep->v.mouse.where);
autoscroll(TRUE);
if (_selecting)
_isselection = TRUE;
// scroll if necessary
if (p.y >= _textrows + 1l)
{
if (_isselection)
erase_selection ();
if (_iscross)
erase_crossbar ();
dispatch_e_scroll (win, K_DOWN);
if (_isselection)
display_selection ();
if (_iscross)
display_crossbar ();
}
else if (p.y <= 0l)
{
if (_isselection)
erase_selection ();
if (_iscross)
erase_crossbar ();
dispatch_e_scroll (win, K_UP);
if (_isselection)
display_selection ();
if (_iscross)
display_crossbar ();
}
else if (p.x <= (long)(X_OFFSET - 1))
{
if (_isselection)
erase_selection ();
if (_iscross)
erase_crossbar ();
dispatch_e_scroll (win, K_LEFT);
if (_isselection)
display_selection ();
if (_iscross)
display_crossbar ();
}
else if (p.x >= _textcolumns + X_OFFSET)
{
if (_isselection)
erase_selection ();
if (_iscross)
erase_crossbar ();
dispatch_e_scroll (win, K_RIGHT);
if (_isselection)
display_selection ();
if (_iscross)
display_crossbar ();
}
if (_selecting)
{
if (in_text (p))
{
p.x += (origin ().x - X_OFFSET);
p.y += (origin ().y - Y_OFFSET);
_point = p;
if (_point.y >= _txt.lines ())
_point.y = _txt.lines () - 1l;
}
if (_point != _sel_end)
{
erase_selection ();
_sel_end = _point;
display_selection ();
}
}
}
if (_iscross)
{
newcross = ep->v.mouse.where;
if (_cross.h != newcross.h || _cross.v != newcross.v)
{
erase_crossbar ();
_cross = newcross;
display_crossbar ();
}
}
}
break;
case E_SIZE:
if (is_open ())
{
check_link ();
erase_point ();
if (_isselection)
erase_selection ();
autoscroll (FALSE);
_textrows = TEXTROWS;
_textcolumns = TEXTCOLUMNS;
autoscroll (TRUE);
repos_buttons ();
display_point ();
force_update ();
do_events ();
check_link (&_point);
}
break;
case E_HSCROLL:
case E_VSCROLL:
{
erase_point ();
tlnk = TRUE;
switch (ep->v.scroll.what)
{
case SC_PAGE_UP:
if (ep->type == E_VSCROLL)
{
if (origin().y > 0)
{
kdiff = (int) (_point.y - origin ().y);
new_origin = origin ().y > _textrows ?
origin().y - _textrows + 1l : 0;
_point.y = new_origin + kdiff;
check_link ();
update_thumb (origin ().x, new_origin);
update (); // ORRIIIBILE!
check_link (&_point);
}
else scroll_error(-1, 0);
}
else
{
if (origin ().x > 0)
{
kdiff = (int) (_point.x - origin ().x);
new_origin = origin ().x > _textcolumns ?
origin().x - _textcolumns + 1 : 0;
_point.x = new_origin + kdiff;
check_link ();
update_thumb(new_origin, origin().y);
update (); // AAAARGH!
check_link (&_point);
}
else scroll_error(0, -1);
}
break;
case SC_LINE_UP:
if (ep->type == E_VSCROLL)
{
if (origin ().y > 0l)
{
_point.y--;
if (need_paint_sel ())
erase_selection ();
check_link ();
update_thumb (origin().x, origin().y - 1l);
//_need_scroll = down;
update (); // AAAARGH!
check_link (&_point);
}
else scroll_error(-1, 0);
}
else
{
if (origin ().x > 0l)
{
if (need_paint_sel (FALSE))
erase_selection ();
check_link ();
update_thumb (origin().x - 1l, origin().y);
_point.x--;
_need_scroll = right;
}
else scroll_error(0, -1);
}
break;
case SC_PAGE_DOWN:
if (ep->type == E_VSCROLL)
{
if ((origin().y + _textrows) < _txt.lines())
{
kdiff = (int) (_point.y - origin ().y);
new_origin = (_txt.lines () - origin ().y) >
(_textrows * 2l) ?
origin ().y + _textrows - 1 : _txt.lines () - _textrows;
_point.y = new_origin + kdiff;
check_link ();
update_thumb (origin ().x, new_origin);
update (); // AAAARGH!
check_link (&_point);
}
else scroll_error(-1, _txt.lines()-_textrows/*-1*/);
}
else
{
if ((origin().x + _textcolumns) < 256)
{
kdiff = (int) (_point.x - origin ().x);
new_origin = (256 - origin ().x) > _textcolumns ?
origin ().x + _textcolumns - 1 : 256 - _textcolumns;
_point.x = new_origin + kdiff;
check_link ();
update_thumb (new_origin, origin().y);
update (); // AAAARGH!
check_link (&_point);
}
else scroll_error(255-_textcolumns, -1);
}
break;
case SC_LINE_DOWN:
if (ep->type == E_VSCROLL)
{
if ((origin().y + _textrows) < _txt.lines ())
{
if (need_paint_sel ())
erase_selection ();
check_link ();
update_thumb (origin ().x, origin ().y + 1l);
_point.y++;
// _need_scroll = up;
update (); // AAAARGH!
check_link (&_point);
}
else scroll_error(-1, _txt.lines()-_textrows/*-1*/);
}
else
{
if ((origin ().x + _textcolumns) < 256)
{
if (need_paint_sel (FALSE))
erase_selection ();
check_link ();
update_thumb (origin ().x + 1l, origin ().y);
_need_scroll = left;
_point.x++;
}
else scroll_error(255-_textcolumns, -1);
}
break;
case SC_THUMB:
check_link ();
kdiff_x = (int) (_point.x - origin ().x);
kdiff_y = (int) (_point.y - origin ().y);
p.x = ep->type == E_VSCROLL ? origin ().x : ep->v.scroll.pos;
p.y = ep->type == E_HSCROLL ? origin ().y : ep->v.scroll.pos;
if ((p.y + _textrows) >= _txt.lines ())
p.y = _txt.lines () - _textrows -1;
if ((p.x + _textcolumns) >= 255)
p.x = 255 - _textcolumns;
update_thumb (p.x, p.y);
_point.x = ep->type == E_VSCROLL ? origin ().x :
origin ().x + kdiff_x;
_point.y = ep->type == E_HSCROLL ? origin ().y :
origin ().y + kdiff_y;
update ();
check_link (&_point);
break;
default:
break;
}
// for failed scrollings
if (!_selecting && _need_scroll == none)
{
check_link (&_point);
display_point ();
}
}
break;
default:
break;
}
if (_need_scroll != none)
{
const scroll tmp = _need_scroll;
_need_scroll = none;
shift_screen (tmp);
if (!_selecting)
{
check_link (&_point);
display_point ();
}
if (_isselection)
display_selection ();
}
return TWindow::handler (win, ep);
}
bool TViswin::on_key(KEY key)
{
if (_timer)
return TRUE;
_timer = xvt_timer_create (win (), 50l);
EVENT_TYPE type = E_USER;
if (key == K_UP || key == K_DOWN || key == K_LEFT || key == K_RIGHT)
if (_selflag)
key += K_SHIFT;
if (_selecting && key != K_SHIFT_UP && key != K_SHIFT_DOWN
&& key != K_SHIFT_LEFT && key != K_SHIFT_RIGHT)
_selecting = FALSE;
switch (key)
{
case K_F7:
find();
break;
case K_F3:
find_next();
break;
case CTRL_E:
if (_isedit)
{
check_link ();
call_editor ();
set_focus ();
update ();
check_link (&_point);
}
break;
case CTRL_G:
exec_link();
break;
case CTRL_C:
sel_to_clipboard();
break;
case CTRL_S:
if (_isprint)
stop_run(CTRL_S);
break;
case CTRL_P:
if (_isprint)
stop_run(CTRL_P);
break;
case CTRL_R:
check_link ();
force_update ();
do_events ();
check_link (&_point);
break;
case K_ESC:
if (_isopen && _toplevel)
abort_print ();
else
{
xvtil_statbar_set ("");
xvtil_statbar_refresh ();
stop_run (K_ESC);
}
break;
case K_ENTER:
if (_isselection)
{
erase_selection ();
_isselection = FALSE;
}
if (_toplevel)
exec_link();
break;
case K_TAB:
if (!_toplevel)
{
TMask& m = owner().mask();
const int pos = m.id2pos(owner().dlg());
for (int i = pos+1; i < m.fields(); i++)
{
const TMask_field& f = m.fld(i);
if (f.active())
{
m.set_focus_field(f.dlg());
break;
}
}
}
break;
case K_BTAB:
if (!_toplevel)
{
TMask& m = owner().mask();
const int pos = m.id2pos(owner().dlg());
for (int i = pos-1; i >= 0; i--)
{
const TMask_field& f = m.fld(i);
if (f.active())
{
m.set_focus_field(f.dlg());
break;
}
}
}
break;
case K_SPACE:
case K_CTRL_ENTER:
if (_linkID != -1)
exec_link();
break;
case K_LHOME:
update_thumb (0, 0);
_point.set (0, 0);
check_link (&_point);
force_update();
break;
case K_LEND:
update_thumb (0, _txt.lines () - _textrows);
_point.set (0, _txt.lines () - 1);
check_link (&_point);
force_update();
break;
case K_RIGHT:
case K_LEFT:
case K_WRIGHT:
case K_WLEFT:
case K_ALT_RIGHT:
case K_ALT_LEFT:
case K_SHIFT_RIGHT:
case K_SHIFT_LEFT:
type = E_HSCROLL;
break;
case K_UP:
case K_DOWN:
case K_NEXT:
case K_PREV:
case K_CTRL_UP:
case K_CTRL_DOWN:
case K_SHIFT_UP:
case K_SHIFT_DOWN:
type = E_VSCROLL;
break;
case K_F5:
check_link ();
erase_point ();
_isbar = !_isbar;
force_update ();
do_events ();
check_link (&_point);
break;
case K_F6:
_selflag = !_selflag;
break;
case '+':
if (PRINT_HEIGHT <= 14)
{
PRINT_HEIGHT += 2;
force_update();
}
break;
case '-':
if (PRINT_HEIGHT >= 6)
{
PRINT_HEIGHT -= 2;
force_update();
}
default:
break;
}
switch (type)
{
case E_HSCROLL:
case E_VSCROLL:
{
erase_point ();
check_link ();
switch (key)
{
case K_PREV:
dispatch_e_scroll (win(), K_PREV);
break;
case K_NEXT:
dispatch_e_scroll (win(), K_NEXT);
break;
case K_WLEFT:
dispatch_e_scroll (win(), K_BTAB);
break;
case K_WRIGHT:
dispatch_e_scroll (win(), K_TAB);
break;
case K_CTRL_UP:
dispatch_e_scroll (win(), K_UP);
break;
case K_CTRL_DOWN:
dispatch_e_scroll (win(), K_DOWN);
break;
case K_ALT_LEFT:
dispatch_e_scroll (win(), K_LEFT);
break;
case K_ALT_RIGHT:
dispatch_e_scroll (win(), K_RIGHT);
break;
case K_UP:
case K_SHIFT_UP:
if (key == K_SHIFT_UP)
{
if (need_paint_sel (FALSE))
erase_selection ();
if (!_selecting)
{
_sel_start = _point;
_selecting = TRUE;
}
}
if (_point.y > 0l)
{
if (_point.y == origin ().y)
{
if (need_paint_sel ())
erase_selection ();
update_thumb (origin ().x, --_point.y);
_need_scroll = down;
}
else
_point.y--;
if (key == K_SHIFT_UP)
{
_sel_end = _point;
_isselection = TRUE;
}
}
else
beep ();
break;
case K_LEFT:
case K_SHIFT_LEFT:
if (_point.x > 0l)
{
if (key == K_SHIFT_LEFT)
{
if (need_paint_sel (FALSE))
erase_selection ();
if (!_selecting)
{
_sel_start = _point;
_selecting = TRUE;
}
}
if (_point.x == origin ().x)
{
if (need_paint_sel (FALSE))
erase_selection();
update_thumb (--_point.x, origin ().y);
_need_scroll = right;
}
else
_point.x--;
if (key == K_SHIFT_LEFT)
{
_sel_end = _point;
_isselection = TRUE;
}
}
else
beep ();
break;
case K_DOWN:
case K_SHIFT_DOWN:
if (_point.y < (_txt.lines() - 1))
{
if (key == K_SHIFT_DOWN)
{
if (need_paint_sel (FALSE))
erase_selection();
if (!_selecting)
{
_sel_start = _point;
_selecting = TRUE;
}
}
if (_point.y == origin().y + _textrows - 1)
{
if (need_paint_sel())
erase_selection();
// check_link();
update_thumb (origin().x, (++_point.y) - _textrows + 1);
_need_scroll = up;
}
else
_point.y++;
if (key == K_SHIFT_DOWN)
{
_sel_end = _point;
_isselection = TRUE;
}
}
else
beep ();
break;
case K_RIGHT:
case K_SHIFT_RIGHT:
if (_point.x < 256)
{
if (key == K_SHIFT_RIGHT)
{
if (need_paint_sel (FALSE))
erase_selection ();
if (!_selecting)
{
_sel_start = _point;
_selecting = TRUE;
}
}
if (_point.x == (origin ().x + _textcolumns - 1))
{
if (need_paint_sel (FALSE))
erase_selection ();
// check_link();
update_thumb ((++_point.x) - _textcolumns + 1l, origin ().y);
_need_scroll = left;
}
else
_point.x++;
if (key == K_SHIFT_RIGHT)
{
_sel_end = _point;
_isselection = TRUE;
}
}
else
beep();
break;
default:
break;
}
if (_need_scroll != none)
{
scroll tmp = _need_scroll;
_need_scroll = none;
shift_screen (tmp);
}
if (_isselection)
display_selection ();
check_link (&_point);
update();
}
break;
default:
break;
}
return TWindow::on_key (key);
}
void TViswin::sel_to_clipboard()
{
if (!_isselection)
return;
TPoint p1, p2;
adjust_selection (p1, p2);
TString_array txt;
_txt.write(txt, &p1, &p2);
long size = 0l; int eol_len = strlen(EOL_SEQ);
xvt_cb_open(TRUE); // open clipboard
int i;
for (i = 0; i < txt.items(); i++)
size += txt.row(i).len() + eol_len;
char* p = xvt_cb_alloc_data(size); // allocate clipboard
if (p == NULL)
{
error_box(FR("Impossibile allocare una clipboard di %ld bytes"), size);
return;
}
// put data
for (i = 0; i < txt.items(); i++)
{
const TString& s = txt.row(i);
const int slen = s.len();
int j;
for (j = 0; j < slen; j++)
*p++ = s[j];
for (j = 0; j < eol_len; j++)
*p++ = EOL_SEQ[j];
}
if (!xvt_cb_put_data(CB_TEXT, NULL, size, (PICTURE)NULL))
error_box("Errore di copiatura del testo nella clipboard");
xvt_cb_free_data(); // free memory
xvt_cb_close(); // close clipboard
}
bool TViswin::call_editor()
{
TFilename pdf;
const KEY key = spotlite_ask_name(pdf);
bool ok = key >= 'A' && key <= 'Z';
switch (key)
{
case 'A':
ok = printer().print_pdf(_txt, pdf);
if (ok)
spotlite_notify(pdf);
break;
case 'X':
ok = _txt.write_xls(pdf);
if (ok)
::edit_url(pdf);
break;
case 'E':
if (_isselection)
{
TPoint p1, p2;
adjust_selection (p1, p2);
ok = _txt.write (pdf, &p1, &p2);
}
else
ok = _txt.write (pdf, NULL, NULL);
if (ok)
::edit_url(pdf);
break;
case 'M':
ok = printer().print_pdf(_txt, pdf);
if (ok)
spotlite_send_mail(pdf);
break;
case 'P':
ok = printer().print_pdf(_txt, pdf);
if (ok)
xvt_sys_goto_url(pdf, "open");
break;
default:
ok = false;
break;
}
return ok;
}
void TViswin::add_line (const char *l)
{
if (_isopen && !_frozen)
{
if (_txt.frozen ()) // error writing files
{
close_print ();
return;
}
_txt.append (l);
const long tot = _txt.lines();
const bool visible = (tot - origin().y) <= _textrows;
if (visible)
{
EVENT ev;
ev.type = E_USER;
ev.v.user.id = E_ADDLINE_ONSCREEN;
xvt_win_dispatch_event (win(), &ev);
}
else
set_scroll_max (MAXLEN - 1, tot-1);
if ((tot & 0xF) == 0)
do_events ();
}
}
void TViswin::destroy_lines()
{
if (_isopen && !_frozen)
{
_txt.destroy();
force_update();
}
}
void TViswin::close_print ()
{
_isopen = FALSE;
if (_showbuts)
{
xvt_timer_destroy (_wtimer);
_wtimer = 0;
}
if (_toplevel)
{
xvt_menu_set_item_title(win(), M_VISWIN_QUIT, TR("Fine\tESC"));
enable_menu_item(M_VISWIN_STOP, FALSE);
if (_isedit)
enable_button(DLG_SAVEREC);
if (_isprint)
{
enable_button(DLG_PRINT);
enable_menu_item(M_VISWIN_PRINT, TRUE);
}
// build bookmark menu tree
_bookmarks = &(printer().get_bookmarks());
if (_bookmarks->items() > 0)
build_index_menu();
}
const TImage* i = (TImage*)_images.objptr(0);
set_scroll_max (MAXLEN - 1, _txt.lines () <= _textrows ? _txt.lines () : _txt.lines () - _textrows);
force_update ();
}
void TViswin::goto_end()
{
goto_pos(0l, _txt.lines () - _textrows);
}
void TViswin::goto_top()
{
goto_pos(0l,0l);
}
// @doc INTERNAL
// @mfunc Sposta la visualizzazione di stampa alla posizione indicata
void TViswin::goto_pos(
long r, // @parm Riga a cui spostare la visualizzazione di stampa
long c, // @parm Colonna a cui spostare la visualizzazione di stampa
bool moveorigin) // @parm Indica se occorre spostare l'origine (default TRUE)
// @xref <mf TViswin::goto_top> e <mf TViswin::goto_end>
{
if (r >= _txt.lines() || c >= 256)
return;
check_link();
erase_point();
if (_isselection) erase_selection();
_point.x = c;
_point.y = r;
if (!moveorigin)
c = (c > (origin().x + _textcolumns)) ? c - origin().x : 0l;
if (_txt.lines() > _textrows)
update_thumb(c,r);
check_link(&_point);
if (_isselection) display_selection();
display_point();
refresh();
}
void TViswin::refresh()
{
force_update();
}
// @doc INTERNAL
// @mfunc Funzione di ricerca non interattiva
//
// @rdesc Ritorna la riga in cui e' stata trovato il testo (-1 se non e' stato trovato)
long TViswin::search(
const char* txt, // @parm Testo da cercare
int& pos, // @parm Intero in cui posizionare la posizione del carattere
long from, // @parm Posizione all'interno della riga da cui iniziare la ricerca (default 0)
bool down, // @parm Indica se la ricerca va effettuata all'indietro:
//
// @flag TRUE | Ricerca dalla posizione indicata all'inizio della riga (default)
// @flag FALSE | Ricerca dalla posizione indicata alla fine della riga
bool cs, // @parm Indica se ricerca il testo con criterio case sensitive (default FALSE)
bool regx) // @parm indica se considerare espressioni regolari (def FALSE)
{
return _txt.search(txt,pos,from,down, cs, regx);
}
// @doc INTERNAL
// @mfunc Funzione di sostituzione di un testo all'interno di una riga non interattiva
//
// @rdesc Ritorna la posizione in cui e' stato sostituito il testo. Ritorna -1 se non e' stata
// fatto nessuna operazione di sostituzione.
int TViswin::replace(
long l, // @parm Numero della riga nella quale sostituire il testo
const char* txt, // @parm Testo da inserire nella riga
int pos, // @parm Posizione nella quale inserire il testo (default 0)
int len) // @parm Lunghezza del testo da sostituire (default -1)
{
if (l == -1l) return -1;
int ret = _txt.replace(l,txt,pos,len);
if (ret != -1)
{
TPoint p; p.x = pos; p.y = l;
}
return ret;
}
void TViswin::find()
{
TMask m("bagn005");
m.set(F_STRING, _txt_to_find);
m.set(F_DIRECT, _down_dir ? "D" : "U");
m.set(F_CASE, _case_sensitive ? "X" : "");
m.set(F_REGEXP, _regexp ? "X" : "");
if (m.run() == K_ENTER)
{
_txt_to_find = m.get(F_STRING);
_down_dir = m.get(F_DIRECT) == "D";
_case_sensitive = m.get_bool(F_CASE);
_regexp = m.get_bool(F_REGEXP);
int x;
long l = search(_txt_to_find, x, _point.y, _down_dir, _case_sensitive,
_regexp);
if (l == -1l)
{
_last_found.y = -1l;
beep();
}
else
{
goto_pos(l, (long)x, FALSE);
_last_found.x = (long)x;
_last_found.y = l;
}
}
if (_toplevel) enable_menu_item(M_VISWIN_NEXT, TRUE);
}
void TViswin::find_next()
{
int x;
if (_txt_to_find.empty() || _last_found.y == -1l)
beep();
else
{
long l = search(_txt_to_find, x, _point.y+(_down_dir ? 1l : -1l),
_down_dir, _case_sensitive, _regexp);
if (l == -1)
beep();
else
goto_pos(l,x,FALSE);
}
}
void TViswin::show_rulers (bool on)
{
_rulers = on;
autoscroll(FALSE);
_textrows = TEXTROWS;
_textcolumns = TEXTCOLUMNS;
autoscroll(TRUE);
refresh();
}
// @doc INTERNAL
// @mfunc Mostra/nasconde i bottoni della finestra di anteprima
void TViswin::show_buttons(
bool on) // @parm Indica l'operazione da svolgere:
//
// @flag TRUE | Mostra i bottoni della finestra (default)
// @flag FALSE | Nasconde i bottoni della finestra
{
_showbuts = on;
autoscroll (FALSE);
_textrows = TEXTROWS;
_textcolumns = TEXTCOLUMNS;
autoscroll(TRUE);
for (int i = 0; i < _button.items(); i++)
((TPushbutton_control&)_button[i]).show(on);
refresh();
}
TViswin::TViswin(const char *fname,
const char *title,
bool editbutton,
bool printbutton,
bool linkbutton,
int x, int y,
int height, int width,
byte rulers, // overridden by config parms
WINDOW parent,
TBrowsefile_field* brwfld):
TField_window(x, y, width, height, parent, brwfld),
_filename (fname), _islink (linkbutton), _isedit (editbutton),
_isprint (printbutton), _iscross (FALSE), _selecting (FALSE), _isselection (FALSE),
_isbar (FALSE), _scrolling (FALSE), _timer (0), _wtimer(0), _selflag (FALSE), _sel_displayed (FALSE),
_link_displayed (FALSE), _cross_displayed (FALSE), _point_displayed (FALSE),
_need_scroll (none), _txt (fname, BUFFERSIZE), _txt_to_find(64), _in_update(FALSE),
_down_dir(TRUE), _case_sensitive(FALSE), _regexp(FALSE), _multiple (FALSE),
_frozen (FALSE), _rulers(rulers), _showbuts(FALSE), _menu_present(FALSE), _brwfld(brwfld)
{
TWait_cursor hourglass;
if (title == NULL)
title = fname ? fname : "Anteprima di stampa";
_last_found.y = -1;
_isopen = fname == NULL || *fname <= ' ';
if (_isopen)
_filename = _txt.name();
if (parent == NULL_WIN)
parent = TASK_WIN;
_toplevel = brwfld == NULL; // parent == TASK_WIN;
if (_toplevel)
{
// load info from config on buttons and rulers
TConfig cnf(CONFIG_USER, "Visualizzazione");
_showbuts = cnf.get_bool("Bottoni", NULL, -1,TRUE);
// Se rulers vale 3 allora leggi dal config il vero valore
if (_rulers != 0 && _rulers != 1)
_rulers = cnf.get_bool("Righelli", NULL, -1, TRUE);
PRINT_HEIGHT = cnf.get_int("FontSize", NULL, -1, PRINT_HEIGHT);
}
else
PRINT_HEIGHT = 10;
// height = rows(); qui
const int larg = 76;
const int alt = 20;
RCT r;
xvt_vobj_get_client_rect (parent, &r);
int maxlarg = width == 0 ? (r.right / CHARX - 6) : width;
int maxalt = height == 0 ? (r.bottom / CHARY - 6) : height;
if (_toplevel && larg > maxlarg)
maxlarg = larg;
if (_toplevel && alt > maxalt)
maxalt = alt;
int i;
for (i = 0; i < 4; i++)
_modules.add(new TImage(BMP_MODULE1 + i), i);
_modules.add(new TImage(BMP_MODULE), i);
for (i = 0; i < _modules.items(); i++)
((TImage*)_modules.objptr(i))->convert_transparent_color(MASK_BACK_COLOR);
if (_toplevel)
{
const long flags = WSF_HSCROLL | WSF_VSCROLL | WSF_SIZE;
WIN_TYPE rt = W_DOC;
WINDOW myself = create(x, y, maxlarg, maxalt, title, flags, rt, parent,
_toplevel ? VISWIN_BAR : 0);
attach_interface(myself, BACKGROUND);
}
else
{
// La finestra e' gia' creata automaticamente dal TWindowed_field
}
set_opaque_text (TRUE);
set_font (PRINT_FONT, XVT_FS_NONE, PRINT_HEIGHT);
if (_toplevel)
{
if (width == 0 && height == 0)
maximize();
enable_menu_item(M_VISWIN_COPY, FALSE);
enable_menu_item(M_VISWIN_CLEAR, FALSE);
enable_menu_item(M_SHOW_RULERS, TRUE);
enable_menu_item(M_SHOW_BUTTONS, TRUE);
check_menu_item(M_SHOW_RULERS, _rulers != 0);
check_menu_item(M_SHOW_BUTTONS, _showbuts);
enable_menu_item(M_VISWIN_PRINT, FALSE);
}
if (_txt.lines() > 0l)
set_scroll_max (MAXLEN - 1, _txt.lines () <= _textrows ?
_txt.lines () : _txt.lines () - _textrows);
if (_toplevel)
{
add_button (DLG_QUIT, "", BMP_QUIT, BMP_QUITDN);
if (_isedit)
{
add_button(DLG_SAVEREC, BR("~Registra", 8), BMP_SAVEREC, BMP_SAVERECDN);
disable_button(DLG_SAVEREC);
}
if (_islink)
{
add_button(DLG_LINK, "", BMP_LINK);
disable_button(DLG_LINK);
}
if (_isprint)
{
add_button (DLG_PRINT, "", BMP_PRINT);
disable_button(DLG_PRINT);
enable_menu_item(M_VISWIN_PRINT, FALSE);
}
}
if (_isopen && _showbuts)
_wtimer = xvt_timer_create(win(), 750L);
_point.set (0, 0);
autoscroll (FALSE);
_textrows = TEXTROWS;
_textcolumns = TEXTCOLUMNS;
autoscroll (TRUE);
_links = _toplevel ? &(printer().links()) : &(_brwfld->_links);
_multiple = _toplevel ? (printer ().ismultiplelink()) :
(_brwfld->is_multiple_link());
_bg = _toplevel ? &(printer().getbgdesc()) : &_brwfld->get_bg_desc();
_formlen = _toplevel ? printer().formlen() : height;
_linkID = -1;
_inside_linkexec = FALSE;
for (i = 0; i < _links->items (); i++)
{
TToken_string & t = (TToken_string &) (*_links)[i];
char f = *(t.get(1));
char b = *(t.get(2));
t.restart();
_txt.set_hotspots(f, b);
}
}
TViswin ::~TViswin ()
{
// avoid deleting child window (already deleted by mask)
if (!_toplevel)
set_win(NULL_WIN);
}
///////////////////////////////////////////////////////////
// Campo di visualizzazione sulle maschere
///////////////////////////////////////////////////////////
// Certified 100%
TBrowsefile_field::TBrowsefile_field(TMask* m)
: TWindowed_field(m), _lh(NULL), _m_link(FALSE), _background(36)
{}
// Certified 100%
word TBrowsefile_field::class_id() const
{
return CLASS_BROWSEFILE_FIELD;
}
// Certified 100%
TBrowsefile_field::~TBrowsefile_field()
{
}
// Certified 100%
TField_window* TBrowsefile_field::create_window(int x, int y, int dx, int dy, WINDOW parent)
{
return new TViswin(_ctl_data._prompt, _ctl_data._prompt, FALSE, FALSE, FALSE,
x, y, dy, dx, _flags.rightjust ? TRUE : FALSE, parent, this);
}
long TBrowsefile_field::set_text(const char* file, const char* line)
// se line != NULL ritorna il numero dell'ultima riga del file che
// comincia (trimmata) come passato; se non la trova ritorna -1
{
long ret = -1;
FILE* instr = NULL; fopen_s(&instr, file, "r"); // Secured FILE* instr = fopen(file, "r");
if (instr != NULL)
{
TWait_cursor hourglass;
TString256 tmpp;
long lines = 0l;
while (!feof(instr))
{
if (fgets(tmpp.get_buffer(), tmpp.size(), instr) == NULL)
break;
char& last = tmpp[tmpp.len()-1];
if (last == '\n')
last = '\0';
add_line(tmpp);
if (line != NULL)
{
if (tmpp.find(line) != -1)
ret = lines;
}
lines++;
}
fclose(instr);
}
vis_win().close_print();
return ret;
}
int TBrowsefile_field::find_link(const char* descr)
{
for (int i = 0; i < _links.items(); i++)
{
TToken_string& tt = (TToken_string&)_links[i];
const TFixed_string d(tt.get(0));
if (d == descr)
return i;
}
return -1;
}
int TBrowsefile_field::enable_link(const char *descr, char fg, char bg)
{
int lnk = find_link(descr);
if (lnk < 0)
{
TToken_string *tt = new TToken_string(30);
char b[2] = { '\0', '\0' };
tt->add(descr);
b[0] = fg;
tt->add(b);
b[0] = bg;
tt->add(b);
lnk = _links.add(tt);
vis_win()._txt.set_hotspots(fg, bg);
}
return lnk;
}
void TBrowsefile_field::disable_link(char fg, char bg)
{
for (int i = 0; i < _links.items (); i++)
{
TToken_string & t = (TToken_string&)_links[i];
const char f = *(t.get(1));
const char b = *(t.get());
if (f == fg && b == bg)
{
_links.remove(i, TRUE);
break;
}
}
}
void TBrowsefile_field::set_background(const char* bg)
{
printer().parse_background(bg, _background);
}
void TBrowsefile_field::add_line(const char* l)
{
vis_win().add_line(l);
}
void TBrowsefile_field::close()
{
vis_win().close_print();
}
void TBrowsefile_field::goto_pos(long r, long c)
{
vis_win().goto_pos(r,c,TRUE);
}
void TBrowsefile_field::goto_top()
{
vis_win().goto_top();
}
void TBrowsefile_field::goto_end()
{
vis_win().goto_end();
}
void TBrowsefile_field::refresh()
{
vis_win().refresh();
}
const char* TBrowsefile_field::get_text(long line, int column, int len)
{
return vis_win()._txt.line(line,(long)column, len);
}
long TBrowsefile_field::lines()
{
return vis_win()._txt.lines();
}