089ac07b38
viswin.cpp Corretto scrolling linee verticali git-svn-id: svn://10.65.10.50/trunk@2309 c028cbd2-c16b-5b4b-a496-9718f37d4682
2697 lines
66 KiB
C++
Executable File
2697 lines
66 KiB
C++
Executable File
#include <xvt.h>
|
|
|
|
#include <browfile.h>
|
|
#include <colors.h>
|
|
#include <config.h>
|
|
#include <defmask.h>
|
|
#include <execp.h>
|
|
#include <mailbox.h>
|
|
#include <printapp.h>
|
|
#include <urldefid.h>
|
|
#include <utility.h>
|
|
#include <viswin.h>
|
|
|
|
#include <bagn005.h>
|
|
|
|
// @doc EXTERNAL
|
|
|
|
const char* const PRINT_FONT = XVT_FFN_FIXED;
|
|
const int PRINT_HEIGHT = 10;
|
|
|
|
#define BUTTONROW_SIZE (_showbuts ? 3 : 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 DLG_QUIT_TITLE "Fine"
|
|
#define DLG_EDIT_TITLE "~Edit"
|
|
#define DLG_LINK_TITLE "~Collega"
|
|
#define DLG_PRINT_TITLE "~Stampa"
|
|
|
|
#if XVT_OS == XVT_OS_WIN
|
|
#include <windows.h>
|
|
#define BACKGROUND (_toplevel ? MASK_BACK_COLOR : COLOR_GRAY)
|
|
#define FOREGROUND (_toplevel ? COLOR_BLACK : COLOR_WHITE)
|
|
#else
|
|
#define BACKGROUND COLOR_BLACK
|
|
#define FOREGROUND COLOR_WHITE
|
|
#endif
|
|
|
|
#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_E (K_CTRL + 'E')
|
|
#define CTRL_S (K_CTRL + 'S')
|
|
#define CTRL_R (K_CTRL + 'R')
|
|
|
|
// vista la mania degli 883, eccoti un po' di concerti di Mozart
|
|
const long E_ADDLINE_ONSCREEN = 467L;
|
|
const long E_ADDLINE = 488L;
|
|
HIDDEN bool in_update;
|
|
|
|
|
|
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
|
|
{
|
|
HIDDEN long w = 0L;
|
|
if (w == 0L)
|
|
{
|
|
TString256 t; t.spaces(256);
|
|
w = xvt_dwin_get_text_width(win(), (char*)(const char*)t, 256);
|
|
}
|
|
return int((w*x) >> 8);
|
|
}
|
|
|
|
int TViswin::taby(int y) const
|
|
{
|
|
return y * CHARY;
|
|
}
|
|
|
|
|
|
void TViswin::check_menu_item(MENU_TAG item, bool on)
|
|
{
|
|
xvt_menu_set_item_checked(win(), item, on);
|
|
xvt_menu_update(win());
|
|
}
|
|
|
|
void TViswin::enable_menu_item(MENU_TAG item, bool on)
|
|
{
|
|
xvt_menu_set_item_enabled(win(), item, on);
|
|
xvt_menu_update(win());
|
|
}
|
|
|
|
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;
|
|
|
|
for (int 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);
|
|
|
|
// build tree
|
|
for (int 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
|
|
{
|
|
LINKHANDLER pl = printer().getlinkhandler();
|
|
if (pl)
|
|
pl(_linkID, _multiple ? (const char*)_multiple_link :
|
|
(const char*)_linktxt);
|
|
// dai opzione per rifare la stampa se e' arrivato un messaggio
|
|
// dall'applicazione chiamata
|
|
// schiaffa indi il tutto in una funzione
|
|
TMailbox m;
|
|
if (m.next_s(MSG_LN) != NULL)
|
|
{
|
|
if (yesno_box("Si desidera riaggiornare la stampa?"))
|
|
{
|
|
((TPrint_application&)main_app()).repeat_print();
|
|
#if XVT_OS == XVT_OS_WIN
|
|
xvt_statbar_refresh ();
|
|
#endif
|
|
stop_run(K_ENTER);
|
|
}
|
|
}
|
|
} // _toplevel
|
|
if (_toplevel)
|
|
{
|
|
set_focus();
|
|
_inside_linkexec = TRUE;
|
|
check_link();
|
|
_need_update = TRUE;
|
|
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;
|
|
#if XVT_OS == XVT_OS_WIN
|
|
TString80 dd; dd.strncpy(d, 40);
|
|
xvt_statbar_set(dd);
|
|
#endif
|
|
if (_link_button != -1)
|
|
{
|
|
if (_showbuts) xvt_enable_control (_link_button, TRUE);
|
|
if (_toplevel) enable_menu_item(M_EDIT_CUT, 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);
|
|
}
|
|
}
|
|
}
|
|
|
|
// @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) return;
|
|
#if XVT_OS == XVT_OS_WIN
|
|
if (!in_update)
|
|
{
|
|
xvt_statbar_set ("");
|
|
xvt_statbar_refresh ();
|
|
}
|
|
#endif
|
|
if (_link_button != -1)
|
|
{
|
|
if (_showbuts) xvt_enable_control (_link_button, FALSE);
|
|
if (_toplevel) enable_menu_item(M_EDIT_CUT, FALSE);
|
|
}
|
|
}
|
|
}
|
|
|
|
// @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));
|
|
}
|
|
|
|
// @mfunc Modifica le dimensione di un box
|
|
//
|
|
// @rdesc Ritorna se sono state modificate le dimensioni del box:
|
|
//
|
|
// @flag TRUE | Sono state riassegante 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;
|
|
}
|
|
|
|
// @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 char descr[128], pdescr[128];
|
|
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;
|
|
|
|
for (int i = 0; i < _hotspots->items (); i++)
|
|
{
|
|
TToken_string & t = (TToken_string &) (*_hotspots)[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 ();
|
|
strcpy (descr, ttt.get ());
|
|
strcat (descr, t.get (3));
|
|
_linktxt = t.get(3);
|
|
if (_multiple)
|
|
{
|
|
// get all parts of the same color
|
|
const char *cp;
|
|
_txt.read_line (ty);
|
|
_multiple_link = "";
|
|
|
|
while (cp = _txt.piece ())
|
|
{
|
|
if (_txt.get_foreground () == *(ttt.get (1)) &&
|
|
_txt.get_background () == *(ttt.get (2)))
|
|
_multiple_link.add (cp);
|
|
}
|
|
}
|
|
old_id = _linkID = id;
|
|
y = ty;
|
|
x1 = tx1;
|
|
x2 = tx2;
|
|
display_link (y, x1, x2, descr);
|
|
}
|
|
if (p == &_point)
|
|
{
|
|
strcpy (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;
|
|
strcpy (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;
|
|
}
|
|
|
|
|
|
// @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;
|
|
}
|
|
|
|
void TViswin::display_selection ()
|
|
{
|
|
if (!_sel_displayed)
|
|
paint_selection ();
|
|
_sel_displayed = TRUE;
|
|
}
|
|
|
|
// @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)+2,
|
|
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;
|
|
}
|
|
|
|
// @mfunc Aggiunge un bottone alla finestra
|
|
//
|
|
// @rdesc Ritorna l'handle del bottone aggiunto
|
|
WINDOW TViswin::add_button (
|
|
short id, // @parm Identificatore del bottone da aggiungere
|
|
const char *caption) // @parm Testo del bottone da aggiungere
|
|
|
|
// @comm Questa funzione aggiunge bottoni nella finestra oltre a quelli standard delle finestre
|
|
// di visualizazioni anteprima di stampa. Il limite dei bottoni da aggiungere e' dato
|
|
// dal <p MAXBUT>.
|
|
{
|
|
const int BUT_HEIGHT =
|
|
#if XVT_OS == XVT_OS_WIN
|
|
2
|
|
#else
|
|
1
|
|
#endif
|
|
;
|
|
WINDOW b = xvt_create_control (WC_PUSHBUTTON, 0, 0, 11,
|
|
BUT_HEIGHT, caption, win (), 0, 0, id);
|
|
|
|
for (int i = 0; i < MAXBUT; i++)
|
|
if (_button[i] == NULL_WIN)
|
|
{
|
|
_button[i] = b;
|
|
break;
|
|
}
|
|
return b;
|
|
}
|
|
|
|
void TViswin::repos_buttons ()
|
|
{
|
|
if (!_toplevel) return;
|
|
for (int buttons = 0; _button[buttons] != NULL_WIN; buttons++)
|
|
if (buttons == MAXBUT - 1)
|
|
{
|
|
buttons++;
|
|
break;
|
|
}
|
|
|
|
if (buttons == 0)
|
|
return;
|
|
|
|
autoscroll (FALSE);
|
|
set_mode (M_COPY);
|
|
set_brush (BACKGROUND);
|
|
bar (5, rows () - BUTTONROW_SIZE, columns () + 1, rows () + 1);
|
|
autoscroll (TRUE);
|
|
|
|
RCT wr;
|
|
xvt_vobj_get_client_rect (win (), &wr);
|
|
RCT br;
|
|
xvt_vobj_get_client_rect (_button[0], &br);
|
|
|
|
int space = (wr.right - buttons * br.right) / (buttons + 1);
|
|
if (space < 0)
|
|
space = 0;
|
|
|
|
int x = space;
|
|
const int y = wr.bottom - br.bottom - 4;
|
|
for (int b = 0; b < buttons; b++, x += br.right + space)
|
|
{
|
|
RCT r;
|
|
xvt_rect_set (&r, x, y, x + br.right, y + br.bottom);
|
|
xvt_vobj_move (_button[b], &r);
|
|
}
|
|
|
|
for (int i = 0; i < _modules.items(); i++)
|
|
((TImage&)_modules[i]).set_pos(4, 4+int(rows()-BUTTONROW_SIZE)*CHARY);
|
|
}
|
|
|
|
void TViswin::open ()
|
|
{
|
|
set_scroll_max (MAXLEN, _txt.lines () <= _textrows ? _txt.lines () : _txt.lines () - _textrows);
|
|
repos_buttons();
|
|
TScroll_window::open();
|
|
show_buttons(_showbuts);
|
|
_need_update = TRUE;
|
|
force_update ();
|
|
}
|
|
|
|
// prints the window contents
|
|
void TViswin::paint_screen ()
|
|
{
|
|
bool first = TRUE;
|
|
for (long j = 0; j < _textrows; j++)
|
|
{
|
|
const long rw = origin ().y + j;
|
|
if (rw < _txt.lines ())
|
|
paint_row (rw);
|
|
else if (!_isopen)
|
|
{
|
|
#if XVT_OS == XVT_OS_WIN
|
|
autoscroll (FALSE);
|
|
set_mode (M_COPY);
|
|
set_pen (COLOR_BLACK);
|
|
|
|
PNT b, e;
|
|
b.h = tabx(5);
|
|
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 (5, (int)(j+(long)Y_OFFSET-origin().y),(int)columns(),
|
|
(int)(rows()-(long)BUTTONROW_SIZE));
|
|
autoscroll (TRUE);
|
|
break;
|
|
#endif
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// j = riga totale, row = riga a video
|
|
// @mfunc Permette di stampare i colori di bakcground
|
|
void TViswin::paint_background (
|
|
long j, // @parm Numero della riga di cui stamparne il bakcground
|
|
int row) // @parm Numero della riga a video sulla quale vine stampato il backgropund
|
|
{
|
|
if (_bg->items() == 0)
|
|
return;
|
|
|
|
const int rw = (int) (j % (long) _formlen);
|
|
const TString& rwd = (TString &)(*_bg)[rw];
|
|
|
|
const int ox = (int)origin().x;
|
|
const int mx = ox + columns();
|
|
|
|
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;
|
|
while ((ch = rwd[cnt++]) != '\0')
|
|
{
|
|
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;
|
|
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++];
|
|
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(2*x1+1) / 2;
|
|
e.h = tabx(2*x2+1) / 2;
|
|
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)
|
|
{
|
|
const int width = tabx(x2);
|
|
TImage* i = (TImage*)_images.objptr(id);
|
|
if (i == NULL && y1 == 0)
|
|
{
|
|
const TString_array& a = printer().image_names();
|
|
const TImage src(a.row(id));
|
|
if (src.ok())
|
|
{
|
|
i = new TImage(src, width, y2*CHARY);
|
|
_images.add(i, id);
|
|
}
|
|
}
|
|
|
|
if (i && i->ok())
|
|
{
|
|
short delta = tabx(short(origin().x-x1)); // Primo pixel sorgente
|
|
if (delta < 0) delta = 0;
|
|
if (delta < width)
|
|
{
|
|
const int scroll = (row == 1) ? 2 : 0;
|
|
PNT p; p.h = delta; p.v = taby(y1);
|
|
RCT src; xvt_rect_set(&src, p.h, p.v, width, min(p.v+taby(1)+scroll , i->height()));
|
|
if (src.top < i->height())
|
|
{
|
|
p.h = tabx(x1+X_OFFSET); p.v = taby(row);
|
|
RCT dst = src; xvt_rect_set_pos(&dst, p);
|
|
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::paint_row (long j)
|
|
{
|
|
TPoint p1, p2;
|
|
if (need_paint_sel (FALSE))
|
|
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) + 2;
|
|
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)
|
|
{
|
|
#if XVT_OS != XVT_OS_SCOUNIX
|
|
const int st = _txt.get_style();
|
|
const COLOR bg = trans_color (_txt.get_background());
|
|
const COLOR fg = trans_color (_txt.get_foreground());
|
|
set_font(PRINT_FONT, st, PRINT_HEIGHT);
|
|
set_color(fg, bg);
|
|
#else
|
|
set_color (COLOR_BLACK, COLOR_WHITE);
|
|
#endif
|
|
printat (X_OFFSET+pos, row, "%s", cp);
|
|
|
|
pos += strlen (cp);
|
|
}
|
|
if (_scrolling && (pos < _textcolumns))
|
|
{
|
|
set_color (COLOR_BLACK, COLOR_WHITE);
|
|
TString80 fill; fill.spaces(80);
|
|
printat (X_OFFSET+pos, row, fill);
|
|
}
|
|
|
|
#if XVT_OS == XVT_OS_WIN // paint page limits
|
|
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(132);
|
|
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);
|
|
}
|
|
#endif
|
|
autoscroll (TRUE);
|
|
}
|
|
|
|
// @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));
|
|
|
|
for (long l = 0L; l < _textrows && l < (_txt.lines () - origin ().y); l++)
|
|
{
|
|
paint_background (l, (int) l + 1);
|
|
|
|
const char *c = (const char *) _txt.line (origin ().y + l);
|
|
#if XVT_OS != XVT_OS_SCOUNIX
|
|
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);
|
|
#endif
|
|
printat (col, (int) l + Y_OFFSET, "%c",
|
|
(unsigned int) j < strlen (c) ? c[(int) j] : ' ');
|
|
}
|
|
|
|
xvt_dwin_set_clip(win(), NULL);
|
|
|
|
autoscroll (TRUE);
|
|
}
|
|
|
|
void TViswin::draw_crossbars ()
|
|
// prints reference crossbars
|
|
{
|
|
#if XVT_OS == XVT_OS_WIN
|
|
|
|
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);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
// @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);
|
|
static bool wasbar;
|
|
|
|
if (_isbar)
|
|
{
|
|
invert_bar (X_OFFSET, (int)(_point.y - origin().y + (long)Y_OFFSET),
|
|
(int)columns(), (int) (_point.y - origin().y + (long)Y_OFFSET + 1l));
|
|
invert_bar ((int)(_point.x - origin().x + (long)X_OFFSET), Y_OFFSET,
|
|
(int)(_point.x - origin().x + (long)X_OFFSET + 1l),
|
|
(int)(rows() - (long)BUTTONROW_SIZE));
|
|
}
|
|
else
|
|
{
|
|
invert_bar ((int) (_point.x - origin ().x + (long)X_OFFSET),
|
|
(int) (_point.y - origin ().y + (long)Y_OFFSET),
|
|
(int) (_point.x - origin ().x + (long)X_OFFSET + 1l),
|
|
(int) (_point.y - origin ().y + (long)Y_OFFSET + 1l));
|
|
if (_rulers)
|
|
{
|
|
invert_bar (0, (int) (_point.y - origin ().y + (long)Y_OFFSET), (X_OFFSET -1),
|
|
(int) (_point.y - origin ().y + (long)Y_OFFSET + 1l));
|
|
invert_bar ((int) (_point.x - origin ().x + (long)X_OFFSET), 0,
|
|
(int) (_point.x - origin ().x + (long)X_OFFSET + 1l), 1);
|
|
}
|
|
}
|
|
autoscroll (TRUE);
|
|
wasbar = _isbar;
|
|
}
|
|
|
|
// 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)), BASEY,
|
|
(char*)(const char*)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);
|
|
}
|
|
}
|
|
}
|
|
|
|
// @mfunc Disegna la barra di attesa
|
|
void TViswin::paint_waitbar (
|
|
bool xor) // @parm Utilizzato in UNIX. (default TRUE)
|
|
{
|
|
#if XVT_OS == XVT_OS_WIN
|
|
HIDDEN int pic = 0;
|
|
((TImage&)_modules[pic]).draw(win());
|
|
pic = (pic+1) & 0x3;
|
|
#else
|
|
autoscroll (FALSE);
|
|
if (xor)
|
|
invert_bar (3, rows() - 2, 4, rows() - 1);
|
|
else
|
|
printat (3, rows() - 2, "%c", '*');
|
|
autoscroll (TRUE);
|
|
#endif
|
|
}
|
|
|
|
void TViswin::update ()
|
|
{
|
|
if (_scrolling)
|
|
return;
|
|
|
|
in_update = TRUE;
|
|
|
|
erase_point();
|
|
autoscroll(FALSE);
|
|
set_mode(M_COPY);
|
|
if (_showbuts)
|
|
{
|
|
set_brush (BACKGROUND);
|
|
bar ((X_OFFSET-1), rows()-BUTTONROW_SIZE, columns()+1, rows() + 1);
|
|
}
|
|
if (_need_update)
|
|
{
|
|
check_link();
|
|
if (_isselection)
|
|
erase_selection ();
|
|
clear (COLOR_WHITE);
|
|
set_mode (M_COPY);
|
|
set_brush (BACKGROUND);
|
|
autoscroll (FALSE);
|
|
|
|
if (_rulers)
|
|
{
|
|
bar (0, 0, columns() + 1, 1);
|
|
bar (0, 0, 5, rows() + 1);
|
|
// RCT r1, r2;
|
|
// r1.top = 0; r1.left = 0; r1.bottom = CHARY; r1.right = (columns() + 1)*CHARX;
|
|
// r2.top = 0; r2.left = 0; r2.bottom = (rows()+1)*CHARY; r2.right = 5*CHARX;
|
|
// xvt_draw_rect(win(), r1, COLOR_WHITE, COLOR_GRAY, 2);
|
|
// xvt_draw_rect(win(), r2, COLOR_WHITE, COLOR_GRAY, 2);
|
|
}
|
|
if (_showbuts)
|
|
bar ((X_OFFSET -1), rows()-BUTTONROW_SIZE, columns() + 1, rows() + 1);
|
|
if (_showbuts && _isopen)
|
|
paint_waitbar (FALSE);
|
|
#if XVT_OS == XVT_OS_WIN
|
|
else
|
|
if (_showbuts) ((TImage&)_modules[4]).draw(win());
|
|
#endif
|
|
autoscroll (TRUE);
|
|
paint_header ();
|
|
paint_screen ();
|
|
if (_isselection)
|
|
display_selection ();
|
|
}
|
|
display_point ();
|
|
check_link(&_point);
|
|
autoscroll (TRUE);
|
|
_need_update = TRUE;
|
|
_need_scroll = none;
|
|
in_update = FALSE;
|
|
}
|
|
|
|
void TViswin::abort_print ()
|
|
{
|
|
if (yesno_box ("Interruzione della stampa su video?"))
|
|
{
|
|
_txt.freeze ();
|
|
freeze ();
|
|
set_focus ();
|
|
close_print();
|
|
}
|
|
}
|
|
|
|
void TViswin::scroll_error(long x, long y)
|
|
{
|
|
beep();
|
|
update_thumb(x, y);
|
|
|
|
#if XVT_OS == XVT_OS_WIN
|
|
POINT p; GetCursorPos(&p);
|
|
if (x < 0) p.x -= 16;
|
|
if (y < 0) p.y -= 16;
|
|
SetCursorPos(p.x, p.y);
|
|
#endif
|
|
}
|
|
|
|
void TViswin::handler (WINDOW win, EVENT * ep)
|
|
{
|
|
int kdiff_x, kdiff_y;
|
|
PNT newcross;
|
|
TPoint p;
|
|
static bool ignore = FALSE;
|
|
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 ();
|
|
if (_txt.lines () > 1l)
|
|
_need_update = FALSE;
|
|
else
|
|
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_EDIT_CLIPBOARD: // interrompi
|
|
dispatch_e_char(win, K_ESC);
|
|
break;
|
|
case M_EDIT_CUT: // collega
|
|
dispatch_e_char(win, CTRL_C);
|
|
break;
|
|
case M_EDIT_PASTE: // esporta
|
|
dispatch_e_char(win, CTRL_E);
|
|
break;
|
|
case M_EDIT_SEL_ALL: // stampa
|
|
#if XVT_OS == XVT_OS_WIN
|
|
xvt_statbar_set ("");
|
|
xvt_statbar_refresh ();
|
|
stop_run(CTRL_S);
|
|
#endif
|
|
break;
|
|
case M_SHOW_RULERS: // mostra righelli
|
|
show_rulers(!_rulers);
|
|
check_menu_item(M_SHOW_RULERS, _rulers);
|
|
break;
|
|
case M_SHOW_BUTTONS: // mostra bottoni
|
|
show_buttons(!_showbuts);
|
|
check_menu_item(M_SHOW_BUTTONS, _showbuts);
|
|
break;
|
|
case M_EDIT_QUIT: // chiudi
|
|
#if XVT_OS == XVT_OS_WIN
|
|
xvt_statbar_set ("");
|
|
xvt_statbar_refresh ();
|
|
#endif
|
|
stop_run (K_ENTER);
|
|
break;
|
|
case M_EDIT_COPY: // copia
|
|
// ???
|
|
break;
|
|
case M_EDIT_CLEAR: // annulla selezione
|
|
dispatch_e_char(win,K_ENTER);
|
|
break;
|
|
case M_EDIT_SEARCH: // cerca
|
|
find();
|
|
break;
|
|
case M_EDIT_DELETE: // cerca il prossimo
|
|
find_next();
|
|
break;
|
|
case M_EDIT_UNDO: // ridisegna
|
|
refresh();
|
|
break;
|
|
}
|
|
break;
|
|
case E_CONTROL:
|
|
if (ep->v.ctl.ci.type == WC_PUSHBUTTON)
|
|
switch (ep->v.ctl.id)
|
|
{
|
|
case DLG_QUIT:
|
|
if (_isopen)
|
|
abort_print ();
|
|
else
|
|
{
|
|
#if XVT_OS == XVT_OS_WIN
|
|
xvt_statbar_set ("");
|
|
xvt_statbar_refresh ();
|
|
#endif
|
|
stop_run (K_ENTER);
|
|
}
|
|
break;
|
|
case DLG_PRINT:
|
|
dispatch_e_menu(win, M_EDIT_SEL_ALL);
|
|
break;
|
|
case DLG_EDIT:
|
|
check_link ();
|
|
call_editor ();
|
|
_need_update = TRUE;
|
|
update ();
|
|
check_link (&_point);
|
|
break;
|
|
case DLG_LINK:
|
|
exec_link();
|
|
break;
|
|
}
|
|
break;
|
|
case E_TIMER:
|
|
if (ep->v.timer.id == _timer)
|
|
{
|
|
xvt_timer_destroy (_timer);
|
|
_istimer = FALSE;
|
|
}
|
|
else if (ep->v.timer.id == _wtimer)
|
|
{
|
|
if (_showbuts) paint_waitbar ();
|
|
xvt_timer_destroy (_wtimer);
|
|
if (_isopen)
|
|
_wtimer = xvt_timer_create (win, 150l);
|
|
}
|
|
break;
|
|
case E_MOUSE_DBL:
|
|
break;
|
|
case E_MOUSE_DOWN:
|
|
p = ep->v.mouse.where;
|
|
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.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
|
|
|
|
{
|
|
p = ep->v.mouse.where;
|
|
|
|
if (_isopen && (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
|
|
{
|
|
TPoint xx;
|
|
_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 = TRUE;
|
|
check_link (&_point);
|
|
display_point ();
|
|
}
|
|
_selecting = FALSE;
|
|
}
|
|
else
|
|
{
|
|
erase_crossbar ();
|
|
_iscross = FALSE;
|
|
}
|
|
break;
|
|
case E_MOUSE_MOVE:
|
|
{
|
|
/*
|
|
if (!_selecting && !_iscross) // no buttons pressed
|
|
{
|
|
p = ep->v.mouse.where;
|
|
if (in_text (p))
|
|
{
|
|
p.x += (origin ().x - 6);
|
|
p.y += (origin ().y - 1);
|
|
check_link (&p);
|
|
}
|
|
}
|
|
*/
|
|
if (_selecting || _iscross)
|
|
{
|
|
p = ep->v.mouse.where;
|
|
if (_selecting)
|
|
_isselection = TRUE;;
|
|
{
|
|
_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 ();
|
|
_need_update = TRUE;
|
|
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);
|
|
_need_update = TRUE;
|
|
update (); // ORRIIIBILE!
|
|
|
|
check_link (&_point);
|
|
_need_update = FALSE;
|
|
}
|
|
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);
|
|
_need_update = TRUE;
|
|
update (); // AAAARGH!
|
|
|
|
check_link (&_point);
|
|
_need_update = FALSE;
|
|
}
|
|
else scroll_error(0, -1);
|
|
}
|
|
break;
|
|
case SC_LINE_UP:
|
|
if (ep->type == E_VSCROLL)
|
|
{
|
|
_need_update = FALSE;
|
|
if (origin ().y > 0l)
|
|
{
|
|
_point.y--;
|
|
if (need_paint_sel ())
|
|
erase_selection ();
|
|
check_link ();
|
|
update_thumb (origin().x, origin().y - 1l);
|
|
_need_scroll = down;
|
|
}
|
|
else scroll_error(-1, 0);
|
|
}
|
|
else
|
|
{
|
|
_need_update = FALSE;
|
|
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);
|
|
_need_update = TRUE;
|
|
update (); // AAAARGH!
|
|
|
|
check_link (&_point);
|
|
_need_update = FALSE;
|
|
}
|
|
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);
|
|
_need_update = TRUE;
|
|
update (); // AAAARGH!
|
|
|
|
check_link (&_point);
|
|
_need_update = FALSE;
|
|
}
|
|
else scroll_error(255-_textcolumns, -1);
|
|
}
|
|
break;
|
|
case SC_LINE_DOWN:
|
|
if (ep->type == E_VSCROLL)
|
|
{
|
|
_need_update = FALSE;
|
|
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;
|
|
}
|
|
else scroll_error(-1, _txt.lines()-_textrows/*-1*/);
|
|
}
|
|
else
|
|
{
|
|
_need_update = FALSE;
|
|
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;
|
|
_need_update = TRUE;
|
|
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)
|
|
{
|
|
_need_update = FALSE;
|
|
scroll tmp = _need_scroll;
|
|
_need_scroll = none;
|
|
shift_screen (tmp);
|
|
if (!_selecting)
|
|
{
|
|
check_link (&_point);
|
|
display_point ();
|
|
}
|
|
if (_isselection)
|
|
display_selection ();
|
|
}
|
|
if (ep->type != E_UPDATE || _need_update)
|
|
TWindow ::handler (win, ep);
|
|
else if (ep->type == E_UPDATE)
|
|
update ();
|
|
}
|
|
|
|
bool TViswin::on_key (KEY key)
|
|
{
|
|
EVENT_TYPE type = E_USER;
|
|
|
|
if (_istimer)
|
|
return TRUE;
|
|
_timer = xvt_timer_create (win (), 50l);
|
|
_istimer = TRUE;
|
|
|
|
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_F8:
|
|
find_next();
|
|
break;
|
|
case CTRL_E:
|
|
if (_isedit)
|
|
{
|
|
check_link ();
|
|
call_editor ();
|
|
set_focus ();
|
|
_need_update = TRUE;
|
|
update ();
|
|
check_link (&_point);
|
|
}
|
|
break;
|
|
case CTRL_C:
|
|
exec_link();
|
|
break;
|
|
case CTRL_S:
|
|
if (_isprint)
|
|
stop_run(CTRL_S);
|
|
break;
|
|
case CTRL_R:
|
|
_need_update = TRUE;
|
|
check_link ();
|
|
force_update ();
|
|
do_events ();
|
|
check_link (&_point);
|
|
break;
|
|
case K_ESC:
|
|
if (_isopen)
|
|
abort_print ();
|
|
else
|
|
{
|
|
|
|
#if XVT_OS == XVT_OS_WIN
|
|
xvt_statbar_set ("");
|
|
xvt_statbar_refresh ();
|
|
#endif
|
|
stop_run (K_ESC);
|
|
}
|
|
break;
|
|
case K_ENTER:
|
|
if (_isselection)
|
|
{
|
|
erase_selection ();
|
|
_isselection = FALSE;
|
|
}
|
|
if (_toplevel)
|
|
exec_link();
|
|
break;
|
|
case K_TAB:
|
|
if (!is_running())
|
|
{
|
|
_need_update = TRUE;
|
|
update();
|
|
}
|
|
else
|
|
{
|
|
if (_curbut == (_buttons - 1))
|
|
_curbut = 0;
|
|
else
|
|
_curbut++;
|
|
}
|
|
break;
|
|
|
|
case K_BTAB:
|
|
if (_curbut == 0)
|
|
_curbut = _buttons - 1;
|
|
else
|
|
_curbut--;
|
|
break;
|
|
case K_SPACE:
|
|
case K_CTRL_ENTER:
|
|
if (_linkID != -1)
|
|
{
|
|
exec_link();
|
|
}
|
|
else if (_toplevel)
|
|
dispatch_e_char (_button[_curbut], K_SPACE);
|
|
break;
|
|
case K_LHOME:
|
|
_need_update = TRUE;
|
|
update_thumb (0, 0);
|
|
_point.set (0, 0);
|
|
check_link (&_point);
|
|
force_update ();
|
|
break;
|
|
case K_LEND:
|
|
_need_update = TRUE;
|
|
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;
|
|
_need_update = TRUE;
|
|
force_update ();
|
|
do_events ();
|
|
check_link (&_point);
|
|
break;
|
|
case K_F6:
|
|
_selflag = !_selflag;
|
|
break;
|
|
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:
|
|
// TBI condizioniamo qui ??
|
|
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:
|
|
_need_update = FALSE;
|
|
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:
|
|
_need_update = FALSE;
|
|
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)
|
|
{
|
|
_need_update = FALSE;
|
|
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:
|
|
_need_update = FALSE;
|
|
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:
|
|
_need_update = FALSE;
|
|
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)
|
|
{
|
|
_need_update = FALSE;
|
|
scroll tmp = _need_scroll;
|
|
_need_scroll = none;
|
|
shift_screen (tmp);
|
|
}
|
|
if (_isselection)
|
|
display_selection ();
|
|
check_link (&_point);
|
|
force_update ();
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return TWindow::on_key (key);
|
|
}
|
|
|
|
bool TViswin::call_editor ()
|
|
{
|
|
TConfig cnf (CONFIG_USER, "Link");
|
|
const TFilename editor (cnf.get ("txt", NULL, -1, "notepad"));
|
|
|
|
bool ok = FALSE;
|
|
|
|
if (!editor.empty ())
|
|
{
|
|
TFilename newfilename; newfilename.tempdir();
|
|
FILE_SPEC fs;
|
|
xvt_fsys_convert_str_to_dir((char*)(const char*)newfilename, &fs.dir);
|
|
strcpy (fs.type, "txt");
|
|
strcpy (fs.name, "");
|
|
|
|
xvt_fsys_save_dir ();
|
|
ok = xvt_dm_post_file_save (&fs, "Salva il file con il nome:") == FL_OK;
|
|
xvt_fsys_restore_dir ();
|
|
|
|
if (ok)
|
|
{
|
|
char path[256];
|
|
xvt_fsys_convert_dir_to_str (&fs.dir, path, sizeof (path));
|
|
newfilename = path;
|
|
newfilename << '/' << fs.name;
|
|
|
|
TPoint p1, p2;
|
|
if (_isselection)
|
|
adjust_selection (p1, p2);
|
|
|
|
if (_txt.write (newfilename, _isselection ? &p1 : NULL,
|
|
_isselection ? &p2 : NULL))
|
|
{
|
|
newfilename.insert (" ", 0);
|
|
newfilename.insert (editor, 0);
|
|
TExternal_app edit (newfilename);
|
|
if (edit.run(TRUE, FALSE))
|
|
beep ();
|
|
else
|
|
ok = TRUE;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
warning_box ("Nessun editor specificato nei parametri studio");
|
|
return ok;
|
|
}
|
|
|
|
void TViswin::add_line (const char *l)
|
|
{
|
|
if (_isopen && !_frozen)
|
|
{
|
|
if (_txt.frozen ()) // error writing files
|
|
{
|
|
close_print ();
|
|
return;
|
|
}
|
|
_txt.append (l);
|
|
EVENT ev;
|
|
ev.type = E_USER;
|
|
ev.v.user.id = (_txt.lines() - origin().y) <= _textrows ?
|
|
E_ADDLINE_ONSCREEN : E_ADDLINE;
|
|
xvt_win_dispatch_event (win (), &ev);
|
|
do_events ();
|
|
}
|
|
}
|
|
|
|
void TViswin::close_print ()
|
|
{
|
|
_isopen = FALSE;
|
|
if (_showbuts) xvt_timer_destroy (_wtimer);
|
|
_need_update = TRUE;
|
|
if (_toplevel)
|
|
{
|
|
xvt_menu_set_item_title(win(), M_EDIT_QUIT, "Chiudi\tESC");
|
|
enable_menu_item(M_EDIT_CLIPBOARD, FALSE);
|
|
xvt_enable_control(_print_button, TRUE);
|
|
enable_menu_item(M_EDIT_SEL_ALL, TRUE);
|
|
// build bookmark menu tree
|
|
_bookmarks = &(printer().get_bookmarks());
|
|
if (_bookmarks->items() > 0)
|
|
build_index_menu();
|
|
}
|
|
|
|
const TImage* i = (TImage*)_images.objptr(0);
|
|
if (i != NULL) i->set_palette(win());
|
|
|
|
force_update ();
|
|
}
|
|
|
|
void TViswin::goto_end()
|
|
{
|
|
goto_pos(0l, _txt.lines () - _textrows);
|
|
}
|
|
|
|
void TViswin::goto_top()
|
|
{
|
|
goto_pos(0l,0l);;
|
|
}
|
|
|
|
// @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;
|
|
update_thumb(c,r);
|
|
check_link(&_point);
|
|
if (_isselection) display_selection();
|
|
display_point();
|
|
refresh();
|
|
}
|
|
|
|
void TViswin::refresh()
|
|
{
|
|
_need_update = TRUE;
|
|
force_update();
|
|
}
|
|
|
|
// @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)
|
|
{
|
|
return _txt.search(txt,pos,from,down, cs);
|
|
}
|
|
|
|
// @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" : "");
|
|
|
|
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);
|
|
int x;
|
|
|
|
long l = search(_txt_to_find, x, _point.y, _down_dir, _case_sensitive);
|
|
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_EDIT_DELETE, 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);
|
|
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();
|
|
}
|
|
|
|
// @mfunc Indica se mostrare o no 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 < _buttons; i++)
|
|
if (_button[i] != NULL_WIN)
|
|
xvt_vobj_set_visible(_button[i],on);
|
|
refresh();
|
|
}
|
|
|
|
TViswin::TViswin(const char *fname,
|
|
const char *title,
|
|
bool editbutton,
|
|
bool printbutton,
|
|
bool linkbutton,
|
|
int x, int y,
|
|
int height, int width,
|
|
bool rulers, // overridden by config parms
|
|
WINDOW parent,
|
|
TBrowsefile_field* brwfld):
|
|
_filename (fname), _txt (fname, BUFFERSIZE), _islink (linkbutton), _isedit (editbutton),
|
|
_isprint (printbutton), _isbar (FALSE), _istimer (FALSE), _iscross (FALSE),
|
|
_isselection (FALSE), _sel_displayed (FALSE), _cross_displayed (FALSE),
|
|
_link_displayed (FALSE), _point_displayed (FALSE), _selecting (FALSE),
|
|
_scrolling (FALSE), _selflag (FALSE), _need_update (TRUE), _need_scroll (none),
|
|
_multiple (FALSE), _rulers(rulers), _txt_to_find(64),
|
|
_frozen (FALSE), _brwfld(brwfld), _link_button(-1),
|
|
_down_dir(TRUE), _showbuts(FALSE), _case_sensitive(FALSE),
|
|
_menu_present(FALSE)
|
|
{
|
|
main_app().begin_wait();
|
|
|
|
if (title == NULL)
|
|
title = (fname ? fname : "Anteprima di stampa");
|
|
|
|
_last_found.y = -1;
|
|
|
|
_isopen = fname == NULL || *fname <= ' ';
|
|
if (_isopen)
|
|
_filename = _txt.name ();
|
|
|
|
for (int i = 0; i < MAXBUT; i++)
|
|
_button[i] = NULL_WIN;
|
|
|
|
if (parent == NULL_WIN)
|
|
parent = TASK_WIN;
|
|
|
|
_toplevel = 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);
|
|
_rulers = cnf.get_bool("Righelli", NULL, -1,TRUE);
|
|
}
|
|
|
|
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;
|
|
|
|
#if XVT_OS == XVT_OS_WIN
|
|
for (i = 0; i < 4; i++)
|
|
_modules.add(new TImage(BMP_MODULE1 + i), i);
|
|
_modules.add(new TImage(BMP_MODULE), i);
|
|
#endif
|
|
|
|
long flags = WSF_HSCROLL | WSF_VSCROLL;
|
|
if (_toplevel)
|
|
{
|
|
flags |= (WSF_CLOSE | WSF_SIZE);
|
|
}
|
|
|
|
WIN_TYPE rt = _toplevel ? W_DOC : W_PLAIN;
|
|
create (x, y, maxlarg, maxalt, title, flags, rt, parent,
|
|
_toplevel ? VISWIN_BAR : 0);
|
|
set_opaque_text (TRUE);
|
|
set_font (PRINT_FONT, XVT_FS_NONE, PRINT_HEIGHT);
|
|
|
|
if (_toplevel)
|
|
{
|
|
enable_menu_item(M_SHOW_RULERS, TRUE);
|
|
enable_menu_item(M_SHOW_BUTTONS, TRUE);
|
|
check_menu_item(M_SHOW_RULERS, _rulers);
|
|
check_menu_item(M_SHOW_BUTTONS, _showbuts);
|
|
enable_menu_item(M_EDIT_SEL_ALL, FALSE);
|
|
}
|
|
|
|
if (_txt.lines() > 0l)
|
|
set_scroll_max (MAXLEN - 1, _txt.lines () <= _textrows ?
|
|
_txt.lines () : _txt.lines () - _textrows);
|
|
|
|
|
|
if (_toplevel)
|
|
{
|
|
add_button (DLG_QUIT, DLG_QUIT_TITLE);
|
|
_buttons = 1;
|
|
|
|
if (_isedit)
|
|
{
|
|
add_button (DLG_EDIT, DLG_EDIT_TITLE);
|
|
_buttons++;
|
|
}
|
|
if (_islink)
|
|
{
|
|
_link_button = add_button (DLG_LINK, DLG_LINK_TITLE);
|
|
_buttons++;
|
|
xvt_enable_control(_link_button, FALSE);
|
|
}
|
|
if (_isprint)
|
|
{
|
|
_print_button = add_button (DLG_PRINT, DLG_PRINT_TITLE);
|
|
xvt_enable_control(_print_button, FALSE);
|
|
enable_menu_item(M_EDIT_SEL_ALL, FALSE);
|
|
_buttons++;
|
|
}
|
|
}
|
|
else _buttons = 0;
|
|
|
|
_curbut = 0;
|
|
|
|
if (_isopen && _showbuts)
|
|
_wtimer = xvt_timer_create(win(), 150l);
|
|
|
|
_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() : maxalt;
|
|
_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);
|
|
}
|
|
|
|
_hotspots = &(_txt.hotspots());
|
|
|
|
main_app().end_wait();
|
|
}
|
|
|
|
TViswin ::~TViswin ()
|
|
{}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// Campo di visualizzazione sulle maschere
|
|
///////////////////////////////////////////////////////////
|
|
|
|
// Certified 100%
|
|
TBrowsefile_field::TBrowsefile_field(TMask* m)
|
|
: TMask_field(m), _viswin(NULL), _m_link(FALSE), _background(36), _lh(NULL)
|
|
{}
|
|
|
|
// Certified 100%
|
|
word TBrowsefile_field::class_id() const
|
|
{
|
|
return CLASS_BROWSEFILE_FIELD;
|
|
}
|
|
|
|
// Certified 100%
|
|
TBrowsefile_field::~TBrowsefile_field()
|
|
{
|
|
CHECK(_viswin, "Can't delete NULL sheet");
|
|
delete _viswin;
|
|
}
|
|
|
|
void TBrowsefile_field::parse_head(TScanner& scanner)
|
|
{
|
|
_width = scanner.integer();
|
|
_size = scanner.integer();
|
|
}
|
|
|
|
// Certified 100%
|
|
void TBrowsefile_field::create(WINDOW parent)
|
|
{
|
|
main_app().begin_wait();
|
|
|
|
const TMask& m = mask();
|
|
_viswin = new TViswin(_prompt, _prompt, FALSE, FALSE, FALSE, _x, _y,
|
|
_size, _width, _flags.rightjust ? TRUE : FALSE, parent, this);
|
|
_win = _viswin->win();
|
|
xvt_vobj_set_enabled(_win, enabled());
|
|
xvt_vobj_set_visible(_win, shown());
|
|
|
|
main_app().end_wait();
|
|
}
|
|
|
|
|
|
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
|
|
{
|
|
FILE* instr = fopen(file,"r");
|
|
if (instr == NULL)
|
|
fatal_box("File non trovato: %s", file);
|
|
|
|
main_app().begin_wait();
|
|
|
|
TString256 tmpp;
|
|
long ret = -1l;
|
|
long lines = 0l;
|
|
|
|
while (!feof(instr))
|
|
{
|
|
if (fgets(__tmp_string, sizeof (__tmp_string), instr) == NULL)
|
|
break;
|
|
if (__tmp_string[strlen(__tmp_string)-1] == '\n')
|
|
__tmp_string[strlen(__tmp_string)-1] = '\0';
|
|
add_line(__tmp_string);
|
|
if (line != NULL)
|
|
{
|
|
tmpp = __tmp_string;
|
|
if (tmpp.find(line) != -1)
|
|
ret = lines;
|
|
}
|
|
lines++;
|
|
}
|
|
fclose(instr);
|
|
|
|
_viswin->close_print();
|
|
|
|
main_app().end_wait();
|
|
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);
|
|
_viswin->_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)
|
|
{
|
|
_viswin->add_line(l);
|
|
}
|
|
|
|
void TBrowsefile_field::close()
|
|
{
|
|
_viswin->close_print();
|
|
}
|
|
|
|
void TBrowsefile_field::goto_pos(long r, long c)
|
|
{
|
|
_viswin->goto_pos(r,c,TRUE);
|
|
}
|
|
|
|
void TBrowsefile_field::goto_top()
|
|
{
|
|
_viswin->goto_top();
|
|
}
|
|
|
|
void TBrowsefile_field::goto_end()
|
|
{
|
|
_viswin->goto_end();
|
|
}
|
|
|
|
void TBrowsefile_field::refresh()
|
|
{
|
|
_viswin->refresh();
|
|
}
|
|
|
|
const char* TBrowsefile_field::get_text(long line, int column, int len)
|
|
{
|
|
return _viswin->_txt.line(line,(long)column, len);
|
|
}
|
|
|
|
long TBrowsefile_field::lines()
|
|
{
|
|
return _viswin->_txt.lines();
|
|
}
|