campo-sirio/include/applicat.cpp
guy 043790be92 applicat.cpp Tolti commenti e riscritto meglio controllo di abiliatzione cambio ditta
controls.cpp   Migliorato riconoscimento tasti estesi
dongle.cpp     Aggiunto riconoscimento delle nuove chiavi programmatori
execp.cpp      Aggiunta chiamata per chiudere tutto il chiudibile prima di un'esecuzione sincrona


git-svn-id: svn://10.65.10.50/trunk@6455 c028cbd2-c16b-5b4b-a496-9718f37d4682
1998-03-30 13:39:21 +00:00

879 lines
20 KiB
C++
Executable File

#include <applicat.h>
#include <colors.h>
#include <config.h>
#include <controls.h>
#include <dongle.h>
#include <execp.h>
#include <extcdecl.h>
#include <mask.h>
#include <modaut.h>
#include <os_dep.h>
#include <prefix.h>
#include <printer.h>
#include <relation.h>
#include <urldefid.h>
#include <utility.h>
#include <bagn002.h>
///////////////////////////////////////////////////////////
// Metodi di accesso globali all'applicazione corrente
///////////////////////////////////////////////////////////
HIDDEN TApplication* _application = NULL;
HIDDEN bool _xvt_running = FALSE;
// @doc EXTERNAL
// @func Ritorna l'applicazione in corso
//
// @rdesc Ritorna il reference all'applicazione in corso
TApplication& main_app()
{
CHECK(_application, "NULL application!");
return *_application;
}
// @doc INTERNAL
// @func Controlla se si sta eseguendo xvt
//
// @rdesc Ritorna i seguenti valori:
//
// @flag TRUE | Se se e' stata definita una <c TApplication>
// @flag FALSE | Se se non e' stata definita una <c TApplication>
bool xvt_running()
{ return _xvt_running; }
// Ritorna il nome della ditta che vende il programma attuale
HIDDEN const char* prassi_spa(TString& firm)
{
TConfig ini("install.ini", "Main");
firm = ini.get("Producer");
if (firm.not_empty())
{
const char* p = decode(firm);
for (const char* c = p; *c; c++)
{
if (*c > '\0' && *c < ' ') // Hand crafted string?
{
p = NULL;
break;
}
}
firm = p;
}
if (firm.empty())
{
ignore_xvt_errors(TRUE);
char* p = firm.get_buffer(80);
xvt_res_get_str(STR_FIRMNAME, p, firm.size());
ignore_xvt_errors(FALSE);
}
if (firm.empty())
firm = "PR.A.S.S.I. S.p.A.";
return firm;
}
///////////////////////////////////////////////////////////
// Gestione dello sfondo della finestra principale
///////////////////////////////////////////////////////////
HIDDEN long backdrop_eh(WINDOW win, EVENT* ep)
{
xvt_dwin_clear(win, MASK_DARK_COLOR);
return 0L;
}
HIDDEN void create_backdrop(void)
{
xvt_create_statbar();
xvt_statbar_set("");
}
///////////////////////////////////////////////////////////
// Gestione del banner iniziale
///////////////////////////////////////////////////////////
class TBanner : public TWindow
{
protected:
virtual void handler(WINDOW win, EVENT* ep);
public:
TBanner();
virtual ~TBanner();
};
TBanner::TBanner()
{
create(-1, 6, 72, 6, "BANNER", WSF_NONE, W_PLAIN);
hide_brush();
open();
do_events();
}
TBanner::~TBanner()
{
if (is_open())
close();
}
void TBanner::handler(WINDOW win, EVENT* ep)
{
if (ep->type == E_UPDATE)
{
const int BIGY = 3*CHARY/2;
clear(COLOR_LTGRAY);
RCT r; xvt_vobj_get_client_rect(win, &r);
set_color(COLOR_WHITE, COLOR_LTGRAY);
set_font(XVT_FFN_TIMES, XVT_FS_BOLD | XVT_FS_ITALIC, BIGY);
char* t = (char*)(const char*)main_app().title();
int w = xvt_dwin_get_text_width(win, t, -1);
int a; xvt_dwin_get_font_metrics(win, NULL, &a, NULL);
int x = (r.right-w)>>1, y = (r.bottom+a)>>1 ;
xvt_dwin_draw_text(win, x+1, y+1, t, -1);
set_color(COLOR_BLACK, COLOR_LTGRAY);
xvt_dwin_draw_text(win, x, y, t, -1);
set_font(XVT_FFN_TIMES);
TString spa;
t = (char*)prassi_spa(spa);
w = xvt_dwin_get_text_width(win, t, -1);
x = (r.right-r.left-w)>>1; y = BIGY;
xvt_dwin_draw_text(win, x, y, t, -1);
t = "Caricamento in corso";
w = xvt_dwin_get_text_width(win, t, -1);
x = (r.right-r.left-w)>>1, y = r.bottom - CHARY;
xvt_dwin_draw_text(win, x, y, t, -1);
r.left += 5; r.right -= 4;
r.top += 5; r.bottom -= 4;
set_pen(COLOR_WHITE); xvt_dwin_draw_rect(win, &r);
xvt_rect_offset(&r, -1, -1);
set_pen(COLOR_BLACK); xvt_dwin_draw_rect(win, &r);
xvt_dwin_draw_icon(win, CHARX<<1, CHARX<<1, ICON_RSRC);
}
else
TWindow::handler(win, ep);
}
long XVT_CALLCONV1 TApplication::task_eh(WINDOW win, EVENT *ep)
{
switch (ep->type)
{
case E_CREATE:
if (_application->pre_create())
{
#ifdef _DEMO_
{
const TString16 dname(encode("DATA"));
const TString16 hname(encode("ORA"));
TConfig c(CONFIG_INSTALL, "Main");
TDate data(decode(c.get(dname)));
TDate oggi(TODAY);
real remaining_time(decode(c.get(hname)));
main_app()._start_time = time(NULL);
if (data < oggi)
{
data = oggi;
c.set(dname, encode(data));
c.set(hname, encode("120.00"));
}
else
if (data == oggi)
{
if (remaining_time <= ZERO)
exit(0);
}
else
exit(0);
}
#endif
// Setta il vero menu principale se diverso dal default
const int meno = _application->argc() > 1 ? atoi(_application->argv(1)+1) : 0;
ignore_xvt_errors(TRUE);
MENU_ITEM* menu = xvt_res_get_menu(MENU_BAR(meno));
ignore_xvt_errors(FALSE);
if (menu)
{
xvt_menu_set_tree(win, menu);
xvt_res_free_menu_tree(menu);
}
// Setta la caption della task window
TString cap;
prassi_spa(cap);
cap << " - " << _application->get_module_name();
TTemp_window tw(win);
tw.set_caption(cap);
// Carica colori e font
customize_controls(TRUE);
// Crea il banner iniziale
create_backdrop();
#if defined(DBG) && XVT_OS == XVT_OS_SCOUNIX
message_box("Attach to process %d ...", getpid());
#endif
do_events();
os_allow_another_instance();
}
break;
case E_UPDATE:
backdrop_eh(win, ep);
break;
default:
break;
}
return _application->handler(win, ep);
}
void TApplication::dispatch_e_menu(MENU_TAG tag)
{
::dispatch_e_menu(TASK_WIN, tag);
}
long TApplication::handler(WINDOW win, EVENT* ep)
{
switch (ep->type)
{
case E_CREATE:
{
TBanner banner;
_create_ok = create();
}
if (_create_ok)
{
on_firm_change();
on_config_change();
do_events();
}
else
stop_run();
break;
case E_COMMAND:
switch(ep->v.cmd.tag)
{
case M_FILE_QUIT:
if (can_close())
stop_run();
break;
case M_FILE_PG_SETUP:
printer().set();
break;
case M_FILE_PRINT:
print();
break;
case M_FILE_NEW:
set_firm();
break;
case M_FILE_REVERT:
if (config())
on_config_change();
break;
case (M_FILE_ABOUT+1):
about();
break;
case M_HELP_CONTENTS:
case M_HELP_SEARCH:
case M_HELP_HELPONHELP:
os_exec_help_command(ep->v.cmd.tag, name());
break;
default:
if (ep->v.cmd.tag > MAX_MENU_TAG)
{
WINDOW w = cur_win();
if (w != NULL_WIN && w != win)
::dispatch_e_menu(w, ep->v.cmd.tag);
}
else
{
if (ep->v.cmd.tag >= BAR_ITEM(1))
{
if(!menu(ep->v.cmd.tag))
stop_run();
}
}
break;
}
break;
case E_CLOSE:
if (can_close())
stop_run();
break;
case E_FONT:
{
XVT_FNTID new_font = ep->v.font.font_id;
char font_ser_desc[512];
TConfig font(CONFIG_USER, "Font");
xvt_font_serialize(new_font, font_ser_desc, sizeof(font_ser_desc));
font.set("FontDesc", font_ser_desc);
font.set_paragraph("Colors"); // Forza la scrittura del paragrafo
xvt_load_default_font();
}
break;
case E_QUIT:
if (ep->v.query)
{
if (can_close())
xvt_app_allow_quit();
}
else
stop_run();
break;
default:
break;
}
return 0L;
}
void TApplication::stop_run()
{
if (_savefirm) prefix().set_codditta(_savefirm);
#ifdef _DEMO_
{
const TString16 hname(encode("ORA"));
TConfig c(CONFIG_STUDIO, "Main");
real remaining_time(decode(c.get(hname)));
if (name() != "ba0100")
{
time_t wt = time(NULL);
int delay = (int) (wt - _start_time);
if (delay < 0)
remaining_time = ZERO;
else
remaining_time -= (delay / 60.0);
c.set(hname, encode(remaining_time.string()));
}
else
message_box("Questo e' un programma dimostrativo.\n Oggi rimangono %s minuti di utilizzo.", remaining_time.string(3, 0));
}
#endif
terminate();
xvt_app_destroy();
}
bool TApplication::add_menu(TString_array& menu, MENU_TAG id)
{
TTemp_window tw(TASK_WIN);
return tw.add_menu(menu,id,TRUE);
}
bool TApplication::remove_menu(MENU_TAG id)
{
TTemp_window tw(TASK_WIN);
return tw.remove_menu(id);
}
TApplication::TApplication()
: _savefirm(0), _create_ok(FALSE)
{
}
TApplication::~TApplication()
{}
bool TApplication::create()
{
return TRUE;
}
bool TApplication::destroy()
{
return TRUE;
}
void TApplication::terminate()
{
os_wake_up_caller();
close_all_dialogs();
if (_create_ok)
destroy(); // Distruzione files e maschere
do_events();
if (use_files())
free_global_vars(); // Distruzione variabili globali
printer_destroy();
customize_controls(FALSE); // Rilascio eventuali DLL
}
const char* TApplication::get_module_name() const
{
TString& module = ((TApplication*)this)->_module_name; // Fool the compiler
if (module.empty())
{
TScanner scanner("prassi.aut");
bool ok = FALSE;
for (int aut = 0; scanner.line() != ""; aut++)
if (strncmp(scanner.token(), _name, 2) == 0)
{ ok = TRUE; break; }
module = scanner.token().mid(3);
if (ok && check_autorization())
ok = has_module(aut);
if (!ok)
{
TToken_string em(extra_modules());
if (!em.empty_items())
{
if (em != "*")
{
FOR_EACH_TOKEN(em, cod)
{
if (has_module(atoi(cod)))
{
ok = TRUE;
break;
}
}
}
else
ok = TRUE;
}
if (!ok)
{
error_box("Il modulo '%s' non e' autorizzato", (const char*)module);
module.cut(0);
}
}
}
return module;
}
void TApplication::set_perms()
{
#ifndef _DEMO_
_dongle_aut.set(0, TRUE);
for (int i = 1 ; i < ENDAUT; i++)
{
const bool val = dongle().active(i);
_dongle_aut.set(i, val);
}
#endif
_user_aut.set(0, TRUE);
const TString& utente = user();
if (utente.not_empty())
{
if (utente == "PRASSI")
{
for (int i = 1 ; i < ENDAUT; i++)
_user_aut.set(i);
}
else
{
if (use_files())
{
TLocalisamfile users(LF_USER);
users.zero();
users.put("USERNAME", utente);
if (users.read() == NOERR)
{
const TString& aut = users.get("AUTSTR");
for (int i = aut.len()-1; i > 0; i--)
_user_aut.set(i, aut[i] == 'X');
}
}
}
}
}
// @doc EXTERNAL
// @mfunc Legge il parametro /uUTENTE e lo toglie dalla lista
void TApplication::check_parameters(
int & argc, // @parm Numero del parametro da controllare
char* argv[]) // @parm Array di paramentri da passare all'applicazione
// @comm Nel caso si identifichi che il paramentro <p argc> sia il nome dell'utente
// si setta la variabile col nome dell'utente, altrimenti l'utente diventa PRASSI,
// e si diminuisce di uno il numero di argomenti da passare.
{
if (argc > 1)
{
TString u(argv[argc-1]);
u.upper();
if (u.compare("-u", 2, TRUE) == 0 || u.compare("/u", 2, TRUE) == 0)
{
user() = u.mid(2);
argc--;
}
}
}
// @doc EXTERNAL
// @mfunc Fa partire l'applicazione
void TApplication::run(
int argc, // @parm Numero deglia argomenti da passara all'applicazione
char* argv[], // @parm Argomenti da passare all'applicazione
const char* title) // @parm Titolo dell'applicazione
// @comm E' in questa fase che si controlla se esiste la chiave e' attaccata
{
CHECK(_application == NULL, "Sorry, multitasking not implemented");
// Devo metterla qui per far funzionare la TDongle::network_login
_application = this;
TFilename base(argv[0]);
base.ext(""); base.lower();
_title = title;
if (user().empty())
check_parameters(argc, argv);
_argc_ = argc;
_argv_ = (const char**)argv;
if (argc > 1 && argv[1][0] == '-')
{
_name = cmd2name(argv[0], argv[1]);
}
else
{
_name = cmd2name(argv[0]);
}
const int sn = get_serial_number();
if (sn < 0)
{
error_box("Probabilmente non e' stata inserita la chiave di protezione");
return;
}
if (!test_assistance_year())
{
error_box("Probabilmente e' scaduto il contratto di assistenza");
return;
}
if (use_files())
init_global_vars();
else
CGetPref();
set_perms();
const TFixed_string mod(get_module_name());
if (mod.empty())
return;
XVT_CONFIG cfg;
cfg.menu_bar_ID = TASK_MENUBAR;
cfg.about_box_ID = 0;
cfg.base_appl_name = (char*)base.name();
cfg.appl_name = (char*)title;
cfg.taskwin_title = "PR.A.S.S.I.";
set_xvt_hooks();
_xvt_running = TRUE;
xvt_app_create(argc, argv, 0L, task_eh, &cfg);
}
bool TApplication::get_version_info(int& year, int& release, int& tag, int& patch)
{
const char* const VERSIONANDPATCH = "Don't cry for me Argentina.1998.01.00.000.1999";
TToken_string vep(VERSIONANDPATCH, '.');
year = vep.get_int(1);
release = vep.get_int();
tag = vep.get_int();
patch = vep.get_int();
int checksum = vep.get_int();
bool valid = year >= 1997 && release > 0 && tag >= 0 && patch >= 0 &&
checksum == (year + release + tag + patch);
return valid;
}
// About box: risposta alla opzione Informazioni del menu File
void TApplication::about() const
{
const TFilename n(argv(0));
const word ser_no = dongle().number();
int year, release, tag, patch;
if (get_version_info(year, release, tag, patch))
{
message_box("Versione %d.%02d\nProgramma %s\nN.ro di serie %u-%02d.%03d",
year, release, (const char*)n.name(), ser_no, tag, patch);
}
else
{
#include <prassi.ver>
message_box("Versione %s\nProgramma %s\nLibreria del %s\nN.ro di serie %u-%s",
VERSION, (const char*)n.name(), __DATE__, ser_no, INTERNAL_VERSION);
}
}
// Risposta alla selezione Stampa del menu File
void TApplication::print()
{
#ifdef DBG
error_box("Non saprei bene cosa stampare!");
#endif
}
void TApplication::check_menu_item(MENU_TAG item)
{
xvt_menu_set_item_checked(TASK_WIN, item, TRUE);
xvt_menu_update(TASK_WIN);
}
void TApplication::uncheck_menu_item(MENU_TAG item)
{
xvt_menu_set_item_checked(TASK_WIN, item, FALSE);
xvt_menu_update(TASK_WIN);
}
// @doc EXTERNAL
// @mfunc Permette di abilitare/disabilitare una voce di menu'
void TApplication::enable_menu_item(
MENU_TAG item, // @parm Voce del menu' da abilitare/disabilitare
bool on) // @parm Operazione da svolgere sulla voce del menu':
//
// @flag TRUE | Viene abilitata la voce del menu'
// @flag FALSE | Viene disabilitata la voce del menu'
{
xvt_menu_set_item_enabled(TASK_WIN, item, on);
xvt_menu_update(TASK_WIN);
}
// @cmember Setta il cursore a clessidra (To be removed soon)
void TApplication::begin_wait()
{
::begin_wait();
}
// @cmember Setta il cursore standard (To be removed soon)
void TApplication::end_wait()
{
::end_wait();
}
bool TApplication::has_module(int module, int checktype) const
{
bool ok = TRUE;
#ifndef _DEMO_
if (checktype == CHK_ALL || checktype == CHK_DONGLE)
ok = _dongle_aut[module];
#endif
if (ok && checktype == CHK_ALL || checktype == CHK_USER)
ok = _user_aut[module];
return ok;
}
long TApplication::get_firm() const
{
return prefix().get_codditta();
}
const char* TApplication::get_firm_dir() const
{
return format("%s%s", __ptprf, prefix().name());
}
bool TApplication::set_firm(long newfirm)
{
const long oldfirm = get_firm();
#ifndef _DEMO_
if (newfirm < 1)
{
TMask mask("bagn002");
TFilename pp(__ptprf); pp.cut(pp.len()-1);
mask.set(F_PATHPREF, pp);
mask.show(-2, extended_firm());
disable_menu_item(M_FILE_NEW);
const KEY k = mask.run();
enable_menu_item(M_FILE_NEW);
if (k == K_ENTER)
{
newfirm = mask.get_long(F_CODDITTA);
const int tipodir = mask.get_int(F_TIPO);
if (tipodir == 0 && !prefix().exist(newfirm) &&
!prefix().build_firm_data(newfirm))
return FALSE;
if (tipodir > 0)
{
if (_savefirm == 0) _savefirm = oldfirm; // E' necessario ricordare la ditta ...
prefix().set(tipodir == 1 ? "com" : ""); // ... se si setta il prefix a com
return TRUE;
}
}
}
#endif
if (newfirm == oldfirm || newfirm < 1)
return newfirm > 0;
if (prefix().test(newfirm))
{
prefix().set_codditta(newfirm);
_savefirm = 0;
WINDOW w = cur_win();
if (w != NULL_WIN)
{
TWindow * win = (TWindow *) xvt_vobj_get_data(w);
win->on_firm_change();
}
on_firm_change();
on_config_change();
}
return TRUE;
}
// @doc INTERNAL
// @mfunc Gestisce le voci di configurazione
//
// @rdesc Ritorna TRUE se sono state cambiate delle voci
bool TApplication::config()
// @comm Le si passa il file in cui cercare il proprio paragrafo (comunque relativo
// alla ditta) se non c'e', viene creato copiando il default la variabile EdMask
// di quel paragrafo specifica la maschera da usare.
{
bool ok = FALSE;
TConfig conf(CONFIG_STUDIO);
TFilename name = conf.get("EdApp");
if (name.not_empty())
{
TExternal_app app(name);
ok = app.run() == 0;
return ok;
}
TConfig cnf(CONFIG_DITTA);
name = cnf.get("EdMask");
if (name.empty())
return warning_box("Nessun parametro da configurare");
TMask* msk = new TMask(name); // Evito problemi di stack
TMask& m = *msk;
// carica campi
for (int i = 0; i < m.fields(); i++)
{
TEditable_field& f = (TEditable_field&)m.fld(i);
const TFieldref* fref = f.field();
if (fref != NULL)
{
const char* fname = fref->name();
if (fname != NULL)
{
const TString& oldvl = cnf.get(fname);
if (!oldvl.empty())
f.set(oldvl);
}
}
}
// run mask
disable_menu_item(M_FILE_REVERT);
if (m.run() == K_ENTER && m.dirty())
{
// aggiusta campi
for (i = 0; i < m.fields(); i++)
{
TEditable_field& f = (TEditable_field&)m.fld(i);
if (f.dirty())
{
const TFieldref* fref = f.field();
if (fref != NULL)
cnf.set(fref->name(), f.get(), NULL, TRUE);
}
}
ok = TRUE;
}
delete msk;
enable_menu_item(M_FILE_REVERT);
return ok;
}
// @doc EXTERNAL
// @mfunc Controlla se al programma corrente e' concesso cambiare ditta da menu.
//
// @rdesc Ritorna i seguenti valori:
//
// @flag TRUE | Se e' abilitata la voce di menu' per il cambio della ditta
// @flag FALSE | Se non e' possibile cambiare ditta da menu'
bool TApplication::firm_change_enabled() const
// @comm Praticamente controlla se e' stato lanciato da ba0 o dal program manager
{
#ifdef _DEMO_
return FALSE;
#else
return ::os_spawn_by_menu();
#endif
}
void TApplication::on_firm_change()
{}
void TApplication::on_config_change()
{}
///////////////////////////////////////////////////////////
// The Skeleton application!
///////////////////////////////////////////////////////////
bool TSkeleton_application::create()
{
dispatch_e_menu(BAR_ITEM(1));
return TRUE;
}
bool TSkeleton_application::menu(MENU_TAG tag)
{
if (tag == BAR_ITEM(1))
main_loop();
return FALSE;
}