campo-sirio/include/xvtility.cpp
guy 2a3e35827d Patch level : 10.0 200
Files correlati     : ba1.exe
Ricompilazione Demo : [ ]
Commento            :
0001036: installazione cd patch 180
Installando ex novo ed indicando una società esistente di dati su una cartella diversa viene segnalato l'errore ba1.exe in fase di conversione archivi, richiamando da manutenzione archivi la conversione vengono generati gli errori allegati. Nell'area ftp di Aga, cartella Ilaria allego l'area dati SIDA per il test.


git-svn-id: svn://10.65.10.50/trunk@17971 c028cbd2-c16b-5b4b-a496-9718f37d4682
2008-12-23 09:05:22 +00:00

764 lines
18 KiB
C++
Executable File

#include <applicat.h>
#include <colors.h>
#include <config.h>
#include <controls.h>
#include <mask.h>
#include <prefix.h>
#include <statbar.h>
#include <urldefid.h>
#include <utility.h>
#include <nditte.h>
short CHARX = 8;
short CHARY = 14;
short ROWY = -CHARY; // Not so good!
short BASEY = 12;
// ERROR HOOK che intercetta errori XVT
// put breakpoint here
HIDDEN bool _ignore_xvt_errors = FALSE;
void ignore_xvt_errors(bool ixe)
{
_ignore_xvt_errors = ixe;
}
HIDDEN BOOLEAN error_hook(XVT_ERRMSG err, DATA_PTR)
{
if (_ignore_xvt_errors)
return TRUE;
const XVT_ERRSEV sev = xvt_errmsg_get_sev_id(err);
#ifdef DBG
return sev == 0 ? FALSE : FALSE;
#else
return sev < SEV_ERROR;
#endif
}
// @doc INTERNAL
// @func Calcola dimensioni e posizione di un controllo contenuto nella finestra
//
// @rdesc Ritorna il rettangolo
RCT& resize_rect(
short x, // @parm Coordinata x del controllo (espresso in caratteri)
short y, // @parm Coordinata y del controllo (espresso in caratteri)
short dx, // @parm Larghezza del controllo (espresso in caratteri)
short dy, // @parm Altezza del controllo (espresso in caratteri)
WIN_TYPE wt, // @parm Tipo di controllo da creare
WINDOW parent) // @parm Identificatore della finestra padre
{
static RCT r;
if (parent != TASK_WIN)
{
if (xvt_vobj_get_type(parent) == W_PLAIN) // Mask with Toolbar
{
/* if (y >= 0)
{
const TWindow* w = (const TWindow*)xvt_vobj_get_data(parent);
if (w->is_kind_of(CLASS_MASK))
{
const TMask* m = (const TMask*)w;
if (parent != m->toolwin())
y++;
}
} */
if (x > 0 || (wt != WO_TE && wt != W_PLAIN && x == 0))
{
RCT pc; xvt_vobj_get_client_rect(parent, &pc); // Get parent window size
const int width = pc.right;
const int tot = 80*CHARX;
if (width > tot) x += (width-tot) / (CHARX<<1);
}
}
wt = WC_TEXTEDIT; // Campo di maschera
}
else
{
if (ROWY <= 0) // Not yet initialized
{
RCT pc; xvt_vobj_get_client_rect(parent, &pc);
ROWY = (pc.bottom - pc.top) / 23;
}
}
switch (wt)
{
case WC_TEXTEDIT :
if (x == 0 && dx == 0 && y == 0 && dy == 0) // Campo a tutta pagina!
{
xvt_vobj_get_client_rect(parent, &r);
}
else
{
r.left = (x+1)*CHARX;
r.top = y*ROWY;
r.right = dx*CHARX;
r.bottom = (CHARY << 1) - BASEY;
if (dy > 1)
r.bottom += ROWY*(dy-1);
}
break;
case W_DOC:
r.left = x * CHARX;
r.top = y * ROWY;
r.right = dx * CHARX;
r.bottom = dy * CHARY;
break;
default:
r.left = x * CHARX;
r.top = y * ROWY;
r.right = (dx+2)*CHARX;
r.bottom = dy*ROWY-1;
break;
}
if (x < 0 || y < 0 || dx <= 0 || dy <= 0)
{
RCT pc;
if (parent == NULL_WIN) parent = TASK_WIN;
xvt_vobj_get_client_rect(parent, &pc); // Get parent window size
if (parent == TASK_WIN)
pc.bottom -= 26;
const short MAXX = pc.right;
const short MAXY = pc.bottom;
if (x < 0)
{
x = -x;
if (wt != WC_TEXTEDIT && x == 1) x = 11;
if (x > 10)
{
const int num = x/10 -1;
const int tot = x%10;
const int spc = (MAXX - tot*r.right) / (tot+1);
r.left = spc + num*(spc+r.right);
}
else
r.left = MAXX - r.right - x*CHARX;
}
if (y < 0)
{
y = -y;
if (wt != WC_TEXTEDIT && y == 1) y = 11;
if (y > 10)
{
const int num = y/10 -1;
const int tot = y%10;
const int spc = (MAXY - tot*r.bottom) / (tot+1);
r.top = spc + num*(spc+r.bottom);
}
else
r.top = MAXY - r.bottom - (y-1)*ROWY;
}
if (dx <= 0) r.right = MAXX + dx*CHARX;
else r.right += r.left;
if (dy <= 0) r.bottom = MAXY + dy*ROWY;
else r.bottom += r.top;
}
else
{
r.right += r.left;
r.bottom += r.top;
}
return r;
}
// @doc EXTERNAL
// @func Emette un suono di default
void beep(int severity)
{
xvt_sys_beep(severity);
}
///////////////////////////////////////////////////////////
// Event Handling
///////////////////////////////////////////////////////////
class TEvent_manager
{
enum { MAX = 16 };
WINDOW _w[MAX];
EVENT _e[MAX];
int _begin, _end;
public:
TEvent_manager() : _begin(0), _end(0) {}
void push(WINDOW win, const EVENT& event);
void pop();
};
HIDDEN TEvent_manager EM;
void TEvent_manager::push(WINDOW w, const EVENT& e)
{
CHECK(w, "You shouldn't send events to NULL_WIN!");
_w[_end] = w;
_e[_end] = e;
const int next = (_end+1) % MAX;
if (next == _begin)
warning_box(FR("Hey %s, clicca piu' piano!"), (const char*)user());
else
_end = next;
}
void TEvent_manager::pop()
{
if (_begin != _end)
{
const int i = _begin;
_begin = (++_begin) % MAX; // Other events may occur!
xvt_win_dispatch_event(_w[i], &_e[i]);
}
WINDOW cw = cur_win();
if (cw != NULL_WIN)
{
TWindow* w = (TWindow*)xvt_vobj_get_data(cw);
CHECK(w != NULL, "Can't idle NULL window");
w->on_idle();
}
}
// @doc EXTERNAL
// @func Processa tutti gli eventi rimasti in coda
void do_events()
{
xvt_app_process_pending_events();
EM.pop();
}
// @doc EXTERNAL
// @func Permette di convertire un evento carattere in un codice carattere premuto
//
// @rdesc Ritorna il codice del carattere corrispondente all'evento
KEY e_char_to_key(
const EVENT* ep) // @parm Evento da codificare
// @comm Viene controllato se l'evento e' un e_car e viene tradotto, in caso
// controrio viene emesso un segnale d'errore.
{
CHECK(ep->type == E_CHAR, "I can't convert a Non-E_CHAR event to a key");
KEY key = ep->v.chr.ch;
if (key < K_INS || key > K_HELP)
{
if (ep->v.chr.shift && (key < ' ' || key >= K_UP))
key += K_SHIFT;
//if (ep->v.chr.control && key >= ' ') key += K_CTRL;
if (ep->v.chr.control && (key > K_SHIFT || (key >= K_F1 && key <= K_F12) ||
xvt_chr_is_alnum(key) || strchr("\r+-*/",key) != NULL))
key += K_CTRL;
}
return key;
}
// @doc EXTERNAL
// @func Simula un evento
void dispatch_event(
WINDOW win, // @parm Finestra destinataria dell'evento
const EVENT& e, // @parm Evento da generare
bool post)
{
if (post)
EM.push(win, e);
else
xvt_win_dispatch_event(win, (EVENT*)&e);
}
// @doc EXTERNAL
// @func Simula la scelta di una voce di menu
void dispatch_e_menu(
WINDOW win, // @parm Finestra che contiene il menu
MENU_TAG item) // @parm Voce del menu da selezionare
// @xref <f dispatch_e_char> <f dispatch_e_scroll>
{
EVENT e; memset(&e, 0, sizeof(e));
e.type = E_COMMAND;
e.v.cmd.tag = item;
dispatch_event(win, e, true);
}
// @doc EXTERNAL
// @func Simula la scelta di una combinazione di caratteri
void dispatch_e_char(
WINDOW win, // @parm Finestra che contiene il menu
KEY key) // @parm Combinazione di caratteri da utilizzare
// @xref <f dispatch_e_menu> <f dispatch_e_scroll>
{
EVENT e; memset(&e, 0, sizeof(e));
e.type = E_CHAR;
if (key > K_CTRL)
{ e.v.chr.control = TRUE; key -= K_CTRL; }
if (key > K_SHIFT)
{ e.v.chr.shift = TRUE; key -= K_SHIFT; }
e.v.chr.ch = short(key);
dispatch_event(win, e, TRUE);
}
// @doc EXTERNAL
// @func Simula uno scroll all'interno di una finestra
void dispatch_e_scroll(
WINDOW win, // @parm Finestra nella quale operare
KEY key) // @parm Tasto utilizzato per lo scroll nella finestra
// @xref <f dispatch_e_menu> <f dispatch_e_char>
{
EVENT e; memset(&e, 0, sizeof(e));
EVENT_TYPE& t = e.type;
SCROLL_CONTROL& w = e.v.scroll.what;
short& p = e.v.scroll.pos;
w = SC_NONE;
switch(key)
{
case K_HOME:
t = E_HSCROLL;
w = SC_THUMB;
p = 0;
break;
case K_LHOME:
t = E_VSCROLL;
w = SC_THUMB;
p = 0;
break;
case K_UP:
t = E_VSCROLL;
w = SC_LINE_UP;
break;
case K_DOWN:
t = E_VSCROLL;
w = SC_LINE_DOWN;
break;
case K_BTAB:
t = E_HSCROLL;
w = SC_PAGE_UP;
break;
case K_TAB:
t = E_HSCROLL;
w = SC_PAGE_DOWN;
break;
case K_PREV:
t = E_VSCROLL;
w = SC_PAGE_UP;
break;
case K_NEXT:
t = E_VSCROLL;
w = SC_PAGE_DOWN;
break;
case K_LEFT:
t = E_HSCROLL;
w = SC_LINE_UP;
break;
case K_RIGHT:
t = E_HSCROLL;
w = SC_LINE_DOWN;
break;
default:
break;
};
if (w != SC_NONE)
dispatch_event(win, e, FALSE);
}
void set_xvt_hooks()
{
xvt_vobj_set_attr(NULL_WIN,ATTR_ERRMSG_HANDLER, (long)error_hook);
xvt_vobj_set_attr(NULL_WIN,ATTR_WIN_PM_DRAWABLE_TWIN, TRUE);
long twin_style = xvt_vobj_get_attr(NULL_WIN,ATTR_WIN_PM_TWIN_STARTUP_STYLE);
twin_style |= WSF_ICONIZABLE | WSF_CLOSE; // WSF_SIZE pare azzardato
TConfig cfg(CONFIG_GUI, "Colors");
const int res = cfg.get_int("Resolution");
const int scx = xvt_vobj_get_attr(NULL_WIN, ATTR_SCREEN_WIDTH);
const int scy = xvt_vobj_get_attr(NULL_WIN, ATTR_SCREEN_HEIGHT);
if (res >= 640 && res < scx)
{
const int fx = xvt_vobj_get_attr(NULL_WIN, ATTR_FRAME_WIDTH);
const int fy = xvt_vobj_get_attr(NULL_WIN, ATTR_FRAME_HEIGHT);
const int cy = xvt_vobj_get_attr(NULL_WIN, ATTR_TITLE_HEIGHT);
const int width = res + 2*fx;
const int height = (res * scy) / scx + 2*fy + cy;
const int deltax = (scx - width) / 2;
const int deltay = (scy - height) / 2;
RCT rct;
rct.left = deltax;
rct.top = deltay;
rct.right = deltax + width;
rct.bottom = deltay + height;
xvt_vobj_set_attr(NULL_WIN, ATTR_WIN_PM_TWIN_STARTUP_RCT, long(&rct));
}
else
twin_style |= WSF_MAXIMIZED;
xvt_vobj_set_attr(NULL_WIN,ATTR_WIN_PM_TWIN_STARTUP_STYLE, twin_style);
}
// @doc INTERNAL
// @func Stabilisce i parametri standard dei controlli
void customize_controls(
bool on) // @parm Permette di inizializzare (TRUE) o scaricare (FALSE) i parametri
{
if (on)
{
customize_colors();
init_controls();
}
else
{
free_controls();
}
}
// @doc INTERNAL
// @func Permette di settare il font attivo nella finestra
void xvtil_set_font(
WINDOW win, // @parm Finestra nella quale settare il font
const char* family, // @parm Nome del font da settare
int style, // @parm Stile da applicare al font
int dim) // @parm Dimensione del font
{
CHECK(win != NULL_WIN, "Can't set the font in a NULL window");
if ((family == NULL || *family == '\0') &&
(style == XVT_FS_NONE || style == XVT_FS_BOLD) &&
dim == 0)
{
xvt_dwin_set_font(win, xvtil_default_font(style == XVT_FS_BOLD));
}
else
{
XVT_FNTID font = xvt_dwin_get_font(TASK_WIN);
if (family && *family) xvt_font_set_family(font, family);
if (dim != 0) xvt_font_set_size(font, dim);
if (style != XVT_FS_NONE) xvt_font_set_style(font, style);
if (!xvt_font_is_mapped(font))
xvt_font_map(font, win);
xvt_dwin_set_font(win, font);
xvt_font_destroy(font);
}
}
// @doc INTERNAL
// @func Permette di creare una finestra
//
// @rdesc Ritorna l'identificatore della finestra creata
WINDOW xvtil_create_window(
WIN_TYPE wt, // @parm Tipo di finestra da creare
short x, // @parm Coordinata x della finestra (espresso in caratteri)
short y, // @parm Coordinata y della finestra (espresso in caratteri)
short dx, // @parm Larghezza della finestra (espresso in caratteri)
short dy, // @parm Altezza della finestra (espresso in caratteri)
const char* caption, // @parm Titolo da assegnare alla finestra
int menu, // @parm Menu della finestra (definito nelle risorse, 0=senza)
WINDOW parent, // @parm Identificatore della finestra padre
long flags, // @parm Attributi della finestra
EVENT_HANDLER eh, // @parm Funzioni per la gestione degli eventi diretti alla finestra
long app_data) // @parm Puntatore alla classe C++ che gestisce la finestra
{
RCT& rect = resize_rect(x, y, dx, dy, wt, parent);
if (wt == WD_MODAL)
wt = W_DOC;
WINDOW win = xvt_win_create(wt,
&rect,
(char*)caption,
menu, parent,
flags,
EM_ALL, eh,
app_data);
// Utile per migliorare il calcolo delle dimensioni dei caratteri
xvt_dwin_set_font(win, xvtil_default_font());
CHECK(win, "Can't create a window: XVT error");
return win;
}
///////////////////////////////////////////////////////////
// Gestione Status bar
///////////////////////////////////////////////////////////
HIDDEN WINDOW _statbar = NULL_WIN;
// @doc INTERNAL
// @func Permette di creare la barra di stato del programma
//
// @rdesc Ritorna l'identificatore della barra di stato creata
WINDOW xvtil_create_statbar()
// @xref <f xvt_statbar_set> <f xvt_statbar_refresh>
{
CHECK(_statbar == NULL_WIN, "Onli uan statbar, plis");
if (TASK_WIN != NULL_WIN) // Puo' succedere in chiusura menu
{
const int prop_count = 4;
char* prop_list[prop_count+1] =
{
"Status bar",
"HEIGHT=24",
"TASK_WIN",
"FIELD_OFFSET=24",
NULL
};
_statbar = statbar_create(0, 0, 600, 1024, 800, prop_count, prop_list,
TASK_WIN, 0, 0, "");
CHECK(_statbar, "Can't create the status bar");
statbar_set_fontid(_statbar, xvtil_default_font());
}
return _statbar;
}
// @doc INTERNAL
// @func Permette di settare una finestra con la barra di stato
void xvtil_statbar_set(
const char* text, // @parm Testo da inserire nella barra di stato
bool def) // @parm (default FALSE)
// @comm Nella barra di stato vi e' sempre presente la data del sistema
//
// @xref <f xvt_create_statbar> <f xvt_statbar_refresh>
{
if (_statbar != NULL_WIN)
{
TToken_string t(80, '\t');
t.add(text);
if (prefix_valid() && main_app().get_firm() > 0)
{
t.add(prefix().firm().get(NDT_RAGSOC));
}
else
{
TString80 ragsoc;
xvt_sys_get_profile_string(NULL, "Main", "Company", "", ragsoc.get_buffer(), ragsoc.size());
t.add(ragsoc);
}
t.add(main_app().title());
if (def)
statbar_set_default_title(_statbar, t);
statbar_set_title(_statbar, t);
}
}
// @doc INTERNAL
// @func Setta il testo standard della barra di stato
void xvtil_statbar_refresh()
// @xref <f xvt_create_statbar> <f xvt_statbar_set>
{
if (_statbar)
statbar_set_title(_statbar, NULL);
}
void xvtil_statbar_destroy()
{
if (_statbar != NULL_WIN && statbar_destroy(_statbar))
_statbar = NULL;
}
///////////////////////////////////////////////////////////
// Test menu
///////////////////////////////////////////////////////////
HIDDEN bool test_menu_tag(MENU_ITEM* mi, MENU_TAG tag)
{
while (mi->tag)
{
if (mi->tag == tag) return TRUE;
if (mi->child != NULL)
{
const bool ok = test_menu_tag(mi->child, tag);
if (ok) return TRUE;
}
mi++;
}
return FALSE;
}
// @doc INTERNAL
// @func Controlla se e' esiste una voce del menu'
//
// @rdesc Ritorna i seguenti valori
//
// @flag TRUE | Se esiste la voce di menu'
// @flag FALSE | Se non esiste la voce di menu'
bool xvtil_test_menu_tag(
MENU_TAG tag) // @parm Menu' nel quale cercare la voce
{
bool ok = FALSE;
MENU_ITEM *mi = xvt_menu_get_tree(TASK_WIN);
if (mi)
{
ok = test_menu_tag(mi, tag);
xvt_res_free_menu_tree(mi);
}
return ok;
}
// @doc INTERNAL
// @func Permette di convertire in attributi grafici i codici caratteri usati
// dalle funzioni di stampa
//
// @rdesc Ritorna il codice del colore convertito in attributo grafico
COLOR trans_color(
char c) // @parm Codice carattere da convertire
{
COLOR col = COLOR_WHITE;
switch (c)
{
case 'b': col = COLOR_BLUE; break;
case 'c': col = COLOR_CYAN; break;
case 'd': col = COLOR_DKGRAY; break;
case 'g': col = COLOR_GREEN; break;
case 'k': col = COLOR_GRAY; break;
case 'l': col = COLOR_LTGRAY; break;
case 'm': col = MASK_BACK_COLOR; break;
case 'n': col = COLOR_BLACK; break;
case 'r': col = COLOR_RED; break;
case 'v': col = COLOR_MAGENTA; break;
case 'w': col = COLOR_WHITE; break;
case 'y': col = COLOR_YELLOW; break;
default : NFCHECK("trans_color: Undefined color '%c'", c); break;
}
return col;
}
// @doc INTERNAL
// @func HIDDEN void | set_cursor | Cambia il cursore del mouse
HIDDEN void set_cursor(
bool w) // @parm Indica il tipo di cursore da utilizzare:
//
// @flag TRUE | Cursore a clessidra per le wait
// @flag FALSE | Cursore a frecca normale
{
static int _count = 0;
static WINDOW _win = NULL_WIN;
if (w)
{
if (_count == 0)
{
_win = cur_win();
if (_win == NULL_WIN)
_win = TASK_WIN;
xvt_win_set_cursor(_win, CURSOR_WAIT);
}
_count++;
}
else
{
_count--;
CHECK(_count >= 0, "end_wait without matching begin_wait");
if (_count == 0)
{
WINDOW cur = cur_win();
if (cur == _win)
xvt_win_set_cursor(_win, CURSOR_ARROW);
else
xvt_win_set_cursor(TASK_WIN, CURSOR_ARROW);
}
}
}
void begin_wait()
{ set_cursor(TRUE); }
void end_wait()
{ set_cursor(FALSE); }
// @doc INTERNAL
// @func Permette di converitire lo stile del pattern in attributi grafici da
// codici carattere.
//
// @rdesc Ritorna il pattern convertito
PAT_STYLE trans_brush(
char p) // @parm Codice carattere da convertire
{
switch (p)
{
case 'n' :
return PAT_NONE;
case 'h' :
return PAT_HOLLOW;
case 's' :
return PAT_SOLID;
case '-' :
return PAT_HORZ;
case '|' :
return PAT_VERT;
case '/' :
return PAT_FDIAG;
case '\\':
return PAT_BDIAG;
case 'X' :
return PAT_DIAGCROSS;
case '+' :
return PAT_CROSS;
default :
CHECK(0,"trans_brush: Undefined pattern"); break;
}
return PAT_NONE;
}
// @doc INTERNAL
// @func Permette di convertire lo stile della penna da codice carattere
//
// @rdesc Ritorna lo stilo convertito
PEN_STYLE trans_pen(
char p) // @parm Codice carattere da convertire
{
PEN_STYLE ps = P_SOLID;
switch (p)
{
case 'n' :
ps = P_SOLID; break;
case '.' :
ps = P_DOT; break;
case '-' :
ps = P_DASH; break;
default:
CHECK(0, "trans_pen: Undefined pattern"); break;
}
return ps;
}