controls.cpp Abbassati legermente i checkbox mask.cpp Corretto controllo sulle maschere multipagina non a tutto schermo maskfld.cpp Corretto passaggio al campo successivo doppo un tasto F9 msksheet.cpp Corretta gestione del messaggio di inizializzazione in modo da cercare di andare sempre sulla prima riga progind.cpp Corretto calcolo della percentuale (arrotondato e non troncato) relapp.h Reso pubblico il metoto TRelation_application::lnflag() const git-svn-id: svn://10.65.10.50/trunk@3573 c028cbd2-c16b-5b4b-a496-9718f37d4682
1763 lines
44 KiB
C++
Executable File
1763 lines
44 KiB
C++
Executable File
#include <time.h>
|
|
#include <stdio.h>
|
|
|
|
#if XVT_OS == XVT_OS_WIN || XVT_OS == XVT_OS_NT
|
|
#define WIN32_LEAN_AND_MEAN
|
|
#define STRICT
|
|
#include <windows.h>
|
|
#endif
|
|
|
|
#include <applicat.h>
|
|
#include <controls.h>
|
|
#include <browfile.h>
|
|
#include <colors.h>
|
|
#include <msksheet.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;
|
|
_sheets = _pages = 0; // Azzera numero pagine e sheets
|
|
_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
|
|
_exchange = 1.0; // Il cambio per la valuta e' la lira
|
|
|
|
_error_severity = 0;
|
|
_msg_field = 0;
|
|
_msg_key = 0;
|
|
_test_fld = -1;
|
|
_last_test = -1;
|
|
|
|
memset(_pagewin, 0, sizeof(_pagewin));
|
|
}
|
|
|
|
|
|
TMask::TMask(const char* title, int pages, int cols, int rows,
|
|
int xpos, int ypos)
|
|
{
|
|
init_mask();
|
|
for (_pages = 0; _pages < pages; _pages++)
|
|
_pagewin[_pages] = create_interface(NULL_WIN, xpos, ypos,
|
|
cols, rows, title, this, pages > 1);
|
|
}
|
|
|
|
// @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
|
|
{
|
|
if (max <= 0) max = MAX_PAGES;
|
|
|
|
_source_file = name;
|
|
_source_file.ext(MASK_EXT);
|
|
_source_file.lower();
|
|
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;
|
|
|
|
for (int i = 0; i < num; i++)
|
|
{
|
|
while (scanner.ok())
|
|
if (scanner.line() == "ENDMASK") break;
|
|
}
|
|
|
|
init_mask();
|
|
|
|
TToken_string captions(80);
|
|
|
|
main_app().begin_wait();
|
|
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);
|
|
|
|
TString title(80);
|
|
xvt_vobj_get_title(w, (char*)(const char*)title, 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", name);
|
|
|
|
if (_pages > 1 || toolwin())
|
|
add_tag_buttons(captions);
|
|
|
|
if (num == 0)
|
|
_total_time = clock()-start_t;
|
|
|
|
main_app().end_wait();
|
|
}
|
|
|
|
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]);
|
|
|
|
_field.add(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("Pag.");
|
|
tags << p;
|
|
}
|
|
add_tag_buttons(tags);
|
|
}
|
|
|
|
TMask::TMask(const char* maskname, int num, int max)
|
|
{
|
|
if (maskname && *maskname)
|
|
read_mask(maskname, num, max);
|
|
}
|
|
|
|
|
|
TMask::~TMask()
|
|
{
|
|
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 = get_focus_id(win());
|
|
if (focus > 0 )
|
|
((TMask *)this)->_focus = id2pos(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)
|
|
{
|
|
const int pos = id2pos(id);
|
|
CHECKD(pos >= 0, "Can't set focus to field ", id);
|
|
_focus = pos;
|
|
if (is_open())
|
|
{
|
|
const TMask_field& f = fld(pos);
|
|
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);
|
|
_focus = pos;
|
|
}
|
|
|
|
bool TMask::can_be_closed() const
|
|
{
|
|
bool ok = TRUE;
|
|
if (is_running() && (edit_mode() || insert_mode()) && dirty())
|
|
ok = yesno_box("Annullare i dati inseriti?");
|
|
return ok;
|
|
}
|
|
|
|
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)
|
|
{
|
|
load_checks();
|
|
|
|
for (int i = 0; i < max; i++)
|
|
{
|
|
TMask_field& f = fld(i);
|
|
if (f.dirty() <= TRUE)
|
|
{
|
|
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 (query_mode() && f.is_edit() && f.in_key(1) &&
|
|
!f.automagic() && !f.empty())
|
|
{
|
|
f.set_dirty(TRUE);
|
|
}
|
|
else
|
|
{
|
|
if (f.dirty() == TRUE)
|
|
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_kind_of(CLASS_SHEET_FIELD));
|
|
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 )
|
|
{
|
|
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)
|
|
{
|
|
const int MAX_FIELDS = 256;
|
|
static byte positions[MAX_FIELDS]; // 100 <= id < MAX_FIELDS
|
|
const int max = fields();
|
|
|
|
const int j = id-100;
|
|
int pos = -1;
|
|
if (j >= 0 && j < MAX_FIELDS) // Try using cache
|
|
{
|
|
pos = positions[j];
|
|
if (pos >= 0 && pos < max)
|
|
{
|
|
const TMask_field& f = fld(pos);
|
|
if (f.dlg() == id) // Mask could have been changed!
|
|
return pos;
|
|
}
|
|
}
|
|
|
|
for (pos = 0; pos < max; pos++) // Standard linear search
|
|
{
|
|
const TMask_field& f = fld(pos);
|
|
if (f.dlg() == id)
|
|
{
|
|
if (j >= 0 && j < MAX_FIELDS) // Store position for the next time
|
|
positions[j] = pos;
|
|
return pos;
|
|
}
|
|
}
|
|
|
|
return -1; // Not found!
|
|
}
|
|
|
|
|
|
TMask_field& TMask::field(short id) const
|
|
{
|
|
int pos = id2pos(id);
|
|
|
|
#ifdef DBG
|
|
if (pos < 0)
|
|
{
|
|
yesnofatal_box("Il campo %d non esiste", id);
|
|
pos = 0;
|
|
}
|
|
#endif
|
|
|
|
return fld(pos);
|
|
}
|
|
|
|
|
|
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;
|
|
}
|
|
|
|
|
|
// @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();
|
|
for (int 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 = 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) return FALSE;
|
|
}
|
|
|
|
return TWindow::stop_run(key);
|
|
}
|
|
|
|
void TMask::on_button(short)
|
|
{
|
|
/* Non devo fare niente !!! non essendo una TWindow */
|
|
}
|
|
|
|
// @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:
|
|
#if XVT_OS == XVT_OS_WIN || XVT_OS == XVT_OS_NT
|
|
if (fexist("prassi.hlp"))
|
|
{
|
|
struct MULTIGUY
|
|
{
|
|
UINT mkSize;
|
|
BYTE mkKeylist;
|
|
char mkKeyphrase[16];
|
|
} mk;
|
|
|
|
TFilename topic(source_file()); topic.ext("");
|
|
mk.mkSize = sizeof(MULTIGUY);
|
|
mk.mkKeylist = 'M';
|
|
strcpy(mk.mkKeyphrase, topic);
|
|
|
|
TFilename hlp("prassi.hlp");
|
|
const TString16 mod(topic.left(2));
|
|
if (mod != "ba") hlp.insert(mod, 0);
|
|
|
|
HWND hwnd = (HWND)xvt_vobj_get_attr(TASK_WIN, ATTR_NATIVE_WINDOW);
|
|
WinHelp(hwnd, hlp, HELP_MULTIKEY, (DWORD)&mk);
|
|
next_page(0);
|
|
}
|
|
#endif
|
|
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;
|
|
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;
|
|
}
|
|
|
|
|
|
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 == "ME") return new TMemo_field(this);
|
|
if (k == "ZO") return new TZoom_field(this);
|
|
if (k == "BR") return new TBrowsefile_field(this);
|
|
if (k == "SP")
|
|
{
|
|
_sheets++;
|
|
return new TSheet_field(this);
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
// @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;
|
|
|
|
TString title(scanner.string());
|
|
|
|
RCT r;
|
|
if (toolwin())
|
|
{
|
|
scanner.line();
|
|
xvt_rect_set(&r, 0, 0, 0, tooly);
|
|
}
|
|
else
|
|
{
|
|
scanner.rectangle(r);
|
|
if (toolbar)
|
|
{
|
|
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())
|
|
{
|
|
w = create_interface(NULL_WIN, 0, r.top, 0, toolbar ? 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);
|
|
#ifdef DBG
|
|
if (f == NULL)
|
|
{
|
|
const int f = fields();
|
|
TString e("Unknown control at position "); e << f;
|
|
if (f > 0) e << ".\nLast good one was " << fld(f-1).dlg() << ": " << fld(f-1).prompt();
|
|
yesnofatal_box(e);
|
|
while (scanner.popkey() != "EN");
|
|
}
|
|
#endif
|
|
|
|
if (f != NULL)
|
|
{
|
|
const long start = clock();
|
|
|
|
f->construct(scanner, w);
|
|
_field.add(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());
|
|
}
|
|
|
|
if (_focus >= 0)
|
|
{
|
|
TMask_field& ff = fld(_focus);
|
|
if (ff.active())
|
|
ff.highlight();
|
|
}
|
|
|
|
TWindow::set_focus();
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
long TMask::get_long(short fld_id) const
|
|
{
|
|
const TString& s = field(fld_id).get();
|
|
return atol(s);
|
|
}
|
|
|
|
bool TMask::get_bool(short fld_id) const
|
|
{
|
|
const TString& s = field(fld_id).get();
|
|
return s.not_empty();
|
|
}
|
|
|
|
real TMask::get_real(short fld_id) const
|
|
{
|
|
const TString& s = field(fld_id).get();
|
|
return real(s);
|
|
}
|
|
|
|
TDate TMask::get_date(short fld_id) const
|
|
{
|
|
const TString& s = field(fld_id).get();
|
|
return TDate(s);
|
|
}
|
|
|
|
// @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
|
|
bool 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 (hit && (f.active() || f.ghost()))
|
|
{
|
|
f.set_dirty();
|
|
f.on_hit();
|
|
}
|
|
}
|
|
|
|
void TMask::set(short fld_id, long n, bool hit)
|
|
{
|
|
char s[16];
|
|
sprintf(s, "%ld", n);
|
|
set(fld_id, s, hit);
|
|
}
|
|
|
|
void TMask::set(short fld_id, const real& n, bool hit)
|
|
{
|
|
CHECK(field(fld_id).is_kind_of(CLASS_REAL_FIELD), "Can't set a real value in a non-number field");
|
|
set(fld_id, n.string(), hit);
|
|
}
|
|
|
|
void TMask::set(short fld_id, const TDate& d, bool hit)
|
|
{
|
|
CHECK(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);
|
|
}
|
|
|
|
// @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 (-1 tutti i campi)
|
|
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();
|
|
}
|
|
|
|
|
|
byte TMask::num_keys() const
|
|
{
|
|
word max = 0;
|
|
for (int i = fields()-1; i >= 0; i--)
|
|
{
|
|
TMask_field& f = fld(i);
|
|
if (f.is_editable())
|
|
{
|
|
word k = ((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(
|
|
byte 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(
|
|
byte 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(int 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_editable())
|
|
((TEditable_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_editable())
|
|
{
|
|
TEditable_field& e = (TEditable_field&)f;
|
|
if (e.field() != NULL)
|
|
{
|
|
bool save = f.shown();
|
|
if (!save)
|
|
{
|
|
e.autoload(r);
|
|
save = f.empty();
|
|
}
|
|
if (save)
|
|
e.autosave(r);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void TMask::on_firm_change()
|
|
{
|
|
TString firm; firm << main_app().get_firm();
|
|
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
|
|
yesnofatal_box("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);
|
|
_field.add(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);
|
|
_field.add(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, defailt 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);
|
|
_field.add(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);
|
|
_field.add(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);
|
|
_field.add(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);
|
|
_field.add(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);
|
|
_field.add(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);
|
|
_field.add(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);
|
|
_field.add(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);
|
|
_field.add(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( ) );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
const char* TMask::get_caption() const
|
|
{
|
|
char* title = &__tmp_string[512];
|
|
xvt_vobj_get_title(_pagewin[0], title, 80);
|
|
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 EXTERNAL
|
|
|
|
// @mfunc Setta il valore attuale della valuta
|
|
void TMask::set_exchange(
|
|
bool show_value, // @parm Indica se il deve essere visibile l'importo in valuta
|
|
const real& n) // @parm Indica il cambio attuale della valuta
|
|
{
|
|
const real nuo = (n.sign() <= 0) ? _exchange : n;
|
|
|
|
main_app().begin_wait();
|
|
for (int i = fields()-1; i >= 0; i--)
|
|
{
|
|
TMask_field& f = fld(i);
|
|
if (f.is_operable())
|
|
{
|
|
TOperable_field& o = (TOperable_field&)f;
|
|
if (o.exchangeable() || o.is_kind_of(CLASS_SHEET_FIELD))
|
|
o.exchange(show_value, nuo);
|
|
}
|
|
}
|
|
|
|
_exchange = nuo; // Update current exchange
|
|
main_app().end_wait();
|
|
}
|
|
|
|
|