#include #include #include #include #include #include #include #include #include #include #ifndef __PRINTER_H typedef void (*LINKHANDLER) (int, const char *); #endif #if XVT_OS == XVT_OS_WIN extern "C" { #include } #endif #define BUTTONROW_SIZE 3 #define W_X1 (origin().x+5) #define W_Y1 (origin().y+1) #define W_X2 (origin().x+columns()) #define W_Y2 (origin().y+rows()+1-BUTTONROW_SIZE) #define TEXTROWS (rows() - 1 - BUTTONROW_SIZE) #define TEXTCOLUMNS (columns() - 6) #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 #define BACKGROUND MASK_BACK_COLOR #define FOREGROUND COLOR_BLACK #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 ('C') #define CTRL_E ('E') #define CTRL_S ('S') #define CTRL_R ('R') // vista la mania degli 883, eccoti un po' di concerti di Mozart const long E_ADDLINE = 488L; const long E_ADDLINE_ONSCREEN = 467L; void TViswin::exec_link() { if (_linkID != -1) { LINKHANDLER pl = main_app().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); } } set_focus(); check_link(); _need_update = TRUE; force_update(); do_events(); check_link (&_point); } 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 XVT_OS == XVT_OS_WIN xvt_statbar_set (d); xvt_statbar_refresh (); #endif xvt_enable_control (_link_button, TRUE); } } void TViswin::erase_link (long y, long x1, long x2) { if (_link_displayed) { paint_link (y, x1, x2); _link_displayed = FALSE; #if XVT_OS == XVT_OS_WIN xvt_statbar_set (""); xvt_statbar_refresh (); #endif xvt_enable_control (_link_button, FALSE); } } void TViswin::paint_link (long y, long x1, long x2) { if (adjust_box (x1, x2, y)) invert_bar ((int) (x1 + 6l), (int) (y + 1l), (int) (x2 + 6l), (int) (y + 2l)); } bool TViswin::adjust_box (long &x1, long &x2, long y) { 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; } bool TViswin::check_link (TPoint * p) { 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 > 5 && p.x < columns () && p.y > 0 && p.y < (rows () - 3)) return TRUE; return FALSE; } bool TViswin::need_paint_sel (bool smart) { 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; } void TViswin::adjust_selection (TPoint & p1, TPoint & p2) { 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: set_rect (&r, 0, CHARY + 2, (int) (CHARX * (_textcolumns + 6)), (int) (CHARY * (_textrows + 1))); win_scroll_rect (win (), &r, 0, dir == down ? CHARY : -CHARY); paint_row (dir == up ? origin ().y + _textrows - 1 : origin ().y); break; case left: case right: set_rect (&r, CHARX * 6, 0, (int) (CHARX * (_textcolumns + 6) + 2), (int) (CHARY * (_textrows + 1) - 2)); win_scroll_rect (win (), &r, dir == right ? CHARX : -CHARX, 0); paint_column (dir == left ? origin ().x + _textcolumns - 1 : origin ().x, dir == left); break; default: break; } _scrolling = FALSE; } WINDOW TViswin::add_button (short id, const char *caption) { 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 () { 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 (MASK_BACK_COLOR); bar (5, rows () - 3, columns () + 1, rows () + 1); autoscroll (TRUE); RCT wr; get_client_rect (win (), &wr); RCT br; 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; set_rect (&r, x, y, x + br.right, y + br.bottom); move_window (_button[b], &r); } } void TViswin::open () { set_scroll_max (MAXLEN, _txt.lines () <= _textrows ? _txt.lines () : _txt.lines () - _textrows); repos_buttons (); TScroll_window ::open (); _need_update = TRUE; force_update (); } // prints the window contents void TViswin::paint_screen () { bool first = TRUE; for (long j = 0; j < _textrows; j++) { 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 = CHARX * 5; b.v = (CHARY * (int) (j + 1l - origin ().y)) - 2; e.h = CHARX * columns (); e.v = b.v; win_move_to (win (), b); win_draw_line (win (), e); set_pen (COLOR_LTGRAY); e.v++; b.v++; win_move_to (win (), b); win_draw_line (win (), e); set_brush (COLOR_DKGRAY); bar (5, (int) (j + 1l - origin ().y), (int) columns (), (int) (rows () - 3l)); autoscroll (TRUE); break; #endif } } } void TViswin::paint_background (long j, int row) { if (!_isbackground) return; int rw = (int) (j % (long) _formlen); TString & rwd = (TString &) (*_bg)[rw]; int cnt = 0; char ch; char curcol = 'n'; char curpen = 'n'; char curpat = 'n'; char curwid = '1'; unsigned int x1, x2; PNT b, e; while (ch = rwd[cnt++]) { switch (ch) { case 'v': // verticale intera x1 = (unsigned char) rwd[cnt++] + 5; b.h = e.h = x1 * CHARX + CHARX / 2; b.v = row * CHARY; e.v = (row + 1) * CHARY; win_move_to (win (), b); win_draw_line (win (), e); break; case 'o': // verticale pezzo sopra x1 = (unsigned char) rwd[cnt++] + 5; b.h = e.h = x1 * CHARX + CHARX / 2; b.v = row * CHARY; e.v = (row + 1) * CHARY - CHARY / 2; win_move_to (win (), b); win_draw_line (win (), e); break; case 'u': // verticale pezzo sotto x1 = (unsigned char) rwd[cnt++] + 5; b.h = e.h = x1 * CHARX + CHARX / 2; b.v = row * CHARY + CHARY / 2; e.v = (row + 1) * CHARY; win_move_to (win (), b); win_draw_line (win (), e); break; case 'h': // orizzontale intera x1 = (unsigned char) rwd[cnt++] + 5; x2 = (unsigned char) rwd[cnt++] + 5; b.v = e.v = row * CHARY + CHARY / 2; b.h = x1 * CHARX; e.h = (x2 + 1) * CHARX; win_move_to (win (), b); win_draw_line (win (), e); break; case 'r': // orizzontale scorciata agli estremi x1 = (unsigned char) rwd[cnt++] + 5; x2 = (unsigned char) rwd[cnt++] + 5; b.v = e.v = row * CHARY + CHARY / 2; b.h = x1 * CHARX + CHARX / 2; e.h = x2 * CHARX + CHARX / 2; win_move_to (win (), b); win_draw_line (win (), e); 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) { // int or = (int)origin().x; long y = origin ().y; TPoint p1, p2; if (need_paint_sel (FALSE)) adjust_selection (p1, p2); int row = (int) (j + 1l - y); static char fill[] = " " " "; autoscroll (FALSE); set_font (FF_FIXED, 0); set_mode (M_COPY); set_opaque_text (TRUE); set_color (FOREGROUND, BACKGROUND); printat (0, row, "%05ld", j + 1); if (_scrolling) { hide_pen (); set_brush (COLOR_WHITE); RCT r; r.top = row * CHARY; r.left = CHARX * 5, r.bottom = r.top + CHARY + 2; r.right = CHARX * 255; win_draw_rect (win (), &r); } const char *cp; int pos = 0; _txt.read_line (j, origin ().x); while (cp = _txt.piece ()) { #if XVT_OS != XVT_OS_SCOUNIX int st = _txt.get_style (); long bg = trans_color (_txt.get_background ()); long fg = trans_color (_txt.get_foreground ()); set_font (FF_FIXED, st & 0x000f); set_color (fg, bg); #else set_color (COLOR_BLACK, COLOR_WHITE); #endif printat (6 + pos, row, "%s", cp); #if XVT_OS == XVT_OS_WIN if (st & underlined) { PNT b, e; set_pen (COLOR_BLACK); b.h = CHARX * (6 + pos); b.v = (row + 1) * CHARY; e.h = CHARX * (6 + pos + strlen (cp)); e.v = (row + 1) * CHARY; win_move_to (win (), b); win_draw_line (win (), e); } #endif pos += strlen (cp); } if (_scrolling && (pos < _textcolumns)) { set_color (COLOR_BLACK, COLOR_WHITE); printat (6 + pos, row, "%s", fill); } #if XVT_OS == XVT_OS_WIN // paint page limits if ((j % _formlen) == (_formlen - 1)) // last row { PNT b, e; b.h = CHARX * 5; b.v = (row + 1) * CHARY - 1; e.h = CHARX * 132; e.v = (row + 1) * CHARY - 1; set_pen (COLOR_LTGRAY, 2, PAT_SOLID, P_DASH); win_move_to (win (), b); win_draw_line (win (), e); } #endif paint_background (j, row); autoscroll (TRUE); } void TViswin::paint_column (long j, bool end) { paint_header (); set_opaque_text (TRUE); set_mode (M_COPY); TPoint p1, p2; if (need_paint_sel (FALSE)) adjust_selection (p1, p2); set_color (COLOR_BLACK, COLOR_WHITE); autoscroll (FALSE); for (long l = 0l; l < _textrows && l < (_txt.lines () - origin ().y); l++) { 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 (FF_FIXED, st & 0x000f); long bg = trans_color (_txt.get_background ((int) j)); long fg = trans_color (_txt.get_foreground ((int) j)); set_color (fg, bg); #endif int col = end ? (int) (_textcolumns + 5) : 6; printat (col, (int) l + 1, "%c", (unsigned int) j < strlen (c) ? c[(int) j] : ' '); #if XVT_OS == XVT_OS_WIN if ((st & underlined) && strlen (c) > (word) j) { PNT b, e; set_pen (COLOR_BLACK); b.h = CHARX * col; b.v = (int) (l + 2l) * CHARY; e.h = CHARX * (col + 1); e.v = (int) (l + 2l) * CHARY; win_move_to (win (), b); win_draw_line (win (), e); } #endif paint_background ((int) l, (int) l + 1); } autoscroll (TRUE); } void TViswin::draw_crossbars () // prints reference crossbars { #if XVT_OS == XVT_OS_WIN if (_cross.v > CHARY && _cross.v < (rows () - 3) * CHARY && _cross.h > CHARX * 5 && _cross.h < columns () * CHARX) { set_pen (COLOR_BLACK); set_mode (M_XOR); PNT b1, e1, b2, e2; autoscroll (FALSE); b1.h = _cross.h; b1.v = CHARY; e1.h = _cross.h; e1.v = ((rows () - 3) * CHARY); b2.h = CHARX * 5; b2.v = _cross.v; e2.h = CHARX * columns (); e2.v = _cross.v; win_move_to (win (), b1); win_draw_line (win (), e1); win_move_to (win (), b2); win_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; } void TViswin::paint_point (bool erase) { autoscroll (FALSE); static bool wasbar; if (_isbar) { invert_bar (6, (int) (_point.y - origin ().y + 1l), (int) columns (), (int) (_point.y - origin ().y + 2l)); invert_bar ((int) (_point.x - origin ().x + 6l), 1, (int) (_point.x - origin ().x + 7l), (int) (rows () - 3l)); } else { invert_bar ((int) (_point.x - origin ().x + 6l), (int) (_point.y - origin ().y + 1l), (int) (_point.x - origin ().x + 7l), (int) (_point.y - origin ().y + 2l)); invert_bar (0, (int) (_point.y - origin ().y + 1l), 5, (int) (_point.y - origin ().y + 2l)); invert_bar ((int) (_point.x - origin ().x + 6l), 0, (int) (_point.x - origin ().x + 7l), 1); } autoscroll (TRUE); wasbar = _isbar; } // draw screen header void TViswin::paint_header () { set_mode (M_COPY); set_opaque_text (TRUE); set_color (FOREGROUND, BACKGROUND); set_font (FF_FIXED, 0); TString htmpst (10); for (int i = 1; i < 26; i++) { htmpst.format ("%d", i); htmpst.right_just (10, '.'); printat (i * 10 - 4, (int) origin ().y, "%s", (const char *) htmpst); } 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 + 1); if (top > 0 && top <= _textrows) { left = p1.y == l ? (int) (p1.x - origin ().x + 6l) : 6; right = p2.y == l ? (int) (p2.x - origin ().x + 6l) : (int) (_textcolumns + 6l); autoscroll (FALSE); invert_bar (left, top, right, top + 1); autoscroll (TRUE); } } } void TViswin::paint_waitbar (bool xor) { #if XVT_OS == XVT_OS_WIN static int pic; #endif autoscroll (FALSE); if (xor) { #if XVT_OS == XVT_OS_WIN cpb_win_picture_draw_at (win (), _picture[pic], 4, 4 + (int) (rows () - 3l) * CHARY); if (pic == 3) pic = 0; else pic++; #else invert_bar (3, rows () - 2, 4, rows () - 1); #endif } else { #if XVT_OS == XVT_OS_WIN cpb_win_picture_draw_at (win (), _picture[pic], 4, 4 + (int) (rows () - 3l) * CHARY); if (pic == 3) pic = 0; else pic++; #else printat (3, rows () - 2, "%c", '*'); #endif } autoscroll (TRUE); } void TViswin::update () { if (_scrolling) return; erase_point (); autoscroll (FALSE); set_mode (M_COPY); set_brush (MASK_BACK_COLOR); bar (5, rows () - 3, columns () + 1, rows () + 1); if (_need_update) { if (_isselection) erase_selection (); clear (COLOR_WHITE); set_mode (M_COPY); set_brush (MASK_BACK_COLOR); autoscroll (FALSE); bar (0, 0, columns () + 1, 1); bar (0, 0, 5, rows () + 1); bar (5, rows () - 3, columns () + 1, rows () + 1); if (_isopen) paint_waitbar (FALSE); #if XVT_OS == XVT_OS_WIN else cpb_win_picture_draw_at (win(), _modpic, 4, 4 + (int) (rows () - 3l) * CHARY); #endif autoscroll (TRUE); paint_header (); paint_screen (); if (_isselection) display_selection (); } display_point (); autoscroll (TRUE); _need_update = TRUE; _need_scroll = none; } void TViswin::abort_print () { if (yesno_box ("Interruzione della stampa su video?")) { _txt.freeze (); freeze (); set_focus (); close_print (); } } 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_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: _txt.print (); 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) { kill_timer (_timer); _istimer = FALSE; } else if (ep->v.timer.id == _wtimer) { paint_waitbar (); kill_timer (_wtimer); if (_isopen) _wtimer = set_timer (win, 150l); } break; case E_MOUSE_DBL: break; case E_MOUSE_DOWN: p = ep->v.mouse.where; trap_mouse (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 - 6); _sel_start.y += (origin ().y - 1); _sel_end = _sel_start; _selecting = TRUE; } else { // show crossbars _cross = ep->v.mouse.where; display_crossbar (); _iscross = TRUE; } break; case E_MOUSE_UP: release_mouse (); if (ep->v.mouse.button == 0) // left button: text selection/move // point { p = ep->v.mouse.where; if (_isopen && (p.x >= 4 && p.x) <= 6 && (p.y >= (int) rows () - 3 && p.y <= (int) rows () - 1)) { abort_print (); ignore = TRUE; } if (ignore) { ignore = FALSE; _selecting = FALSE; break; } // confirm selection & store p.x += (origin ().x - 6); p.y += (origin ().y - 1); 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 <= 5l) { 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 + 6) { 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 - 6); p.y += (origin ().y - 1); _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 { beep (); update_thumb(-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, _point.y); _need_update = TRUE; update (); // AAAARGH! check_link (&_point); _need_update = FALSE; } else { beep (); update_thumb(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 { beep (); update_thumb(-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 { beep (); update_thumb(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 { beep (); update_thumb(-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 { beep (); update_thumb(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 { beep (); update_thumb(-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 { beep (); update_thumb(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 = set_timer (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 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) _txt.print (); 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; } break; case K_TAB: 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 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: 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_GENERAL, "Link"); TString editor (cnf.get ("txt")); bool ok = FALSE; if (!editor.empty ()) { TString newfilename; static FILE_SPEC fs; get_default_dir (&fs.dir); strcpy (fs.type, "txt"); save_dir (); if (save_file_dlg (&fs, "Salva il file con il nome:") == FL_OK) { restore_dir (); char path[256]; dir_to_str (&fs.dir, path, sizeof (path)); newfilename << path << '/' << 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)) beep (); else ok = TRUE; } } else restore_dir (); } 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; dispatch_event (win (), &ev); do_events (); } } void TViswin::close_print () { _isopen = FALSE; kill_timer (_wtimer); _need_update = TRUE; force_update (); } TViswin ::TViswin (const char *fname, const char *title, bool editbutton, bool printbutton, bool linkbutton): _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), _frozen (FALSE) { if (title == NULL) title = (fname ? fname : "Anteprima di stampa"); _isopen = fname == NULL; if (_isopen) _filename = _txt.name (); for (int i = 0; i < MAXBUT; i++) _button[i] = NULL_WIN; const int larg = 76; const int alt = 20; RCT r; get_client_rect (TASK_WIN, &r); int maxlarg = r.right / CHARX - 6; // Calculates max window width int maxalt = r.bottom / CHARY - 6; if (larg > maxlarg) maxlarg = larg; if (alt > maxalt) maxalt = alt; #if XVT_OS == XVT_OS_WIN for (i = 0; i < 4; i++) _picture[i] = cpb_picture_load (BMP_MODULE1 + i); _modpic = cpb_picture_load (BMP_MODULE); #endif create (-1, -1, maxlarg, maxalt, title, WSF_CLOSE | WSF_HSCROLL | WSF_VSCROLL | WSF_SIZE); set_opaque_text (TRUE); set_font (FF_FIXED); 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) { add_button (DLG_PRINT, DLG_PRINT_TITLE); _buttons++; } //#if XVT_OS == XVT_OS_SCOUNIX // maximize(); // #endif _curbut = 0; if (_isopen) _wtimer = set_timer (win (), 150l); _point.set (0, 0); autoscroll (FALSE); _textrows = TEXTROWS; _textcolumns = TEXTCOLUMNS; autoscroll (TRUE); _links = &(main_app().printer ().links ()); _multiple = main_app().printer ().ismultiplelink (); _bg = main_app().printer ().getbgdesc (); _isbackground = _bg->items () > 0; _formlen = main_app().printer ().formlen (); 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 ()); } TViswin ::~TViswin () { #if XVT_OS == XVT_OS_WIN for (int i = 0; i < 4; i++) picture_free (_picture[i]); #endif }