Files correlati : Alberi esetsi analmente Ricompilazione Demo : [ ] Commento : git-svn-id: svn://10.65.10.50/trunk@12552 c028cbd2-c16b-5b4b-a496-9718f37d4682
2259 lines
57 KiB
C++
Executable File
2259 lines
57 KiB
C++
Executable File
#include <xinclude.h>
|
|
|
|
#include <controls.h>
|
|
#include <browfile.h>
|
|
#include <colors.h>
|
|
#include <diction.h>
|
|
#include <msksheet.h>
|
|
#include <prefix.h>
|
|
#include <relation.h>
|
|
#include <urldefid.h>
|
|
#include <utility.h>
|
|
|
|
#define DLG_PAGETAGS 31000
|
|
|
|
HIDDEN const char* const MASK_EXT = "msk";
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// PAGE BUTTONS
|
|
///////////////////////////////////////////////////////////
|
|
|
|
class TPage_field : public TRadio_field
|
|
{
|
|
byte _def;
|
|
|
|
protected:
|
|
virtual void current(int) { } // Evita il reset
|
|
virtual int current() const { return _def; }
|
|
|
|
public:
|
|
virtual void set_prompt(const char* p);
|
|
void create(WINDOW parent);
|
|
void set_default(byte d) { _def = d; }
|
|
void show_button(int i, bool on);
|
|
|
|
TPage_field(TMask* m) : TRadio_field(m) { }
|
|
virtual ~TPage_field() { }
|
|
};
|
|
|
|
void TPage_field::create(WINDOW parent)
|
|
{
|
|
_ctl = new TTagbutton_control(parent, _ctl_data._dlg, 0, 0, 80, 1, "", _values, _def);
|
|
}
|
|
|
|
void TPage_field::set_prompt(const char* p)
|
|
{
|
|
_ctl->set_caption(p);
|
|
}
|
|
|
|
void TPage_field::show_button(int i, bool on)
|
|
{
|
|
TTagbutton_control* tag = (TTagbutton_control*)_ctl;
|
|
tag->show_button(i, on);
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// TMask methods
|
|
///////////////////////////////////////////////////////////
|
|
|
|
void TMask::init_mask()
|
|
{
|
|
_msg_field = 0;
|
|
_msg_key = 0;
|
|
_pages = 0; // Azzera numero pagine e sheets
|
|
if (_mask_num == 0) _sheet = NULL; // Non appartiene a nessuno sheet
|
|
|
|
_enabled.set(MAX_PAGES);
|
|
_enabled.set(); // Abilita tutte le pagine
|
|
_should_check = TRUE;
|
|
|
|
_focus = _first_focus = 0; // Il primo ha il focus
|
|
_page = -1; // Nessuna pagina corrente
|
|
_handler = NULL; // Nessun handler utente
|
|
_mode = NO_MODE; // Inizializza modo
|
|
|
|
_error_severity = 0;
|
|
_msg_field = 0;
|
|
_msg_key = 0;
|
|
_test_fld = -1;
|
|
_last_test = -1;
|
|
|
|
memset(_pagewin, 0, sizeof(_pagewin));
|
|
}
|
|
|
|
TMask::TMask()
|
|
: _mask_num(0)
|
|
{ init_mask(); }
|
|
|
|
|
|
TMask::TMask(const char* title, int pages, int cols, int rows,
|
|
int xpos, int ypos, WINDOW parent)
|
|
: _mask_num(0)
|
|
|
|
{
|
|
init_mask();
|
|
for (_pages = 0; _pages < pages; _pages++)
|
|
_pagewin[_pages] = create_interface(parent, xpos, ypos,
|
|
cols, rows, title, this, pages > 1);
|
|
}
|
|
|
|
HIDDEN int customize_field(TConfig & cfg, void * jolly)
|
|
{
|
|
TMask & m = *((TMask *) jolly);
|
|
TToken_string para(cfg.get_paragraph(), ',');
|
|
const int id = para.get_int();
|
|
const int nmask = para.get_int();
|
|
|
|
if (nmask != m.number())
|
|
return 0;
|
|
|
|
const int pos = m.id2pos(id);
|
|
if (pos < 0)
|
|
{
|
|
TScanner scanner(cfg.name());
|
|
scanner.paragraph(para);
|
|
|
|
scanner.popkey();
|
|
TMask_field * f = m.parse_field(scanner);
|
|
const int npage = para.get_int();
|
|
f->construct(scanner, m.win(npage));
|
|
m.add_field(f);
|
|
return 0;
|
|
}
|
|
|
|
TMask_field & f = m.fld(pos);
|
|
|
|
f.update_flags(cfg.get("FLAGS"));
|
|
f.update_flags(cfg.get("NFLAGS"), TRUE);
|
|
if (f.is_operable())
|
|
{
|
|
for (int n = 0; cfg.exist("MESSAGE", n) ; n++)
|
|
{
|
|
const TString m(cfg.get("MESSAGE", NULL, n));
|
|
((TOperable_field &)f).message(n, TRUE)->add(m);
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
// @doc EXTERNAL
|
|
|
|
// @mfunc Legge la maschera da file
|
|
void TMask::read_mask(
|
|
const char* name, // @parm Nome della maschera da leggere (senza estensione)
|
|
int num, // @parm Numero della maschera da leggere all'interno del file
|
|
int max) // @parm Numero massimo di pagine che deve avere la maschera
|
|
{
|
|
TWait_cursor hourglass;
|
|
if (max <= 0) max = MAX_PAGES;
|
|
|
|
_source_file = name;
|
|
_source_file.ext(MASK_EXT);
|
|
_source_file.lower();
|
|
_source_file.custom_path();
|
|
TScanner scanner(_source_file);
|
|
|
|
long start_t = clock();
|
|
while (clock() == start_t) continue; // Attende scatto timer
|
|
start_t = clock();
|
|
|
|
if (num == 0)
|
|
_total_time = _build_time = _init_time = 0;
|
|
else
|
|
_mask_num = num;
|
|
|
|
for (int i = 0; i < num; i++)
|
|
{
|
|
while (scanner.ok())
|
|
if (scanner.line() == "ENDMASK") break;
|
|
}
|
|
|
|
init_mask();
|
|
|
|
TToken_string captions(80);
|
|
|
|
while (scanner.ok() && scanner.popkey() != "EN")
|
|
{
|
|
if (scanner.key() == "PA")
|
|
{
|
|
CHECKD(_pages < MAX_PAGES, "Maschera con troppe pagine: ", _pages);
|
|
WINDOW w = read_page(scanner, FALSE);
|
|
|
|
TString80 title;
|
|
xvt_vobj_get_title(w, title.get_buffer(), title.size());
|
|
captions.add(title);
|
|
|
|
_pagewin[_pages++] = w;
|
|
if (_pages >= max)
|
|
break;
|
|
} else
|
|
if (scanner.key() == "TO")
|
|
{
|
|
CHECK(toolwin() == NULL_WIN, "La maschera puo' avere una sola TOOLBAR");
|
|
_pagewin[MAX_PAGES] = read_page(scanner, TRUE);
|
|
}
|
|
}
|
|
|
|
if (_pages <= 0)
|
|
fatal_box("Impossibile leggere la maschera %s : %d", (const char*)_source_file, num);
|
|
|
|
if (_pages > 1 || toolwin())
|
|
add_tag_buttons(captions);
|
|
|
|
TFilename cust("cust/");
|
|
cust << name; cust.ext("ini");
|
|
|
|
if (cust.exist())
|
|
{
|
|
TConfig cfg(cust);
|
|
|
|
cfg.for_each_paragraph(customize_field, this);
|
|
}
|
|
|
|
if (num == 0)
|
|
_total_time = clock()-start_t;
|
|
}
|
|
|
|
void TMask::add_field(TMask_field* f)
|
|
{
|
|
const long pos = _field.add(f)+1;
|
|
const short id = f->dlg();
|
|
if (id > 0 && id < 512)
|
|
{
|
|
if (_position.objptr(id))
|
|
{
|
|
if (id > DLG_QUIT)
|
|
NFCHECK("Il campo %d e' duplicato!", id);
|
|
}
|
|
else
|
|
_position.TArray::add((TObject*)pos, id);
|
|
}
|
|
}
|
|
|
|
void TMask::add_tag_button(byte pag, TToken_string& tags, byte sel)
|
|
{
|
|
TPage_field* pf = new TPage_field(this);
|
|
pf->_ctl_data._dlg = DLG_PAGETAGS + 100 * pag;
|
|
pf->replace_items("1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16", tags);
|
|
pf->set_default(sel);
|
|
pf->create(_pagewin[pag]);
|
|
add_field(pf);
|
|
}
|
|
|
|
void TMask::add_tag_buttons(TToken_string& tags)
|
|
{
|
|
for (byte p = 0; p < _pages; p++)
|
|
add_tag_button(p, tags, p);
|
|
}
|
|
|
|
void TMask::add_default_tag_buttons()
|
|
{
|
|
TToken_string tags(_pages * 6);
|
|
for (int p = 1; p <= _pages; p++)
|
|
{
|
|
tags.add(TR("Pag."));
|
|
tags << p;
|
|
}
|
|
add_tag_buttons(tags);
|
|
}
|
|
|
|
TMask::TMask(const char* maskname, int num, int max)
|
|
: _mask_num(num)
|
|
{
|
|
if (maskname && *maskname)
|
|
read_mask(maskname, num, max);
|
|
}
|
|
|
|
|
|
TMask::~TMask()
|
|
{
|
|
_field.destroy();
|
|
for (int p = MAX_PAGES; p >= 0; p--)
|
|
if (_pagewin[p])
|
|
{
|
|
if (xvt_vobj_get_attr(_pagewin[p], ATTR_NATIVE_WINDOW) != 0)
|
|
xvt_vobj_destroy(_pagewin[p]);
|
|
_pagewin[p] = NULL_WIN;
|
|
}
|
|
}
|
|
|
|
word TMask::class_id() const
|
|
{ return CLASS_MASK; }
|
|
|
|
bool TMask::is_kind_of(word c) const
|
|
{
|
|
if (c == CLASS_MASK)
|
|
return TRUE;
|
|
return TWindow::is_kind_of(c);
|
|
}
|
|
|
|
void TMask::open()
|
|
{
|
|
if (!_open || _page != 0)
|
|
{
|
|
_open = TRUE;
|
|
if (toolwin())
|
|
xvt_vobj_set_visible(toolwin(), TRUE);
|
|
}
|
|
_focus = first_focus(0);
|
|
set_focus_field(fld(_focus).dlg());
|
|
}
|
|
|
|
int TMask::find_first_active(WINDOW p) const
|
|
{
|
|
const int max = fields();
|
|
for (int f = 0; f < max; f++)
|
|
{
|
|
TMask_field& c = fld(f);
|
|
if (c.active() && c.parent() == p)
|
|
return f;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
int TMask::first_focus(short id)
|
|
{
|
|
static int tempfirstfocus = -1;
|
|
|
|
int f = _first_focus;
|
|
if (id == 0)
|
|
{
|
|
if (tempfirstfocus >= 0)
|
|
{
|
|
f = tempfirstfocus;
|
|
if (fld(f).dirty() == FALSE)
|
|
fld(f).set_dirty();
|
|
tempfirstfocus = -1;
|
|
}
|
|
else
|
|
{
|
|
if (f < 0 || !fld(f).active())
|
|
{
|
|
f = find_first_active(_pagewin[0]);
|
|
if (f < 0 && toolwin())
|
|
f = find_first_active(toolwin());
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (id > 0)
|
|
{
|
|
f = _first_focus = id2pos(id);
|
|
tempfirstfocus = -1;
|
|
}
|
|
else
|
|
f = tempfirstfocus = id2pos(-id);
|
|
}
|
|
|
|
CHECKD(f >= 0 && f < fields(), "Invalid focus field ", f);
|
|
return f;
|
|
}
|
|
|
|
TOperable_field& TMask::focus_field() const
|
|
{
|
|
if (is_open())
|
|
{
|
|
const short focus = low_get_focus_id(win());
|
|
if (focus > 0 )
|
|
((TMask *)this)->notify_focus_field(focus);
|
|
}
|
|
|
|
TMask_field & f = fld(_focus);
|
|
CHECK(f.is_kind_of(CLASS_OPERABLE_FIELD), "A non operable_field has the focus");
|
|
return (TOperable_field&)f;
|
|
}
|
|
|
|
void TMask::set_focus_field(short id)
|
|
{
|
|
notify_focus_field(id);
|
|
if (is_open())
|
|
{
|
|
const TMask_field& f = field(id);
|
|
int p = find_parent_page(f);
|
|
if (p < 0 || p >= _pages || !page_enabled(p))
|
|
p = 0;
|
|
show_page(p);
|
|
}
|
|
}
|
|
|
|
void TMask::notify_focus_field(short id)
|
|
{
|
|
const int pos = id2pos(id);
|
|
CHECKD(pos >= 0, "Can't set focus to field ", id);
|
|
_focus = pos;
|
|
}
|
|
|
|
bool TMask::can_be_closed() const
|
|
{
|
|
if (is_running())
|
|
{
|
|
bool ok = TRUE;
|
|
if ((edit_mode() || insert_mode()) && dirty() && id2pos(DLG_QUIT) < 0)
|
|
ok = yesno_box(TR("Annullare i dati inseriti?"));
|
|
if (ok)
|
|
((TMask*)this)->stop_run(K_FORCE_CLOSE);
|
|
return FALSE;
|
|
}
|
|
return TRUE; // Should never happen!
|
|
}
|
|
|
|
void TMask::close()
|
|
{
|
|
_open = FALSE;
|
|
_page = -1;
|
|
for (int p = 0; p <= MAX_PAGES; p++)
|
|
if (_pagewin[p]) xvt_vobj_set_visible(_pagewin[p], FALSE);
|
|
}
|
|
|
|
short TMask::dirty() const
|
|
{
|
|
const int max = fields();
|
|
for (int i = 0; i < max; i++)
|
|
{
|
|
const TMask_field& f = fld(i);
|
|
if (f.dirty() && f.active())
|
|
return f.dlg();
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void TMask::load_checks() const
|
|
{
|
|
const int max = fields();
|
|
for (int i = 0; i < max; i++)
|
|
{
|
|
TMask_field& f = fld(i);
|
|
if (f.has_check())
|
|
f.check(STARTING_CHECK);
|
|
}
|
|
}
|
|
|
|
// @doc EXTERNAL
|
|
|
|
// @mfunc Abilita/disabilita una pagina e tutte le successive
|
|
void TMask::enable_page(
|
|
byte page, // @parm Pagina da abilitare/disabilitare
|
|
bool on) // @parm Operazione da svolgere:
|
|
//
|
|
// @flag TRUE | Abilita la pagina <p p> (default)
|
|
// @flag FALSE | Disabilita la pagina <p p>
|
|
{
|
|
CHECK(page > 0, "Can't enable/disable first page");
|
|
|
|
if (_enabled[page] != on)
|
|
{
|
|
for (byte i = page; i < _pages; i++)
|
|
{
|
|
_enabled.set(i, on);
|
|
for (byte b = 0; b < _pages; b++)
|
|
{
|
|
TPage_field& pf = (TPage_field&)field(DLG_PAGETAGS + 100 * b);
|
|
pf.show_button(i, on);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Controlla lo stato di abilitazione di una pagina
|
|
// Certified 100%
|
|
bool TMask::page_enabled(byte p) const
|
|
{
|
|
CHECKD(p <= MAX_PAGES, "Page too high ", (int)p);
|
|
const bool on = _pagewin[p] != NULL_WIN && _enabled[p];
|
|
return on;
|
|
}
|
|
|
|
|
|
void TMask::start_run()
|
|
{
|
|
const long start = clock();
|
|
const int max = fields();
|
|
|
|
if (_should_check)
|
|
{
|
|
TWait_cursor hourglass;
|
|
|
|
load_checks();
|
|
|
|
for (int i = 0; i < max; i++)
|
|
{
|
|
TMask_field& f = fld(i);
|
|
if (f.dirty() <= 1) // Attenzione puo' valere anche 3 per i very dirty!
|
|
{
|
|
f.set_dirty(FALSE);
|
|
const bool op = f.is_operable() && !f.is_kind_of(CLASS_BUTTON_FIELD);
|
|
if (op && (f.active() || f.ghost()))
|
|
f.on_hit(); // Lancia messaggio di inizializzazione
|
|
}
|
|
}
|
|
}
|
|
_should_check = TRUE;
|
|
|
|
// Make sure that "nearly" all fields are clean!
|
|
for (int i = 0; i < max; i++)
|
|
{
|
|
TMask_field& f = fld(i);
|
|
if (f.dirty() == 1) // Attenzione puo' valere anche 3 per i very dirty!
|
|
f.set_dirty(FALSE);
|
|
}
|
|
|
|
_init_time = clock()-start;
|
|
_last_test = -1;
|
|
}
|
|
|
|
bool TMask::check_fields()
|
|
{
|
|
WINDOW curpage = NULL_WIN; // Page under test
|
|
|
|
const bool sheet = is_sheetmask() && !is_open();
|
|
|
|
const int max = fields();
|
|
for (int i = 0; i < max; i++)
|
|
{
|
|
TMask_field& f = fld(i);
|
|
const bool on = f.active() || (f.shown() && f.is_sheet());
|
|
if (on) // Don't test inactive fields
|
|
{
|
|
if (f.parent() != curpage)
|
|
{
|
|
const int pa = find_parent_page(f);
|
|
if (!page_enabled(pa))
|
|
break; // Page disabled: end of test
|
|
curpage = f.parent(); // Update current page
|
|
}
|
|
|
|
if (sheet) f.set_dirty(); // Force check in sheet masks
|
|
if (f.on_key(K_ENTER) == FALSE)
|
|
{
|
|
if (is_open())
|
|
set_focus_field(f.dlg());
|
|
return FALSE;
|
|
}
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
void TMask::check_field( short fld_id )
|
|
{
|
|
if (fld_id <= 0)
|
|
{
|
|
const int gr = -fld_id;
|
|
for (int i = fields()-1; i >= 0; i--)
|
|
{
|
|
TMask_field& f = fld(i);
|
|
if (gr == 0 || f.in_group(gr))
|
|
{
|
|
f.on_hit();
|
|
f.check();
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
field(fld_id).on_hit();
|
|
field(fld_id).check();
|
|
}
|
|
}
|
|
|
|
// @doc EXTERNAL
|
|
|
|
// @mfunc Converte un identificatore di campo nella sua posizione
|
|
//
|
|
// @rdesc Ritorna la posizione del campo nella maschera (-1 se non lo trova)
|
|
int TMask::id2pos(
|
|
short id) const // @parm Identificatore del campo del quale trovare la posizione
|
|
|
|
// @comm Cerca nella maschera il campo con identificatore <p id> e ne ritorna il numero ordinale
|
|
// (es. il campo 120 e' il quarto della maschera)
|
|
{
|
|
int pos = -1;
|
|
if (id > 0)
|
|
{
|
|
if (id < 512)
|
|
pos = int(long(_position.objptr(id))-1);
|
|
else
|
|
{
|
|
for (pos = fields()-1; pos >= 0; pos--)
|
|
if (fld(pos).dlg() == id)
|
|
break;
|
|
}
|
|
}
|
|
return pos;
|
|
}
|
|
|
|
|
|
TMask_field& TMask::field(short id) const
|
|
{
|
|
int pos = id2pos(id);
|
|
if (pos < 0)
|
|
{
|
|
yesnofatal_box("Non esiste il campo %d sulla maschera %s", id, (const char*)_source_file);
|
|
pos = 0;
|
|
}
|
|
return fld(pos);
|
|
}
|
|
|
|
TMask_field* TMask::find_by_fieldname(const char* fieldname) const
|
|
{
|
|
for (int i = fields()-1; i >= 0; i--)
|
|
{
|
|
TMask_field& f = fld(i);
|
|
const TFieldref* fr = f.field();
|
|
if (fr && fr->name() == fieldname)
|
|
return &f;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
TEdit_field& TMask::efield(short id) const
|
|
{
|
|
TMask_field& f = field(id);
|
|
CHECKD(f.is_edit(), "Impossibile trattare come editabile il campo ", id);
|
|
return (TEdit_field&)f;
|
|
}
|
|
|
|
TSheet_field& TMask::sfield(short id) const
|
|
{
|
|
TMask_field& f = field(id);
|
|
CHECKD(f.is_sheet(), "Impossibile trattare come spreadsheet il campo ", id);
|
|
return (TSheet_field&)f;
|
|
}
|
|
|
|
TTree_field& TMask::tfield(short id) const
|
|
{
|
|
TMask_field& f = field(id);
|
|
CHECKD(f.is_kind_of(CLASS_TREE_FIELD), "Impossibile trattare come albero il campo ", id);
|
|
return (TTree_field&)f;
|
|
}
|
|
|
|
// @doc EXTERNAL
|
|
|
|
int TMask::find_parent_page(const TMask_field& f) const
|
|
{
|
|
const WINDOW pw = f.parent();
|
|
for (int p = 0; p < _pages; p++)
|
|
if (pw == _pagewin[p]) return p;
|
|
return MAX_PAGES; // Toolbar button
|
|
}
|
|
|
|
// @mfunc Forza la chiusura della maschera
|
|
//
|
|
// @rdesc Ritorna il risultato dell'operazione:
|
|
//
|
|
// @flag TRUE | E' riuscita a chiudere la maschera
|
|
// @flag FALSE | Non e' riuscita a chiudere la maschera
|
|
bool TMask::stop_run(
|
|
KEY key) // @parm Tasto che deve provocare la chiusura
|
|
|
|
// @comm Permette di chiudere la maschera come se l'utente avesse premuto il tasto <p key>.
|
|
// Nel caso la maschera non si chiuda (es. un check fallito), ritorna FALSE.
|
|
{
|
|
if (key != K_AUTO_ENTER && key != K_FORCE_CLOSE)
|
|
{
|
|
const int last = fields();
|
|
int i;
|
|
|
|
for (i = 0; i < last; i++)
|
|
{
|
|
const TMask_field& f = fld(i);
|
|
if (f.active() && f.is_kind_of(CLASS_BUTTON_FIELD))
|
|
{
|
|
const TButton_field& b = (const TButton_field&)f;
|
|
if (b.exit_key() == key)
|
|
break;
|
|
}
|
|
}
|
|
if (i >= last)
|
|
return FALSE;
|
|
}
|
|
|
|
if (key == K_CTRL_ENTER || key == K_AUTO_ENTER)
|
|
key = K_ENTER;
|
|
else
|
|
{
|
|
if (key == K_FORCE_CLOSE)
|
|
key = (id2pos(DLG_QUIT)<0 && id2pos(DLG_CANCEL)>=0) ? K_ESC : K_QUIT;
|
|
}
|
|
|
|
if (key != K_ESC && key != K_QUIT && key != K_DEL && key != K_F9)
|
|
{
|
|
bool ok = check_current_field();
|
|
if (ok)
|
|
ok = check_fields();
|
|
if (ok)
|
|
{
|
|
if (id2pos(DLG_PROFILE) >= 0 && field(DLG_PROFILE).hidden())
|
|
save_profile();
|
|
}
|
|
else
|
|
return FALSE;
|
|
}
|
|
|
|
return TWindow::stop_run(key);
|
|
}
|
|
|
|
void TMask::on_button(short)
|
|
{
|
|
/* Non devo fare niente !!! non essendo una TWindow */
|
|
}
|
|
|
|
void TMask::handler(WINDOW win, EVENT* ep)
|
|
{
|
|
static TSheet_field* _last_sheet = NULL;
|
|
|
|
if (ep->type == E_MOUSE_DOWN && ep->v.mouse.button == 1)
|
|
{
|
|
_last_sheet = NULL;
|
|
for (int f = fields()-1; f >= 0; f--)
|
|
{
|
|
TMask_field& cur_fld = fld(f);
|
|
if (cur_fld.shown() && cur_fld.parent() == win)
|
|
{
|
|
RCT rct; cur_fld.get_rect(rct);
|
|
if (xvt_rect_has_point(&rct, ep->v.mouse.where))
|
|
{
|
|
if (cur_fld.is_kind_of(CLASS_SHEET_FIELD))
|
|
_last_sheet = (TSheet_field*)&cur_fld;
|
|
else
|
|
cur_fld.on_key(K_F11);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (_last_sheet)
|
|
{
|
|
MENU_ITEM* menu = xvt_res_get_menu(BROWSE_BAR);
|
|
if (menu != NULL)
|
|
{
|
|
const PNT& p = ep->v.mouse.where;
|
|
xvt_menu_popup(menu->child, win, p, XVT_POPUP_CENTER, 0); // verificare
|
|
xvt_res_free_menu_tree(menu);
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
if (ep->type == E_COMMAND && _last_sheet != NULL)
|
|
{
|
|
switch (ep->v.cmd.tag)
|
|
{
|
|
case BROWSE_BAR+1: _last_sheet->save_columns_order(); break;
|
|
case BROWSE_BAR+2: _last_sheet->reset_columns_order(); break;
|
|
case BROWSE_BAR+3: _last_sheet->on_key(K_F11); break;
|
|
default: break;
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (ep->type == E_VSCROLL)
|
|
{
|
|
for (int i = 0; i < fields(); i++)
|
|
{
|
|
const TMask_field& ff = fld(i);
|
|
if (ff._ctl != NULL)
|
|
{
|
|
XI_OBJ* obj = ff._ctl->xi_object();
|
|
if (obj->type == 11)
|
|
{
|
|
const int dir = ep->v.scroll.what == SC_LINE_UP ? -3 : +3;
|
|
xi_scroll(obj, dir);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
TWindow::handler(win, ep);
|
|
}
|
|
|
|
|
|
// @doc EXTERNAL
|
|
|
|
// @mfunc Assegna una azione al tasto non standard
|
|
//
|
|
// @rdesc Ritrna se e' stto effetuato una azione:
|
|
//
|
|
// @flag TRUE | Era prevista una azione collegata al tasto ed e' stata eseguita
|
|
// @flag FALSE | Non era prevista nessuna azione collegata al tasto
|
|
bool TMask::on_key(
|
|
KEY key) // @parm Tasto premuto sulla maschera
|
|
|
|
// @comm Controlla se il tasto e' tra quelli standard previsti dalla maschera corrente, in caso
|
|
// contrario ne assegna una azione
|
|
{
|
|
if (_handler)
|
|
{
|
|
const bool cont = _handler(*this, key);
|
|
if (!cont) return FALSE;
|
|
}
|
|
|
|
switch(key)
|
|
{
|
|
case K_AUTO_ENTER:
|
|
case K_CTRL_ENTER:
|
|
case K_QUIT:
|
|
case K_ESC:
|
|
stop_run(key);
|
|
break;
|
|
case K_PREV:
|
|
if (fld(_focus).on_key(K_TAB))
|
|
next_page(-1);
|
|
break;
|
|
case K_NEXT:
|
|
if (fld(_focus).on_key(K_TAB))
|
|
next_page(+1);
|
|
break;
|
|
case K_F1:
|
|
{
|
|
char key[_MAX_FNAME];
|
|
xvt_fsys_parse_pathname(source_file(), NULL, NULL, key, NULL, NULL);
|
|
|
|
EVENT e; memset(&e, 0, sizeof(e));
|
|
e.type = E_HELP;
|
|
e.v.help.tag = M_HELP_ONCONTEXT;
|
|
e.v.help.obj = win();
|
|
e.v.help.tid = (long)key;
|
|
|
|
TFilename n = "campo";
|
|
TString16 module = key; module.cut(2);
|
|
if (module != "ba")
|
|
n.insert(module);
|
|
FILE_SPEC fs; memset(&fs, 0, sizeof(FILE_SPEC));
|
|
strcpy(fs.name, n);
|
|
XVT_HELP_INFO hi = xvt_help_open_helpfile(&fs, 0);
|
|
xvt_help_process_event(hi, win(), &e);
|
|
}
|
|
break;
|
|
case K_F12:
|
|
post_error_message(format("Lettura = %ld\n"
|
|
"Creazione = %ld\n"
|
|
"Inizializzazione = %ld\n",
|
|
_total_time-_build_time, _build_time, _init_time),
|
|
1);
|
|
break;
|
|
case K_CTRL+'+':
|
|
if (is_running())
|
|
{
|
|
// Cerco nella pagina corrente il primo spreadsheet a partire dal campo col focus
|
|
if (_focus < 0) _focus = 0;
|
|
const WINDOW myparent = fld(_focus).parent();
|
|
for (int fire = _focus; fire < fields(); fire++)
|
|
{
|
|
TMask_field& f = fld(fire);
|
|
if (f.parent() != myparent)
|
|
break;
|
|
if (f.is_kind_of(CLASS_SHEET_FIELD))
|
|
{
|
|
TSheet_field& s = (TSheet_field&)f;
|
|
const int newrow = s.append() ? -1 : 0;
|
|
notify_focus_field(s.dlg());
|
|
s.insert(newrow, TRUE, TRUE);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
if (key > K_CTRL)
|
|
{
|
|
key -= K_CTRL;
|
|
if (key >= K_F1 && key <= K_F12)
|
|
{
|
|
const int page = key - K_F1;
|
|
if (page < _pages && fld(_focus).on_key(K_TAB))
|
|
show_page(page);
|
|
}
|
|
else
|
|
{
|
|
for (int i = fields()-1; i >= 0; i--)
|
|
{
|
|
TMask_field& f = fld(i);
|
|
if (f.active() && f.is_kind_of(CLASS_BUTTON_FIELD))
|
|
{
|
|
TButton_field& b = (TButton_field&)f;
|
|
if (b.virtual_key() == key)
|
|
{
|
|
f.on_key(K_SPACE);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
bool TMask::on_dirty(TMask_field&)
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
int TMask::win2page(WINDOW w) const
|
|
{
|
|
for (int p = MAX_PAGES; p >= 0; p--)
|
|
if (w == _pagewin[p])
|
|
return p;
|
|
return -1;
|
|
}
|
|
|
|
TMask_field* TMask::parse_field(TScanner& scanner)
|
|
{
|
|
const TString& k = scanner.key();
|
|
if (k == "ST") return new TEdit_field(this);
|
|
if (k == "NU") return new TReal_field(this);
|
|
if (k == "DA") return new TDate_field(this);
|
|
if (k == "BO") return new TBoolean_field(this);
|
|
if (k == "TE") return new TText_field(this);
|
|
if (k == "BU") return new TButton_field(this);
|
|
if (k == "GR") return new TGroup_field(this);
|
|
if (k == "LI") return new TList_field(this);
|
|
if (k == "RA") return new TRadio_field(this);
|
|
if (k == "CU") return new TCurrency_field(this);
|
|
if (k == "ME") return new TMemo_field(this);
|
|
if (k == "ZO") return new TZoom_field(this);
|
|
if (k == "GO") return new TGolem_field(this);
|
|
if (k == "BR") return new TBrowsefile_field(this);
|
|
if (k == "SP") return new TSheet_field(this);
|
|
if (k == "TR") return new TTree_field(this);
|
|
if (k == "CL") return new TGolem_client_field(this);
|
|
return NULL;
|
|
}
|
|
|
|
int TMask::sheets() const
|
|
{
|
|
int count = 0;
|
|
for (int f = fields()-1; f >= 0; f--)
|
|
{
|
|
if (fld(f).is_sheet())
|
|
count++;
|
|
}
|
|
return count;
|
|
}
|
|
|
|
// @doc EXTERNAL
|
|
|
|
// @mfunc Legge la pagina dal file
|
|
//
|
|
// @rdesc Ritorna l'handle della finestra creata
|
|
WINDOW TMask::read_page(
|
|
TScanner& scanner, // @parm File dal quale leggere la pagina
|
|
bool toolbar) // @parm Indica se e' la toolbar
|
|
|
|
// @comm Il parametro <p toolbar> e' utilizzato per indicare se la pagina deve essere visualizzata
|
|
// a tutto schermo (TRUE) oppure no
|
|
{
|
|
static int tooly;
|
|
static RCT rect;
|
|
|
|
const TString title = dictionary_translate(scanner.string());
|
|
|
|
RCT r;
|
|
if (toolwin()) // Pagina successiva ad una toolbar
|
|
{
|
|
scanner.line();
|
|
xvt_rect_set(&r, 0, 0, 0, tooly);
|
|
}
|
|
else
|
|
{
|
|
scanner.rectangle(r.left, r.top, r.right, r.bottom);
|
|
if (toolbar)
|
|
{
|
|
if (r.top > 15) // Rendi negative le coordinate delle toolbar per ...
|
|
r.top -= 23; // ... ottimizzare l'uso dello schermo ad alta risoluzione
|
|
tooly = r.top;
|
|
}
|
|
else
|
|
{
|
|
if (_pages == 0)
|
|
{
|
|
if (!is_sheetmask())
|
|
rect = r;
|
|
}
|
|
else
|
|
r = rect;
|
|
}
|
|
}
|
|
|
|
bool orecchie = _pagewin[0] != NULL_WIN || toolwin();
|
|
if (!orecchie && !toolbar) // Controlla se la maschera ha piu' di una pagina
|
|
{
|
|
const streampos pos = scanner.tellg(); // Memorizza posizione dello scanner
|
|
while (TRUE)
|
|
{
|
|
const TString& l = scanner.line();
|
|
|
|
if (l.empty() || l == "ENDMASK") // Fine maschera
|
|
break;
|
|
|
|
if (l.compare("PA", 2, TRUE) == 0) // Ho trovato un'altra pagina!
|
|
{
|
|
orecchie = TRUE; // Quindi devo metterci le orecchie
|
|
break;
|
|
}
|
|
}
|
|
scanner.seekg(pos); // Ripristina posizione dello scanner
|
|
}
|
|
|
|
WINDOW w;
|
|
if (toolbar || toolwin())
|
|
{
|
|
if (toolbar)
|
|
w = create_interface(NULL_WIN, 0, r.top, 0, 0, title, this, FALSE);
|
|
else
|
|
w = create_interface(NULL_WIN, 0, r.top, 0, tooly, title, this, orecchie);
|
|
}
|
|
else
|
|
{
|
|
w = create_interface(NULL_WIN, r.left, r.top, r.right, r.bottom, title, this, orecchie);
|
|
}
|
|
|
|
while (scanner.popkey() != "EN")
|
|
{
|
|
TMask_field* f = parse_field(scanner);
|
|
if (f == NULL)
|
|
{
|
|
#ifdef DBG
|
|
const int f = fields();
|
|
TString e;
|
|
e << "Campo non riconosciuto alla posizione " << f;
|
|
if (f > 0)
|
|
e << ".\nL'ultimo riconosciuto e' " << fld(f-1).dlg() << ": " << fld(f-1).prompt();
|
|
error_box(e);
|
|
#endif
|
|
while (scanner.popkey() != "EN");
|
|
}
|
|
else
|
|
{
|
|
const long start = clock();
|
|
f->construct(scanner, w);
|
|
add_field(f);
|
|
_build_time += clock()-start;
|
|
}
|
|
}
|
|
return w;
|
|
}
|
|
|
|
bool TMask::check_current_field() const
|
|
{
|
|
bool ok = TRUE;
|
|
if (_focus >= 0)
|
|
{
|
|
TMask_field& ff = fld(_focus);
|
|
if (ff.focusdirty())
|
|
ok = ff.on_key(K_TAB);
|
|
}
|
|
return ok;
|
|
}
|
|
|
|
// @doc EXTERNAL
|
|
|
|
// @mfunc Mostra la prossima/precedente pagina
|
|
void TMask::next_page(
|
|
int p) // @parm Pagina alla quale saltare
|
|
|
|
// @comm Il valore <p p> puo' assumere i seguenti valori:
|
|
//
|
|
// @flag -1 | Mostra la pagina precedente
|
|
// @flag 0 | Mostra la pagina corrente
|
|
// @flag +1 | Mostra la pagina successiva
|
|
// @flag 1000+n | Mostra la pagina n-esima
|
|
{
|
|
const int prev = _page; // Previous page
|
|
|
|
if (p != 0)
|
|
{
|
|
const int k = (p < 1000) ? _page+p : p-1000;
|
|
if (k < 0 || k >= _pages || !page_enabled(k))
|
|
{
|
|
beep();
|
|
return;
|
|
}
|
|
_page = k;
|
|
}
|
|
else
|
|
{
|
|
if (_page < 0 || _page >= _pages)
|
|
_page = 0;
|
|
}
|
|
if (_page != prev)
|
|
{
|
|
xvt_vobj_set_visible(win(), TRUE);
|
|
if (prev >= 0)
|
|
xvt_vobj_set_visible(_pagewin[prev], FALSE);
|
|
}
|
|
|
|
TMask_field& ff = fld(_focus);
|
|
if (ff.parent() != win() || !ff.active())
|
|
{
|
|
_focus = find_first_active(win());
|
|
if (_focus < 0 && toolwin() != NULL_WIN)
|
|
_focus = find_first_active(toolwin());
|
|
}
|
|
|
|
TWindow::set_focus();
|
|
|
|
if (_focus >= 0)
|
|
{
|
|
TMask_field& ff = fld(_focus);
|
|
if (ff.active())
|
|
ff.highlight();
|
|
}
|
|
}
|
|
|
|
void TMask::show_page(int p)
|
|
{
|
|
CHECKD(p >= 0 && p < _pages, "Pagina errata ", p);
|
|
next_page(1000 + p);
|
|
}
|
|
|
|
void TMask::reset(short fld_id)
|
|
{
|
|
if (fld_id <= 0)
|
|
{
|
|
const int gr = -fld_id;
|
|
for (int f = fields()-1; f >= 0; f--)
|
|
{
|
|
TMask_field& c = fld(f);
|
|
if (gr == 0 || c.in_group(gr))
|
|
{
|
|
c._flags.dirty = c._flags.focusdirty = FALSE;
|
|
c.reset();
|
|
}
|
|
}
|
|
}
|
|
else field(fld_id).reset();
|
|
}
|
|
|
|
const TString& TMask::get(short fld_id) const
|
|
{
|
|
const TString& s = field(fld_id).get();
|
|
return s;
|
|
}
|
|
|
|
const TString& TMask::get(const char * fld_id) const
|
|
{
|
|
const TString * s = &EMPTY_STRING;
|
|
for (int i = 0 ; i < fields(); i++)
|
|
{
|
|
TMask_field& f = fld(i);
|
|
const TFieldref * campo = f.field();
|
|
if (campo != NULL && campo->name() == fld_id)
|
|
{
|
|
s= &f.get();
|
|
if (f.active())
|
|
break;
|
|
}
|
|
}
|
|
return *s;
|
|
}
|
|
|
|
long TMask::get_long(short fld_id) const
|
|
{
|
|
// const TString& s = field(fld_id).get();
|
|
const TString& s = get(fld_id);
|
|
return atol(s);
|
|
}
|
|
|
|
bool TMask::get_bool(short fld_id) const
|
|
{
|
|
// const TString& s = field(fld_id).get();
|
|
const TString& s = get(fld_id);
|
|
return s.not_empty();
|
|
}
|
|
|
|
real TMask::get_real(short fld_id) const
|
|
{
|
|
// const TString& s = field(fld_id).get();
|
|
const TString& s = get(fld_id);
|
|
return real(s);
|
|
}
|
|
|
|
TDate TMask::get_date(short fld_id) const
|
|
{
|
|
// const TString& s = field(fld_id).get();
|
|
const TString& s = get(fld_id);
|
|
return TDate(s);
|
|
}
|
|
|
|
TCurrency& TMask::get_currency(short fld_id, TCurrency& c) const
|
|
{
|
|
const TMask_field& cf = field(fld_id);
|
|
if (cf.class_id() == CLASS_CURRENCY_FIELD)
|
|
{
|
|
((TCurrency_field&)cf).get_currency(c);
|
|
}
|
|
else
|
|
{
|
|
real n(cf.get());
|
|
c.force_value("");
|
|
c.set_num(n);
|
|
}
|
|
return c;
|
|
}
|
|
|
|
// @doc EXTERNAL
|
|
|
|
// @mfunc Setta il campo con un valore
|
|
void TMask::set(
|
|
short fld_id, // @parm Identificatore del campo da settare
|
|
const char* s, // @parm Stringa da assegnare al campo
|
|
byte hit) // @parm Indica se occorre rifare i controlli una volta settato il campo
|
|
// con il nuovo valore (default FALSE)
|
|
// @parm long | n | Numero da asegnare al campo
|
|
|
|
// @syntax set(short fld_id, const char *s, bool hit);
|
|
// @syntax set(short fld_id, long n, bool hit);
|
|
{
|
|
TMask_field& f = field(fld_id);
|
|
f.set(s);
|
|
if ((f.active() || f.ghost()))
|
|
{
|
|
f.set_dirty();
|
|
if (hit & 0x2)
|
|
f.check();
|
|
if (hit & 0x1)
|
|
f.on_hit();
|
|
}
|
|
}
|
|
|
|
void TMask::set(
|
|
const char * fld_id, // @parm FIELD del campo da settare
|
|
const char* str, // @parm Stringa da assegnare al campo
|
|
byte hit) // @parm Indica se occorre rifare i controlli una volta settato il campo
|
|
// con il nuovo valore (default FALSE)
|
|
// @parm long | n | Numero da asegnare al campo
|
|
|
|
// @syntax set(short fld_id, const char *s, bool hit);
|
|
// @syntax set(short fld_id, long n, bool hit);
|
|
{
|
|
for (int i = 0 ; i < fields(); i++)
|
|
{
|
|
TMask_field& f = fld(i);
|
|
const TFieldref * campo = f.field();
|
|
if (campo != NULL && campo->name() == fld_id)
|
|
set(f.dlg(), str, hit);
|
|
}
|
|
}
|
|
|
|
void TMask::set(short fld_id, long n, byte hit)
|
|
{
|
|
char s[16];
|
|
sprintf(s, "%ld", n);
|
|
set(fld_id, s, hit);
|
|
}
|
|
|
|
void TMask::set(short fld_id, const real& n, byte hit)
|
|
{
|
|
CHECK(id2pos(fld_id) < 0 || field(fld_id).is_edit(), "Can't set a real value in a non edit field");
|
|
set(fld_id, n.string(), hit);
|
|
}
|
|
|
|
void TMask::set(short fld_id, const TDate& d, byte hit)
|
|
{
|
|
CHECK(id2pos(fld_id) < 0 || field(fld_id).is_kind_of(CLASS_DATE_FIELD), "Can't set a date in a non-date field");
|
|
set(fld_id, d.string(), hit);
|
|
}
|
|
|
|
void TMask::set(short fld_id, const TCurrency& n, byte hit)
|
|
{
|
|
CHECK(field(fld_id).is_kind_of(CLASS_CURRENCY_FIELD), "Can't set a currency in a non-currency field");
|
|
// CHECK(id2pos(fld_id) < 0 || field(fld_id).is_edit(), "Can't set a currency in a non edit field");
|
|
set(fld_id, n.get_num().string(), hit);
|
|
}
|
|
|
|
// @doc EXTERNAL
|
|
|
|
// @mfunc Permette di attivare/disattivare tutta la pagina
|
|
void TMask::activate(
|
|
bool on) // @parm Indica l'operazione da svolgere sul campo:
|
|
//
|
|
// @flag TRUE | Attiva la pagina(default)
|
|
// @flag FALSE | Disattiva la pagina
|
|
{
|
|
TWindow::activate(on);
|
|
if (toolwin() != NULL_WIN)
|
|
xvt_vobj_set_visible(toolwin(), on);
|
|
}
|
|
|
|
// @doc EXTERNAL
|
|
|
|
// @mfunc Abilita/disabilita un campo
|
|
void TMask::enable(
|
|
short fld_id, // @parm Identificatore del campo da abilitare (0 tutti i campi, <0 id gruppo)
|
|
bool on) // @parm Indica l'operazione da svolgere sul campo:
|
|
//
|
|
// @flag TRUE | Abilita il campo (default)
|
|
// @flag FALSE | Disabilita il campo
|
|
{
|
|
if (fld_id <= 0)
|
|
{
|
|
const int gr = -fld_id;
|
|
for (int i = fields()-1; i >= 0; i--)
|
|
{
|
|
TMask_field& f = fld(i);
|
|
if (gr == 0 || f.in_group(gr))
|
|
f.enable(on);
|
|
}
|
|
}
|
|
else
|
|
field(fld_id).enable(on);
|
|
}
|
|
|
|
|
|
void TMask::enable_default(short fld_id)
|
|
{
|
|
if (fld_id <= 0)
|
|
{
|
|
const int gr = -fld_id;
|
|
for (int i = fields()-1; i >= 0; i--)
|
|
{
|
|
TMask_field& f = fld(i);
|
|
if (gr == 0 || f.in_group(gr))
|
|
f.enable_default();
|
|
}
|
|
}
|
|
else
|
|
field(fld_id).enable_default();
|
|
}
|
|
|
|
|
|
word TMask::num_keys() const
|
|
{
|
|
word max = 0;
|
|
for (int i = fields()-1; i >= 0; i--)
|
|
{
|
|
const TMask_field& f = fld(i);
|
|
if (f.is_editable())
|
|
{
|
|
word k = ((const TEditable_field&)f).last_key();
|
|
if (k > max) max = k;
|
|
}
|
|
}
|
|
return max;
|
|
}
|
|
|
|
// @doc EXTERNAL
|
|
|
|
// @mfunc Abilita/disabilita i campi di una chiave sulla maschera
|
|
void TMask::enable_key(
|
|
word key, // @parm Chiave di cui abilitare il campo
|
|
bool on) // @parm Indica l'operazione da svolgere sul tasto:
|
|
//
|
|
// @flag TRUE | Abilita il campo (default)
|
|
// @flag FALSE | Disabilita il campo
|
|
|
|
{
|
|
for (int i = fields()-1; i >= 0; i--)
|
|
{
|
|
TMask_field& f = fld(i);
|
|
if (f.in_key(key))
|
|
{
|
|
if (on)
|
|
{
|
|
f.enable_default();
|
|
if (!f.shown())
|
|
f.show_default();
|
|
}
|
|
else
|
|
f.disable();
|
|
}
|
|
}
|
|
}
|
|
|
|
// @doc EXTERNAL
|
|
|
|
// @mfunc Ritorna il l'identificatore di un campo della chiave <p key>
|
|
//
|
|
// @rdesc Ritorna l'identificatore del campo cercato
|
|
TEditable_field* TMask::get_key_field(
|
|
word key, // @parm Chiave di cui controllare l'esistenza
|
|
bool first) const // @parm Indica se la ricerca dev partire dell'inizio. Assume i valori:
|
|
//
|
|
// @flag TRUE | Comincia la ricerca dal primo campo della maschera
|
|
// @flag FALSE | Comincia la ricerca dal campo attuale nella maschera
|
|
{
|
|
static int last = 0;
|
|
|
|
if (first) last = 0;
|
|
|
|
const int max = fields();
|
|
for (int i = last; i < max; i++)
|
|
{
|
|
TMask_field& f = fld(i);
|
|
if (f.in_key(key))
|
|
{
|
|
last = i+1;
|
|
return (TEditable_field*)&f;
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
bool TMask::key_valid(word key) const
|
|
{
|
|
const int max = fields();
|
|
for (short f = 0; f < max; f++)
|
|
{
|
|
TMask_field& c = fld(f);
|
|
if (c.is_editable() && c.shown())
|
|
{
|
|
TEditable_field& e = (TEditable_field&)c;
|
|
if (e.required() && e.in_key(key))
|
|
{
|
|
if (e.empty())
|
|
return FALSE;
|
|
}
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
// @doc EXTERNAL
|
|
|
|
// @mfunc Permette di mostrare/nascondere un campo
|
|
void TMask::show(
|
|
short fld_id, // @parm Campo da mostrare/nascondere (default -1)
|
|
bool on) // @parm Indica l'operazione da svolgere sul campo:
|
|
//
|
|
// @flag TRUE | Mostra il campo(default)
|
|
// @flag FALSE | Nasconde il campo
|
|
|
|
// @comm Se <p fld_id> e' -1 allora permette di operare su tutti i campi della maschera
|
|
|
|
{
|
|
if (fld_id <= 0)
|
|
{
|
|
const int gr = -fld_id;
|
|
for (int i = fields()-1; i >= 0; i--)
|
|
{
|
|
TMask_field& f = fld(i);
|
|
if (gr == 0 || f.in_group(gr))
|
|
f.show(on);
|
|
}
|
|
}
|
|
else field(fld_id).show(on);
|
|
}
|
|
|
|
// @doc EXTERNAL
|
|
// @mfunc Rimette lo stato di default del campo
|
|
void TMask::show_default(
|
|
short fld_id) // @parm Identificatore del campo da risettare (default -1)
|
|
|
|
// @comm Se <p parm> Assume il valore -1 vuole dire che vengono risettati tutti i campi della amschera
|
|
{
|
|
if (fld_id <= 0)
|
|
{
|
|
for (int i = fields()-1; i >= 0; i--)
|
|
fld(i).show_default();
|
|
} else field(fld_id).show_default();
|
|
}
|
|
|
|
|
|
void TMask::autoload(const TRelation& r)
|
|
{
|
|
const int max = fields();
|
|
for (int i = 0; i < max; i++)
|
|
{
|
|
TMask_field& f = fld(i);
|
|
if (f.is_loadable())
|
|
((TLoadable_field&)f).autoload(r);
|
|
}
|
|
}
|
|
|
|
|
|
void TMask::autosave(TRelation& r) const
|
|
{
|
|
const int max = fields();
|
|
for (int i = 0; i < max; i++)
|
|
{
|
|
TMask_field& f = fld(i);
|
|
if (f.is_loadable())
|
|
{
|
|
TLoadable_field& l = (TLoadable_field&)f;
|
|
bool save = f.shown();
|
|
if (!save && f.is_editable())
|
|
{
|
|
// tenta di effettuare il save dei campi Edit hidden:
|
|
// salva il nuovo valore solo se il precedente era blank
|
|
TEditable_field& e = (TEditable_field&)f;
|
|
if (e.field() != NULL)
|
|
{
|
|
const char* str = l.field()->read(r);
|
|
save = *str == '\0';
|
|
}
|
|
}
|
|
if (save)
|
|
l.autosave(r);
|
|
}
|
|
}
|
|
}
|
|
|
|
void TMask::on_firm_change()
|
|
{
|
|
TString16 firm;
|
|
firm << prefix().get_codditta();
|
|
for (int i = fields()-1; i >= 0; i--)
|
|
{
|
|
TMask_field& f = fld(i);
|
|
if (f._flags.firm)
|
|
{
|
|
f.set(firm);
|
|
f.check(STARTING_CHECK);
|
|
f.on_hit();
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void TMask::on_idle()
|
|
{
|
|
if (_focus >= 0 && _focus < fields())
|
|
{
|
|
if (fld(_focus).is_operable())
|
|
{
|
|
TOperable_field& s = (TOperable_field&)fld(_focus);
|
|
s.on_idle();
|
|
|
|
if (_msg_field > 0)
|
|
{
|
|
TMask_field& f = field(_msg_field);
|
|
_msg_field = 0;
|
|
if (_msg_key > 0)
|
|
f.on_key(_msg_key);
|
|
}
|
|
}
|
|
if (_error_severity > 0)
|
|
{
|
|
switch(_error_severity)
|
|
{
|
|
case 2:
|
|
warning_box("%s", (const char*)_error_message); break;
|
|
case 3:
|
|
error_box("%s", (const char*)_error_message); break;
|
|
default:
|
|
message_box("%s", (const char*)_error_message); break;
|
|
}
|
|
_error_severity = 0;
|
|
set_focus();
|
|
}
|
|
if (_test_fld >= 0)
|
|
{
|
|
const TOperable_field & f = focus_field();
|
|
if (_last_test != f.dlg())
|
|
{
|
|
TEditable_field & e = (TEditable_field &) field(_test_fld);
|
|
|
|
if (!f.in_key(0) || !e.has_a_common_key(f))
|
|
{
|
|
e.test_key_complete(FALSE);
|
|
_test_fld = -1;
|
|
}
|
|
_last_test = f.dlg();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// @doc EXTERNAL
|
|
|
|
// @mfunc Permette di mandare un tasto ad un campo
|
|
void TMask::send_key(
|
|
KEY key, // @parm Codice del tasto da spedire
|
|
short to, // @parm Identificatore del campo che deve ricevere
|
|
TMask_field* from) // @parm Campo che spedisce il tasto
|
|
{
|
|
if (to == 0)
|
|
{
|
|
WINDOW w = from ? from->parent() : _pagewin[0];
|
|
dispatch_e_char(w, key);
|
|
return;
|
|
}
|
|
|
|
if (to > 0)
|
|
{
|
|
if (to == DLG_PAGE)
|
|
{
|
|
CHECK(from, "You should specify a sender!");
|
|
const int p = find_parent_page(*from)+1;
|
|
CHECKD(p > 0 && p < _pages, "You should specify a good page, not ", p);
|
|
key -= K_CTRL+K_SHIFT;
|
|
enable_page(p, key == 's' || key == 'e');
|
|
}
|
|
else
|
|
{
|
|
const int pos = id2pos(to);
|
|
if (pos >= 0)
|
|
{
|
|
if (_msg_field > 0)
|
|
on_idle();
|
|
_msg_field = to;
|
|
_msg_key = key;
|
|
}
|
|
#ifdef DBG
|
|
else
|
|
NFCHECK("Can't send key %u to field %d", key, to);
|
|
#endif
|
|
}
|
|
}
|
|
else
|
|
{
|
|
const int gr = -to;
|
|
for (int i = fields()-1; i >= 0; i--)
|
|
{
|
|
TMask_field& campo = fld(i);
|
|
if (campo.in_group(gr))
|
|
campo.on_key(key);
|
|
}
|
|
}
|
|
}
|
|
|
|
// @doc EXTERNAL
|
|
|
|
// @mfunc Permette di mandare un handler ad controllo o ad una maschera
|
|
void TMask::set_handler(
|
|
short fld_id, // @parm Identificatere del campo che deve ricevere l'handler
|
|
CONTROL_HANDLER handler) // @parm Handler da spedire al campo
|
|
// @parm MASK_HANDLER | handler | Handler da spedire alla maschera
|
|
|
|
// @syntax set_handler(short fld_id, CONTROL_HANDLER handler);
|
|
// @syntax set_handler(MASK_HANDLER handler);
|
|
//
|
|
// @comm Nel primo caso viene mandato un <t CONTROL_HANDLER> al campo indicato
|
|
// da <p fld_id>, mentre nel secondo viene mandato un <t MASK_HANDLER>
|
|
// alla maschera corrente
|
|
|
|
{
|
|
TMask_field& f = field(fld_id);
|
|
CHECKD(f.is_operable(), "Can't set an handler to non-operable field ", fld_id);
|
|
((TOperable_field&)f).set_handler(handler);
|
|
}
|
|
|
|
void TMask::set_handler(MASK_HANDLER handler)
|
|
{
|
|
_handler = handler;
|
|
}
|
|
|
|
// @doc EXTERNAL
|
|
|
|
// @mfunc Aggiunge runtime un campo testo alla maschera
|
|
//
|
|
// @rdesc Ritorna l'handle del campo creato
|
|
TMask_field& TMask::add_static (
|
|
short id, // @parm Numero identificatore del campo da aggiungere
|
|
int page, // @parm Pagina nel quale aggiungere il campo
|
|
const char* prompt, // @parm Prompt del campo
|
|
int x, // @parm Coordinata x (in caratteri)
|
|
int y, // @parm Coordinata y (in caratteri)
|
|
const char* flags) // @parm Flag di controllo del campo (deafult "")
|
|
|
|
// @xref <mf TMask::add_string> <mf TMask::add_number> <mf TMask::add_date>
|
|
// <mf TMask::add_button> <mf TMask::add_radio> <mf TMask::add_memo>
|
|
{
|
|
TText_field* f = new TText_field(this);
|
|
f->construct(id, prompt, x, y, 0, _pagewin[page], flags);
|
|
add_field(f);
|
|
return *f;
|
|
}
|
|
|
|
// @doc EXTERNAL
|
|
|
|
// @mfunc Aggiunge runtime un campo stringa alla maschera
|
|
//
|
|
// @rdesc Ritorna l'handle del campo creato
|
|
TEdit_field& TMask::add_string (
|
|
short id, // @parm Numero identificatore del campo da aggiungere
|
|
int page, // @parm Pagina nel quale aggiungere il campo
|
|
const char* prompt, // @parm Prompt del campo
|
|
int x, // @parm Coordinata x (in caratteri)
|
|
int y, // @parm Coordinata y (in caratteri)
|
|
int dim, // @parm Lunghezza del campo sulla maschera
|
|
const char* flags, // @parm Flag di controllo del campo (defailt "")
|
|
int width) // @parm Lunghezza totale del campo stringa (default 0)
|
|
|
|
// @xref <mf TMask::add_static> <mf TMask::add_number> <mf TMask::add_date>
|
|
// <mf TMask::add_button> <mf TMask::add_radio> <mf TMask::add_memo>
|
|
{
|
|
TEdit_field* f = new TEdit_field(this);
|
|
f->construct(id, prompt, x, y, dim, _pagewin[page], flags, width);
|
|
add_field(f);
|
|
return *f;
|
|
}
|
|
|
|
// @doc EXTERNAL
|
|
|
|
// @mfunc Aggiunge runtime un campo bottone alla maschera
|
|
//
|
|
// @rdesc Ritorna l'handle del campo creato
|
|
TButton_field& TMask::add_button (
|
|
short id, // @parm Numero identificatore del campo da aggiungere
|
|
int page, // @parm Pagina nel quale aggiungere il campo
|
|
const char* prompt, // @parm Prompt del campo
|
|
int x, // @parm Coordinata x (in caratteri)
|
|
int y, // @parm Coordinata y (in caratteri)
|
|
int dx, // @parm Larghezza del campo (in caratteri, default 9)
|
|
int dy, // @parm Altezza del campo (in caratteri, default 1)
|
|
const char* flags, // @parm Flag di controllo del campo (default "")
|
|
short bmpup, // @parm Icona normale
|
|
short bmpdn) // @parm Icona premuta
|
|
|
|
// @xref <mf TMask::add_static> <mf TMask::add_string> <mf TMask::add_number>
|
|
// <mf TMask::add_date> <mf TMask::add_radio> <mf TMask::add_memo>
|
|
{
|
|
TButton_field* f = new TButton_field(this);
|
|
f->construct(id, prompt, x, y, dy, _pagewin[page], flags, dx);
|
|
if (bmpup > 0)
|
|
f->set_bmp(bmpup, bmpdn);
|
|
add_field(f);
|
|
return *f;
|
|
}
|
|
|
|
// @doc EXTERNAL
|
|
|
|
// @mfunc Aggiunge runtime un campo boolean alla maschera
|
|
//
|
|
// @rdesc Ritorna il descrittore del campo aggiunto
|
|
TBoolean_field& TMask::add_boolean (
|
|
short id, // @parm Numero identificatore del campo da aggiungere
|
|
int page, // @parm Pagina nel quale aggiungere il campo
|
|
const char* prompt, // @parm Prompt del campo
|
|
int x, // @parm Coordinata x (in caratteri)
|
|
int y, // @parm Coordinata y (in caratteri)
|
|
const char* flags) // @parm Flag di controllo del campo (default "")
|
|
|
|
// @xref <mf TMask::add_static> <mf TMask::add_string> <mf TMask::add_number>
|
|
// <mf TMask::add_date> <mf TMask::add_radio> <mf TMask::add_memo>
|
|
{
|
|
TBoolean_field* f = new TBoolean_field(this);
|
|
f->construct(id, prompt, x, y, strlen(prompt), _pagewin[page], flags);
|
|
add_field(f);
|
|
return *f;
|
|
}
|
|
|
|
// @doc EXTERNAL
|
|
|
|
// @mfunc Aggiunge runtime un campo numerico alla maschera
|
|
//
|
|
// @rdesc Ritorna l'handle del campo creato
|
|
TReal_field& TMask::add_number (
|
|
short id, // @parm Numero identificatore del campo da aggiungere
|
|
int page, // @parm Pagina nel quale aggiungere il campo
|
|
const char* prompt, // @parm Prompt del campo
|
|
int x, // @parm Coordinata x (in caratteri)
|
|
int y, // @parm Coordinata y (in caratteri)
|
|
int dim, // @parm Lunghezza del campo sulla maschera
|
|
const char* flags, // @parm Flag di controllo del campo (default "")
|
|
int ndec) // @parm Numero di decimali (default 0)
|
|
|
|
// @xref <mf TMask::add_static> <mf TMask::add_string> <mf TMask::add_date>
|
|
// <mf TMask::add_button> <mf TMask::add_radio> <mf TMask::add_memo>
|
|
{
|
|
TReal_field* f = new TReal_field(this);
|
|
f->construct(id, prompt, x, y, dim, _pagewin[page], flags, ndec);
|
|
add_field(f);
|
|
return *f;
|
|
}
|
|
|
|
// @doc EXTERNAL
|
|
|
|
// @mfunc Aggiunge runtime un campo importo alla maschera
|
|
//
|
|
// @rdesc Ritorna l'handle del campo creato
|
|
TCurrency_field& TMask::add_currency (
|
|
short id, // @parm Numero identificatore del campo da aggiungere
|
|
int page, // @parm Pagina nel quale aggiungere il campo
|
|
const char* prompt, // @parm Prompt del campo
|
|
int x, // @parm Coordinata x (in caratteri)
|
|
int y, // @parm Coordinata y (in caratteri)
|
|
int dim, // @parm Lunghezza del campo sulla maschera
|
|
const char* flags, // @parm Flag di controllo del campo (default "")
|
|
short driver) // @parm Numero di decimali (default 0)
|
|
|
|
// @xref <mf TMask::add_static> <mf TMask::add_string> <mf TMask::add_date>
|
|
// <mf TMask::add_button> <mf TMask::add_radio> <mf TMask::add_memo>
|
|
{
|
|
TCurrency_field* f = new TCurrency_field(this);
|
|
f->construct(id, prompt, x, y, dim, _pagewin[page], flags, 0);
|
|
if (driver != 0)
|
|
f->add_driver(driver);
|
|
add_field(f);
|
|
return *f;
|
|
}
|
|
|
|
// @doc EXTERNAL
|
|
|
|
// @mfunc Aggiunge runtime un campo data alla maschera
|
|
//
|
|
// @rdesc Ritorna l'handle del campo creato
|
|
TDate_field& TMask::add_date (
|
|
short id, // @parm Numero identificatore del campo da aggiungere
|
|
int page, // @parm Pagina nel quale aggiungere il campo
|
|
const char* prompt, // @parm Prompt del campo
|
|
int x, // @parm Coordinata x (in caratteri)
|
|
int y, // @parm Coordinata y (in caratteri)
|
|
const char* flags) // @parm Flag di controllo del campo (default "")
|
|
|
|
// @xref <mf TMask::add_static> <mf TMask::add_string> <mf TMask::add_number>
|
|
// <mf TMask::add_button> <mf TMask::add_radio> <mf TMask::add_memo>
|
|
{
|
|
TDate_field* f = new TDate_field(this);
|
|
f->construct(id, prompt, x, y, 10, _pagewin[page], flags);
|
|
add_field(f);
|
|
return *f;
|
|
}
|
|
|
|
// @doc EXTERNAL
|
|
|
|
// @mfunc Aggiunge runtime un campo lista alla maschera
|
|
//
|
|
// @rdesc Ritorna l'handle del campo creato
|
|
TList_field& TMask::add_list (
|
|
short id, // @parm Numero identificatore del campo da aggiungere
|
|
int page, // @parm Pagina nel quale aggiungere il campo
|
|
const char* prompt, // @parm Prompt del campo
|
|
int x, // @parm Coordinata x (in caratteri)
|
|
int y, // @parm Coordinata y (in caratteri)
|
|
int dim, // @parm Lunghezza del campo sulla maschera
|
|
const char* flags, // @parm Flag di controllo del campo (default "")
|
|
const char* codes, // @parm tokenstring con i codici (NULL def.)
|
|
const char* items) // @parm tokenstring con gli items (NULL def.)
|
|
|
|
// @xref <mf TMask::add_static> <mf TMask::add_number> <mf TMask::add_date>
|
|
// <mf TMask::add_button> <mf TMask::add_radio> <mf TMask::add_memo>
|
|
{
|
|
TList_field* f = new TList_field(this);
|
|
f->construct(id, prompt, x, y, dim, _pagewin[page], flags);
|
|
f->replace_items(codes,items);
|
|
add_field(f);
|
|
return *f;
|
|
}
|
|
|
|
// @doc EXTERNAL
|
|
|
|
// @mfunc Aggiunge runtime un campo radio button alla maschera
|
|
//
|
|
// @rdesc Ritorna l'handle del campo creato
|
|
TRadio_field& TMask::add_radio(
|
|
short id, // @parm Numero identificatore del campo da aggiungere
|
|
int page, // @parm Pagina nel quale aggiungere il campo
|
|
const char* prompt, // @parm Prompt del campo
|
|
int x, // @parm Coordinata x (in caratteri)
|
|
int y, // @parm Coordinata y (in caratteri)
|
|
int dx, // @parm Larghezza del campo (in caratteri)
|
|
const char* codes, // @parm Array di codici delle voci
|
|
const char* items, // @parm Array di prompt delle voci
|
|
const char* flags) // @parm Flag di controllo del campo (default "")
|
|
|
|
// @xref <mf TMask::add_static> <mf TMask::add_string> <mf TMask::add_number>
|
|
// <mf TMask::add_date> <mf TMask::add_button> <mf TMask::add_memo>
|
|
{
|
|
TRadio_field* f = new TRadio_field(this);
|
|
f->replace_items(codes, items);
|
|
f->construct(id, prompt, x, y, dx, _pagewin[page], flags, dx);
|
|
add_field(f);
|
|
return *f;
|
|
}
|
|
|
|
|
|
// @doc EXTERNAL
|
|
|
|
// @mfunc Aggiunge runtime un campo zoom alla maschera
|
|
//
|
|
// @rdesc Ritorna l'handle del campo creato
|
|
TZoom_field& TMask::add_zoom (
|
|
short id, // @parm Numero identificatore del campo da aggiungere
|
|
int page, // @parm Pagina nel quale aggiungere il campo
|
|
const char* prompt, // @parm Prompt del campo
|
|
int x, // @parm Coordinata x (in caratteri)
|
|
int y, // @parm Coordinata y (in caratteri)
|
|
int dim, // @parm Lunghezza del campo sulla maschera
|
|
const char* flags, // @parm Flag di controllo del campo (defailt "")
|
|
int width) // @parm Lunghezza totale del campo stringa (default 0)
|
|
|
|
// @xref <mf TMask::add_static> <mf TMask::add_number> <mf TMask::add_date>
|
|
// <mf TMask::add_button> <mf TMask::add_radio> <mf TMask::add_memo>
|
|
{
|
|
TZoom_field* f = new TZoom_field(this);
|
|
f->construct(id, prompt, x, y, dim, _pagewin[page], flags, width);
|
|
add_field(f);
|
|
return *f;
|
|
}
|
|
|
|
// @doc EXTERNAL
|
|
|
|
// @mfunc Aggiunge runtime un campo memo alla maschera
|
|
//
|
|
// @rdesc Ritorna l'handle del campo creato
|
|
TMemo_field& TMask::add_memo(
|
|
short id, // @parm Numero identificatore del campo da aggiungere
|
|
int page, // @parm Pagina nel quale aggiungere il campo
|
|
const char* prompt, // @parm Prompt del campo
|
|
int x, // @parm Coordinata x (in caratteri)
|
|
int y, // @parm Coordinata y (in caratteri)
|
|
int dx, // @parm Larghezza del campo (in caratteri, deafilt 78)
|
|
int dy, // @parm Altezza del campo (in caratteri, default 4)
|
|
const char* flags) // @parm Flag di controllo del campo (default "")
|
|
|
|
// @xref <mf TMask::add_static> <mf TMask::add_string> <mf TMask::add_number>
|
|
// <mf TMask::add_date> <mf TMask::add_button> <mf TMask::add_radio>
|
|
{
|
|
TMemo_field* f = new TMemo_field(this);
|
|
f->construct(id, prompt, x, y, dy, _pagewin[page], flags, dx);
|
|
add_field(f);
|
|
return *f;
|
|
}
|
|
|
|
TTree_field& TMask::add_tree (
|
|
short id, // @parm Numero identificatore del campo da aggiungere
|
|
int page, // @parm Pagina nel quale aggiungere il campo
|
|
int x, // @parm Coordinata x (in caratteri)
|
|
int y, // @parm Coordinata y (in caratteri)
|
|
int dx, // @parm Larghezza del campo sulla maschera
|
|
int dy, // @parm Altezza del campo sulla maschera
|
|
const char* flags)// @parm Flag di controllo del campo (default "")
|
|
{
|
|
TTree_field* f = new TTree_field(this);
|
|
f->construct(id, "", x, y, dy, _pagewin[page], flags, dx);
|
|
add_field(f);
|
|
return *f;
|
|
}
|
|
|
|
TGroup_field& TMask::add_groupbox (
|
|
short id, // @parm Numero identificatore del campo da aggiungere
|
|
int page, // @parm Pagina nel quale aggiungere il campo
|
|
const char* prompt, // @parm Prompt del campo
|
|
int x, // @parm Coordinata x (in caratteri)
|
|
int y, // @parm Coordinata y (in caratteri)
|
|
int dx, // @parm Larghezza del campo sulla maschera
|
|
int dy, // @parm Altezza del campo sulla maschera
|
|
const char* flags)// @parm Flag di controllo del campo (default "")
|
|
{
|
|
TGroup_field* f = new TGroup_field(this);
|
|
f->construct(id, prompt, x, y, dy, _pagewin[page], flags, dx);
|
|
add_field(f);
|
|
return *f;
|
|
}
|
|
|
|
|
|
// @doc EXTERNAL
|
|
|
|
// @mfunc Salva i valori dei campi della maschera sul file di salvataggio
|
|
//
|
|
// @rdesc Ritorna il risultato dell'operazione:
|
|
//
|
|
// @flag TRUE | Se l'operazione e' avvenuta corretamente
|
|
// @flag FALSE | Se non si riesce a creare il file di salvataggio
|
|
bool TMask::save(
|
|
bool append) const // @parm Indica se creare il file o appendere (TRUE) le informazioni
|
|
// ad uno gia' esistente (FALSE, default).
|
|
|
|
{
|
|
FILE* f = fopen(_workfile, append ? "a" : "w");
|
|
|
|
if (f == NULL)
|
|
return yesnofatal_box("Non posso aprire %s ", (const char*) _workfile);
|
|
|
|
const int max = fields();
|
|
for (int i = 0; i < max; i++)
|
|
{
|
|
TMask_field& c = fld(i);
|
|
if (c.is_editable())
|
|
fprintf(f, "%d|%s\n", c.dlg(), (const char*)c.get());
|
|
}
|
|
fprintf(f, "[EOM]\n");
|
|
fclose(f);
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
// @doc EXTERNAL
|
|
|
|
// @mfunc Legge i valori dei campi della maschera da file di salvataggioo
|
|
//
|
|
// @rdesc Ritorna il risultato dell'operazione:
|
|
//
|
|
// @flag TRUE | Se l'operazione e' avvenuta corretamente
|
|
// @flag FALSE | Se non si riesce a leggere il file di salvataggio
|
|
bool TMask::load(
|
|
bool reset) // @parm Indica la posizione di lettura del file:
|
|
//
|
|
// @flag TRUE | Comincia la lettura dell'inizio
|
|
// @flag FALSE | Comincia la lettura dalla posizione corrente dell'offset
|
|
|
|
{
|
|
FILE* f = fopen(_workfile, "r");
|
|
|
|
if (f == NULL) return FALSE;
|
|
if (reset) _lastpos = 0;
|
|
fseek(f, _lastpos, SEEK_SET);
|
|
TToken_string t(256);
|
|
while (fgets((char*)(const char*)t, t.size(), f) != NULL && t != "[EOM]")
|
|
{
|
|
if (t.not_empty())
|
|
{
|
|
t.cut(t.len() - 1);
|
|
const int pos = id2pos(t.get_int(0));
|
|
if (pos >= 0) fld(pos).set(t.get());
|
|
}
|
|
}
|
|
_lastpos = ftell(f);
|
|
fclose(f);
|
|
return TRUE;
|
|
}
|
|
|
|
// @doc EXTERNAL
|
|
|
|
// @mfunc Copia i valori dei campi dalla maschera <p m>
|
|
//
|
|
void TMask::copy_values(
|
|
const TMask& m) // @parm Maschera sorgente
|
|
|
|
{
|
|
reset();
|
|
const int nfields = fields();
|
|
for (int i = 0; i < nfields; i++)
|
|
{
|
|
TMask_field& dest_field = fld( i );
|
|
|
|
if (dest_field.is_editable() )
|
|
{
|
|
const int pos = m.id2pos(dest_field.dlg());
|
|
if (pos >= 0)
|
|
{
|
|
const TMask_field& source_field = m.fld(pos);
|
|
dest_field.set( source_field.get( ) );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void TMask::make_profile_name(TFilename& f) const
|
|
{
|
|
f =::firm2dir(-1); // Directory dati
|
|
f.add("config"); // Directory config
|
|
f.add(source_file().name()); // Nome Maschera
|
|
f.ext("ini"); // Estensione
|
|
}
|
|
|
|
int TMask::save_profile(int num, const char* desc) const
|
|
{
|
|
TFilename prof;
|
|
make_profile_name(prof);
|
|
TConfig ini(prof, "Main");
|
|
|
|
if (num == 0)
|
|
num = ini.get_int(user());
|
|
if (num <= 0)
|
|
{
|
|
TString_array p;
|
|
TBit_array b(256);
|
|
b.set(255); b.set(); b.reset(0);
|
|
ini.list_paragraphs(p);
|
|
FOR_EACH_ARRAY_ROW_BACK(p, r, row)
|
|
{
|
|
num = atoi(*row);
|
|
if (num > 0)
|
|
b.reset(num);
|
|
}
|
|
num = int(b.first_one());
|
|
}
|
|
|
|
TString16 para; para << num;
|
|
ini.set(user(), para);
|
|
|
|
TString description = desc;
|
|
if (ini.set_paragraph(para))
|
|
{
|
|
if (description.blank())
|
|
description = ini.get("Description");
|
|
ini.remove_all();
|
|
}
|
|
else
|
|
{
|
|
if (description.blank())
|
|
description << "Profilo standard per " << user();
|
|
}
|
|
ini.set("Description", description);
|
|
|
|
TString16 name;
|
|
|
|
for (int i = 0; i < fields(); i++)
|
|
{
|
|
TMask_field& f = fld(i);
|
|
if (f.is_loadable() && f.get_default().empty())
|
|
{
|
|
name.format("F_%d", f.dlg());
|
|
if (f.is_sheet())
|
|
{
|
|
TSheet_field& s = (TSheet_field&)f;
|
|
FOR_EACH_SHEET_ROW(s, r, row)
|
|
ini.set(name, *row, NULL, TRUE, r);
|
|
}
|
|
else
|
|
{
|
|
if (!f.is_firm())
|
|
ini.set(name, f.get());
|
|
}
|
|
}
|
|
}
|
|
return num;
|
|
}
|
|
|
|
int TMask::load_profile(int num, bool reset)
|
|
{
|
|
TFilename prof;
|
|
make_profile_name(prof);
|
|
|
|
TConfig ini(prof, "Main");
|
|
if (num <= 0)
|
|
num = ini.get_int(user());
|
|
else
|
|
ini.set(user(), num);
|
|
|
|
TString16 name; name << num;
|
|
TAssoc_array& var = ini.list_variables(name);
|
|
|
|
for (int pos = fields()-1; pos >= 0; pos--)
|
|
{
|
|
TMask_field& f = fld(pos);
|
|
if (f.is_loadable() && f.get_default().empty())
|
|
{
|
|
name.format("F_%d", f.dlg());
|
|
if (reset || var.objptr(name) != NULL)
|
|
{
|
|
if (f.is_sheet())
|
|
{
|
|
TSheet_field& sf = (TSheet_field&)f;
|
|
sf.destroy();
|
|
for (int r = 0; ini.exist(name,r); r++)
|
|
sf.row(r) = ini.get(name, NULL, r);
|
|
sf.force_update();
|
|
}
|
|
else
|
|
{
|
|
if (!f.is_firm())
|
|
f.set(ini.get(name));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return num;
|
|
}
|
|
|
|
const char* TMask::get_caption(TString& str) const
|
|
{
|
|
char* title = str.get_buffer(128);
|
|
xvt_vobj_get_title(_pagewin[0], title, str.size());
|
|
return title;
|
|
}
|
|
|
|
void TMask::set_caption(const char* c)
|
|
{
|
|
TToken_string captions(c);
|
|
for (int p = 0; p < _pages; p++)
|
|
{
|
|
const char* cap = captions.get();
|
|
if (cap == NULL) cap = captions.get(0);
|
|
xvt_vobj_set_title(_pagewin[p], (char*)cap);
|
|
|
|
const int pos = id2pos(DLG_PAGETAGS + 100 * p);
|
|
if (pos >= 0)
|
|
{
|
|
TPage_field& tag = (TPage_field&)fld(pos);
|
|
tag.set_prompt(c);
|
|
}
|
|
}
|
|
}
|
|
|
|
void TMask::post_error_message(const char* msg, int sev)
|
|
{
|
|
CHECK(sev > 0 && msg, "Bad error message posted");
|
|
if (_error_severity > 0) // C'e' gia' un messaggio d'errore in coda
|
|
on_idle();
|
|
_error_message = msg;
|
|
_error_severity = sev;
|
|
}
|
|
|
|
// @doc INTERNAL
|
|
|
|
// @mfunc costruttore di copia
|
|
TTimed_box::TTimed_box(const char * header,const char * message,int seconds,short button_id,int x,int y)
|
|
: TMask(header,1,x,y)
|
|
{
|
|
// costruisce una maschera run time
|
|
add_memo(FIRST_FIELD, 0, "", 1, 0,-1,-3);
|
|
set(FIRST_FIELD, message);
|
|
|
|
// setta il timer per l'evento
|
|
_timer_delay=seconds *1000+1;
|
|
_timer_id=XVT_TIMER_ERROR;
|
|
_button_id=button_id;
|
|
}
|
|
|
|
void TTimed_box::start_run()
|
|
{
|
|
if (_timer_id!=XVT_TIMER_ERROR)
|
|
xvt_timer_destroy(_timer_id);
|
|
_timer_id=xvt_timer_create(win(),_timer_delay);
|
|
TMask::start_run();
|
|
}
|
|
|
|
void TTimed_box::handler(WINDOW win, EVENT* ep)
|
|
{
|
|
if (ep->type == E_TIMER && ep->v.timer.id==_timer_id)
|
|
send_key(K_SPACE, _button_id);
|
|
TMask::handler(win, ep);
|
|
}
|
|
|
|
TTimed_box::~TTimed_box()
|
|
{
|
|
if (_timer_id != XVT_TIMER_ERROR)
|
|
xvt_timer_destroy(_timer_id);
|
|
}
|
|
|
|
TTimed_breakbox::TTimed_breakbox(const char * message,int seconds,int x,int y)
|
|
: TTimed_box("Richiesta di interruzione",message,seconds,DLG_OK,x,y)
|
|
{
|
|
add_button(DLG_CANCEL, 0, TR("Interrompi"), -22, -1, 12, 2,"",0);
|
|
add_button(DLG_OK, 0, TR("Riprova"), -12, -1, 12, 2,"",0);
|
|
}
|
|
|
|
TTimed_breakbox::~TTimed_breakbox()
|
|
{}
|
|
|
|
// @doc INTERNAL
|
|
|
|
// @mfunc costruttore di copia
|
|
TYesnoallnone_box::TYesnoallnone_box(const char * message, int default_key)
|
|
: TMask("Richiesta",1,40,8)
|
|
|
|
{
|
|
// costruisce una maschera run time
|
|
add_memo(FIRST_FIELD, 0, "", 1, 0,-1,-3);
|
|
set(FIRST_FIELD, message);
|
|
disable(FIRST_FIELD);
|
|
add_button(DLG_OK, 0, TR("Tutti"), -14, -1, 8, 2,"",0);
|
|
add_button(FIRST_FIELD+1, 0, TR("Si"), -24, -1, 8, 2,"",0).set_exit_key(K_YES);
|
|
add_button(FIRST_FIELD+2, 0, TR("No"), -34, -1, 8, 2,"",0).set_exit_key(K_NO);
|
|
add_button(DLG_CANCEL, 0, TR("Nessuno"), -44, -1, 8, 2,"",0);
|
|
switch (default_key)
|
|
{
|
|
case K_ENTER:
|
|
first_focus(DLG_OK); break;
|
|
case K_ESC:
|
|
first_focus(DLG_CANCEL); break;
|
|
case K_NO:
|
|
first_focus(FIRST_FIELD+2); break;
|
|
default:
|
|
first_focus(FIRST_FIELD+1);
|
|
}
|
|
}
|
|
|
|
|
|
TYesnoallnone_box::~TYesnoallnone_box()
|
|
{}
|