campo-sirio/include/mask.cpp

2773 lines
72 KiB
C++
Executable File
Raw Blame History

#include <xinclude.h>
#include <controls.h>
#include <config.h>
#include <browfile.h>
#include <colors.h>
#include <diction.h>
#include <msksheet.h>
#include <prefix.h>
#include <recarray.h>
#include <relation.h>
#include <statbar.h>
#include <toolfld.h>
#include <treectrl.h>
#include <urldefid.h>
#include <utility.h>
#include <user.h>
HIDDEN const char* const MASK_EXT = "msk";
HIDDEN BOOLEAN _bShowGrid = FALSE;
//////////////////////////////////////////////////////////
// TMask scanner
///////////////////////////////////////////////////////////
struct TScanner_win : public TObject
{
WINDOW _win;
RCT _rct;
TScanner_win(WINDOW w) : _win(w) { xvt_vobj_get_client_rect(w, &_rct); }
};
void TMask_scanner::push_win(WINDOW w)
{ _pages.push(new TScanner_win(w)); }
WINDOW TMask_scanner::peek_win() const
{ return ((const TScanner_win&)_pages.peek())._win; }
RCT TMask_scanner::peek_rct() const
{ return ((const TScanner_win&)_pages.peek())._rct; }
WINDOW TMask_scanner::pop_win()
{ return ((const TScanner_win&)_pages.pop())._win; }
TMask_scanner::TMask_scanner(const TFilename& n) : TScanner(n)
{}
//////////////////////////////////////////////////////////
// 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;
_toolwin = _toolbar = _notebook = _single = NULL_WIN;
memset(_pagewin, 0, sizeof(_pagewin)); // Azzero lista pagine
}
WINDOW TMask::page_win(int p) const
{
if (p >= MAX_PAGES)
return p == MAX_PAGES ? toolwin() : toolbar();
if (p >= 0 && p < _pages)
return _pagewin[p];
return p <= 0 ? win() : NULL_WIN;
}
WINDOW TMask::curr_win() const
{
return page_win(_page > 0 && _page < _pages ? _page : 0);
}
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();
if (pages > 1)
{
//WINDOW w = create_interface(parent, xpos, ypos, cols, rows, title, this);
//set_win(w); // Crea la pagina principale che ospitera' il notebook
const WIN_TYPE wt = (cols == 0) ? W_PLAIN : W_DOC;
const long wsf = WSF_INVISIBLE | WSF_NO_MENUBAR;
create(xpos, ypos, cols, rows, title, wsf, wt);
create_book(false); // Crea il notebook che ospitera' le pagine
for (int p = 1; p <= pages; p++)
{
WINDOW w = create_interface(notebook(), 0, 0, 0, 0, title, this);
insert_page(w, -1); // Aggiunge nuova pagina in fondo
}
}
else
{
WINDOW w = create_interface(parent, xpos, ypos, cols, rows, title, this);
insert_page(w, 0);
}
}
void TMask::set_locking(TBit_array& read_only, TToken_string& list, bool on)
{
if (list.find('*') >= 0)
{
if (on)
{
read_only.set(fields());
read_only.set();
}
else
read_only.reset();
}
else
{
FOR_EACH_TOKEN(list, fld)
{
const TFixed_string id(fld);
if (id[0] == '-' || id.ends_with("@")) // Gestione gruppi
{
const int grp = abs(atoi(fld));
FOR_EACH_MASK_FIELD((*this), pos, f)
{
if (f->in_group(grp))
read_only.set(pos, on);
}
}
else
{
const int pos = field2pos(fld);
if (pos >= 0)
read_only.set(pos, on);
}
}
}
}
// @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();
TMask_scanner scanner(_source_file);
if (num != 0)
_mask_num = num;
// Salta la maschera principale e quelle degli sheet precedenti a pie' pari
for (int i = 0; i < num; i++)
{
while (scanner.ok())
{
if (scanner.line().starts_with("ENDMASK"))
break;
}
}
init_mask();
while (scanner.ok())
{
const TString& key = scanner.popkey();
if (key.empty() || key == "EN")
break;
if (key == "PA")
{
read_page(scanner, false);
if (_pages >= max)
break;
} else
if (key == "TO")
read_page(scanner, true);
}
if (_pages <= 0)
fatal_box("Impossibile leggere la maschera %s : %d", (const char*)_source_file, num);
if (num == 0)
{
TFilename prof; make_profile_name(prof);
if (prof.exist())
{
// Costruisce la lista dei gruppi di appartenenza dell'utente
const TString_array& uag = user_and_groups();
TConfig ini(prof);
FOR_EACH_ARRAY_ROW_BACK(uag, c, rec)
{
TString utonto = rec->get(0);
utonto << "_Locks";
if (ini.set_paragraph(utonto))
{
TBit_array read_only;
TAuto_token_string lfields(ini.get("Lock"));
TAuto_token_string ufields(ini.get("Unlock"));
if (ufields.find("*")>=0)
{
set_locking(read_only, lfields, true);
}
else
{
set_locking(read_only, lfields, true);
set_locking(read_only, ufields, false);
}
FOR_EACH_MASK_FIELD((*this), j, f)
{
if (f->is_loadable())
{
const bool ro = read_only[j];
if (f->read_only() != ro)
f->set_read_only(ro);
}
}
}
}
TAssoc_array & defs = ini.list_variables("defaults");
FOR_EACH_ASSOC_STRING(defs, obj, key, str)
{
short id = atoi(key);
const int pos = id2pos(id);
if (pos >= 0 && fld(pos).is_operable())
fld(pos).set_default(str);
}
}
}
else
{
// Faccio una prima passata in questa occasione: tuttavia il ciclo
// verra' ripetuto nella load checks, nel caso ci siano campi aggiunti dinamicamente
FOR_EACH_MASK_FIELD((*this), i, f) if (f->is_edit())
((TEdit_field*)f)->test_drivers();
}
}
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 (f->is_sheet() && strncmp(_source_file.name(), "lv", 2) != 0)
{
for (short cid = 101; cid <= 110; cid++)
{
if (_position.objptr(cid) && f->parent() == field(cid).parent())
{
NFCHECK("Lo sheet %d mal sopporta la convivenza col campo %d", id, cid);
break;
}
}
}
if (_position.objptr(id))
{
if (id > DLG_QUIT)
NFCHECK("Il campo %d e' duplicato!", id);
}
else
_position.TArray::add((TObject*)pos, id);
}
}
void TMask::set_tab_buttons(TToken_string& tabs)
{
int tab = 0;
WINDOW nb = notebook();
if (nb == NULL_WIN)
nb = create_book(false);
FOR_EACH_TOKEN(tabs, title)
{
if (tab >= _pages) // Se devo creare piu' orecchie che pagine...
insert_page(page_win(_pages-1), -1); // ... ripeto l'ultima pagina
xvt_notebk_set_tab_title(nb, tab, title);
tab++;
}
}
void TMask::set_default_tab_buttons()
{
TToken_string tabs;
TString16 pag;
for (int i = 1; i <= _pages; i++)
{
pag.format(FR("Pag.%d"), i);
tabs.add(pag);
}
set_tab_buttons(tabs);
}
TMask::TMask(const char* maskname, int num, int max)
: _mask_num(num), _sheet(NULL)
{
if (maskname && *maskname)
read_mask(maskname, num, max);
}
TMask::~TMask()
{
_field.destroy();
}
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 (toolbar() != NULL_WIN)
xvt_toolbar_realize(toolbar()); // Non si capisce perche' ce ne sia bisogno, ma tant'e'
_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, bool dirty)
{
static int tempfirstfocus = -1;
static bool tempdirty = false;
int f = _first_focus;
if (id == 0)
{
if (tempfirstfocus >= 0)
{
f = tempfirstfocus;
if (tempdirty && fld(f).dirty() == false)
fld(f).set_dirty();
tempfirstfocus = -1;
}
else
{
if (f < 0 || !fld(f).active())
{
f = find_first_active(curr_win());
if (f < 0 && toolwin() != NULL_WIN)
f = find_first_active(toolwin());
if (f < 0 && toolbar() != NULL_WIN)
f = find_first_active(toolbar());
}
}
}
else
{
if (id > 0)
{
f = _first_focus = id2pos(id);
tempfirstfocus = -1;
}
else
{
f = tempfirstfocus = id2pos(-id);
tempdirty = dirty;
}
}
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(curr_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 = _page > 0 ? _page : 0;
if (f.parent() != curr_win()) // Controllo se devo cambiar pagina
{
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;
xvt_vobj_set_visible(win(), 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();
int i;
for (i = 0; i < max; i++)
{
const TMask_field& f = fld(i);
if (f.is_edit())
((TEdit_field&)f).test_drivers();
}
for (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 page> (default)
// @flag false | Disabilita la pagina <p page>
{
if (page > 0 && page < _pages) // Non posso spegnere la prima pagina
{
if (_enabled[page] != on)
{
CHECK(_notebook, "Can't find an useful notebook");
const short tabs = xvt_notebk_get_num_tabs(_notebook);
if (on)
{
// Riaggiungo i tab buttons (normalmente tabs == page)
for (short i = tabs; i < _pages; i++)
{
_enabled.set(i, true);
xvt_notebk_add_page(_notebook, _pagewin[i], NULL, NULL, i);
}
}
else
{
// Elimino i tab buttons (normalmente tabs == _pages)
for (short i = tabs-1; i >= page; i--)
{
_enabled.set(i, false);
xvt_notebk_rem_tab(_notebook, i);
}
_page = -1;
}
}
}
}
// Controlla lo stato di abilitazione di una pagina
// Certified 99%
bool TMask::page_enabled(byte p) const
{
// First page and toolbars are always enabled
const bool on = p == 0 || p >= MAX_PAGES || _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.active() || f.ghost()) &&
!f.is_kind_of(CLASS_BUTTON_FIELD) &&
!f.is_kind_of(CLASS_BUTTON_TOOL);
if (op)
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);
}
_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
{
TMask_field* f = find_by_id(id);
if (f == NULL)
{
if (_mask_num == 0)
yesnofatal_box("Non esiste il campo %d sulla maschera %s", id, (const char*)_source_file);
else
yesnofatal_box("Non esiste il campo %d della griglia %d sulla maschera %s ", id, _mask_num, (const char*)_source_file);
f = &((TMask*)this)->add_string(id, 0, "???", 1, id%100, 20, "D"); // Creo un campo anti-errore bloccante
}
return *f;
}
int TMask::field2pos(const char* fieldname) const
{
if (real::is_natural(fieldname) || *fieldname == '-')
{
const short id = atoi(fieldname);
return id2pos(id);
}
int i;
for (i = fields()-1; i >= 0; i--)
{
TMask_field& f = fld(i);
const TFieldref* fr = f.field();
if (fr != NULL && fr->name() == fieldname)
break;
}
return i;
}
TMask_field* TMask::find_by_id(short id) const
{
if (id < DLG_NULL)
{
const TSheet_field* s = get_sheet();
return s ? s->mask().find_by_id(-id) : NULL;
}
const int i = id2pos(id);
return i >= 0 ? &fld(i) : NULL;
}
TMask_field* TMask::find_by_fieldname(const char* fieldname) const
{
const int i = field2pos(fieldname);
return i >= 0 ? &fld(i) : 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;
}
TList_field& TMask::lfield(short id) const
{
TMask_field& f = field(id);
CHECKD(f.is_list(), "Impossibile trattare come listbox il campo ", id);
return (TList_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
{
return win2page(f.parent());
}
// @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;
// Cerca se esiste un bottone avente come exit_key() il tasto key
for (i = 0; i < last; i++)
{
const TMask_field& f = fld(i);
if (f.is_operable() && !f.is_editable() && f.active())
{
if (f.is_kind_of(CLASS_BUTTON_FIELD))
{
const TButton_field& b = (const TButton_field&)f;
if (b.exit_key() == key)
break;
} else
if (f.is_kind_of(CLASS_BUTTON_TOOL))
{
const TButton_tool& b = (const TButton_tool&)f;
if (b.exit_key() == key || b.virtual_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 */
}
long TMask::handler(WINDOW w, EVENT* ep)
{
static TSheet_field* _last_sheet = NULL;
if (ep->type == E_MOUSE_DOWN && ep->v.mouse.button == 1)
{
_last_sheet = NULL;
w = curr_win();
for (int f = fields()-1; f >= 0; f--)
{
TMask_field& cur_fld = fld(f);
if (cur_fld.shown() && cur_fld.parent() == w && cur_fld.is_operable())
{
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, w, p, XVT_POPUP_CENTER, 0); // verificare
xvt_res_free_menu_tree(menu);
}
}
return 0L;
}
if (ep->type == E_COMMAND)
{
const int tag = ep->v.cmd.tag;
if (_last_sheet != NULL)
{
switch (tag - BROWSE_BAR)
{
case 1: _last_sheet->save_columns_order(); break;
case 2: _last_sheet->reset_columns_order(); break;
case 3: _last_sheet->on_key(K_F11); break;
case 4: _last_sheet->esporta(); break;
default: break;
}
return 0L;
}
if (tag == M_HELP_ONCONTEXT)
{
on_key(K_F1);
return 0L;
}
}
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;
}
}
}
}
if (ep->type == E_CONTROL)
{
if (is_running()) // Scarto a priori gli eventi di inizializzazione
{
switch (ep->v.ctl.ci.type)
{
case WC_NOTEBK:
if (ep->v.ctl.ci.win == _notebook)
{
const bool changing = ep->v.ctl.ci.v.notebk.page == NULL_WIN;
const int new_page = ep->v.ctl.ci.v.notebk.page_new;
if (changing) // Tentativo di cambio pagina
{
if (new_page != _page && new_page < _pages)
{
if (_focus >= 0 && find_parent_page(fld(_focus)) != new_page)
{
if (!check_current_field())
return 1;
}
}
}
else
{
// Cambio pagina avvenuto
show_page(new_page); // Forza il focus al primo campo
}
}
break;
case WC_ICON: // In realta' trattasi di bottone di toolbar
if (ep->v.ctl.ci.win == toolbar()) // Test di sicurezza semi-inutile
{
TMask_field& tool = field(ep->v.ctl.id);
if (tool.active())
tool.on_key(K_SPACE); // Gestisco l'evento di pressione del bottone
}
break;
case WC_HSCROLL:
case WC_VSCROLL:
if (id2pos(ep->v.ctl.id) < 0) // potrebbero non avere un controllo associato
break;
// fall down
case WC_HSLIDER:
case WC_VSLIDER:
case WC_PROPGRID:
{
TMask_field& f = field(ep->v.ctl.id);
f.set_focusdirty();
f.on_key(K_SPACE);
}
break;
default:
break;
}
}
return 0L;
}
if (ep->type == E_UPDATE)
{
if (_bShowGrid)
{
RCT rct; xvt_vobj_get_client_rect(w, &rct);
DRAW_CTOOLS dct;
xvt_dwin_get_draw_ctools(w, &dct);
dct.fore_color = PROMPT_COLOR;
dct.back_color = MASK_BACK_COLOR;
dct.opaque_text = TRUE;
dct.pen.color = PROMPT_COLOR;
dct.pen.pat = PAT_SOLID;
dct.pen.style = P_SOLID;
dct.pen.width = 0;
xvt_dwin_set_draw_ctools(w, &dct);
for (int y = ROWY; y < rct.bottom; y += ROWY)
{
PNT pt0 = { y, rct.left }, pt1 = { y, rct.right};
xvt_dwin_draw_set_pos(w, pt0);
xvt_dwin_draw_line(w, pt1);
char text[8]; sprintf(text, "%d", y/ROWY);
xvt_dwin_draw_text(w, pt0.h, pt0.v, text, -1);
}
}
if (w == page_win(0) && source_file().find("custom") > 0)
{
RCT rct; xvt_vobj_get_client_rect(w, &rct);
rct.left += 2; rct.right -= 2; rct.bottom -= 2;
DRAW_CTOOLS dct;
xvt_dwin_get_draw_ctools(w, &dct);
dct.fore_color = MASK_BACK_COLOR;
dct.back_color = PROMPT_COLOR;
dct.opaque_text = TRUE;
xvt_dwin_set_draw_ctools(w, &dct);
//xvt_dwin_set_font(w, DEF_FONT);
xvt_dwin_set_clip(w, NULL);
const char* text = "Custom";
const int tw = xvt_dwin_get_text_width(w, text, -1);
xvt_dwin_draw_text(w, rct.left, rct.bottom, text, -1);
xvt_dwin_draw_text(w, rct.right-tw, rct.bottom, text, -1);
}
}
return TWindow::handler(w, 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:
{
const char* key = source_file().name_only();
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";
TString4 module; module.strncpy(key, 2); module.lower();
if (module != "ba")
n.insert(module);
FILE_SPEC fs; xvt_fsys_convert_str_to_fspec(n, &fs);
XVT_HELP_INFO hi = xvt_help_open_helpfile(&fs, 0);
xvt_help_process_event(hi, win(), &e);
}
break;
case K_F12:
send_key(K_F12, focus_field().dlg());
break;
case K_SHIFT+K_F11:
if (is_power_station())
{
_bShowGrid = !_bShowGrid;
xvt_dwin_invalidate_rect(curr_win(), NULL);
}
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_sheet())
{
send_key(key, f.dlg());
break;
}
}
}
break;
/*
case K_CTRL+'-':
if (is_running() && focus_field().is_sheet())
send_key(key, focus_field().dlg());
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.is_operable() && !f.is_editable() && f.active())
{
KEY vk = 0;
if (f.is_kind_of(CLASS_BUTTON_FIELD))
{
TButton_field& b = (TButton_field&)f;
vk = b.virtual_key();
} else
if (f.is_kind_of(CLASS_BUTTON_TOOL))
{
TButton_tool& t = (TButton_tool&)f;
vk = t.virtual_key();
}
if (vk > 0 && vk == key)
{
f.on_key(K_SPACE);
break;
}
}
}
}
}
}
return true;
}
bool TMask::on_dirty(TMask_field&)
{
return true;
}
int TMask::win2page(WINDOW w) const
{
if (w == toolwin())
return MAX_PAGES;
if (w == toolbar())
return MAX_PAGES+1;
int p;
for (p = _pages-1; p >= 0; p--)
if (w == page_win(p))
break;
return p;
}
TMask_field* TMask::parse_field(TScanner& scanner)
{
const TString& k = scanner.key();
if (k == "BO") return new TBoolean_field(this);
if (k == "BR") return new TBrowsefile_field(this);
if (k == "BU") return new TButton_field(this);
if (k == "CL") return new TGolem_client_field(this);
if (k == "CU") return new TCurrency_field(this);
if (k == "DA") return new TDate_field(this);
if (k == "GO") return new TGolem_field(this);
if (k == "GR") return new TGroup_field(this);
if (k == "LI") return new TList_field(this);
if (k == "ME") return new TMemo_field(this);
if (k == "NU") return new TReal_field(this);
if (k == "PR") return new TProp_field(this);
if (k == "RA") return new TRadio_field(this);
if (k == "SL") return new TSlider_field(this);
if (k == "SP") return new TSheet_field(this);
if (k == "ST") return new TEdit_field(this);
if (k == "TE") return new TText_field(this);
if (k == "TL") return new TTreelist_field(this);
if (k == "TR") return new TTree_field(this);
if (k == "ZO") return new TZoom_field(this);
return NULL;
}
TMask_field* TMask::parse_tool(TScanner& scanner)
{
const TString& k = scanner.key();
if (k == "BU") return new TButton_tool(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
void TMask::read_page(
TMask_scanner& scanner, // @parm File dal quale leggere la pagina
bool is_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
{
const TString title = dictionary_translate(scanner.string());
RCT r;
if (!is_toolbar && notebook() != NULL_WIN) // Pagina oltre la prima
{
scanner.line(); // Scarto rettangolo inutile
xvt_rect_set(&r, 0, 0, 0, 0);
}
else
{
scanner.rectangle(r.left, r.top, r.right, r.bottom);
if (is_toolbar)
{
if (r.top > 15) // Rendi negative le coordinate delle toolbar per ...
r.top -= MAX_MASK_ROWS; // ... ottimizzare l'uso dello schermo ad alta risoluzione
}
}
if (_notebook == NULL_WIN && _single == NULL) // Controlla se la maschera ha piu' di una pagina ...
{ // ... nel caso serva un notebook per le prossime
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.starts_with("PA") || l.starts_with("TO")) // Ho trovato un'altra pagina!
{
if (is_toolbar)
{
create_book(false); // Crea notebook
scanner.push_win(win()); // finestra principale
}
else
{
const WIN_TYPE wt = (r.right == 0) ? W_PLAIN : W_DOC;
const long wsf = WSF_INVISIBLE | WSF_NO_MENUBAR;
create(r.left, r.top, r.right, r.bottom, title, wsf, wt);
const bool single = l.starts_with("TO"); // Crea sotto-pagina singola o multipla?
create_book(single);
}
break;
}
}
scanner.seekg(pos); // Ripristina posizione dello scanner
}
WINDOW w = NULL_WIN;
if (is_toolbar)
{
if (r.top == 0)
w = create_bar(1);
else
{
CHECKD(r.top < 0, "Bad bottom bar height ", r.top);
w = create_bar(r.top);
}
}
else
{
if (notebook() != NULL_WIN)
w = create_page(title, -1);
else
{
if (_single != NULL_WIN)
w = _single;
else
{
CHECK(win() == NULL_WIN, "bad page sequence");
w = create_interface(NULL_WIN, r.left, r.top, r.right, r.bottom, title, this);
insert_page(w, 0);
}
}
}
scanner.push_win(w);
while (scanner.popkey() != "EN" && scanner.key().full())
{
TMask_field* f = NULL;
if (is_toolbar && r.top == 0)
f = parse_tool(scanner);
else
f = parse_field(scanner);
if (f == NULL)
{
#ifdef DBG
const int pf = fields();
TString e;
e << "Campo non riconosciuto nella pagina " << title << " alla posizione " << pf << ": " << scanner.key();
if (pf > 0)
e << "\nL'ultimo riconosciuto <20> " << fld(pf-1).dlg() << ": " << fld(pf-1).prompt();
error_box(e);
#endif
while (scanner.popkey() != "EN" && scanner.key().full());
}
else
{
f->construct(scanner, w);
add_field(f);
}
}
if (is_toolbar && r.top ==0 && _toolbar != NULL_WIN)
xvt_toolbar_realize(_toolbar);
scanner.pop_win();
}
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;
}
WINDOW TMask::create_book(bool single)
{
WINDOW parent = win();
if (parent == NULL_WIN)
{
parent = create(0, 0, 0, 0, "", WSF_INVISIBLE|WSF_NO_MENUBAR, W_PLAIN);
}
if (single)
{
CHECK(_single == NULL_WIN, "One single page pane, please!");
CHECK(_notebook == NULL_WIN, "Single and notebook?");
_single = create_interface(parent, 0, 0, 0, 0, "", this);
xvt_pane_add(parent, _single, "_MainSingle_", 0, 0);
_pagewin[0] = _single;
_pages = 1;
}
else
{
CHECK(_notebook == NULL_WIN, "One single notebook, please!");
CHECK(_single == NULL_WIN, "Notebook and Single?");
XVT_COLOR_COMPONENT xcc[4]; memset(xcc, 0, sizeof(xcc));
xcc[0].type = XVT_COLOR_BACKGROUND; xcc[0].color = MASK_BACK_COLOR;
xcc[1].type = XVT_COLOR_FOREGROUND; xcc[1].color = PROMPT_COLOR;
WIN_DEF wd; memset(&wd, 0, sizeof(wd));
wd.wtype = WC_NOTEBK;
wd.ctlcolors = xcc;
wd.v.ctl.flags = CTL_FLAG_TAB_DEFAULT | CTL_FLAG_TAB_TOP | (CAMPI_SCAVATI ? 0 : WSF_NO_TASKBAR);
xvt_vobj_get_client_rect(parent, &wd.rct);
_notebook = xvt_ctl_create_def(&wd, parent, long(this));
xvt_pane_add(parent, _notebook, "_MainNoteBook_", 0, 0);
if (_single != NULL) // Bello ... se solo andasse!
{
xvt_pane_detach(_single);
insert_page(_single, 0);
_single = NULL_WIN;
}
}
return single ? _single : _notebook;
}
void TMask::insert_bar(WINDOW page)
{
WINDOW parent = win();
CHECK(page != NULL_WIN, "Invalid toolbar");
CHECK(parent != NULL_WIN, "Invalid main window for toolbar");
if (_notebook == NULL_WIN && _single == NULL_WIN)
create_book(true); // In assenza di notebook crea un pane a pagina singola
RCT rct_win; xvt_vobj_get_outer_rect(parent, &rct_win);
RCT rct_bar; xvt_vobj_get_outer_rect(page, &rct_bar);
if (rct_bar.top > (rct_win.bottom-rct_win.top)/2) // BottomBar
{
CHECK(_toolwin == NULL_WIN, "One single bottom bar, please!");
_toolwin = page;
xvt_pane_add(parent, _toolwin, "_BottomBar_", 4, 0);
// Ammazza la caption e ne blocca le dimensioni
xvt_pane_change_flags(page, 0, 1 <<10); // No caption
xvt_pane_change_flags(page, 0, 1 << 8); // No resize
}
else // TopBar
{
CHECK(_toolbar == NULL_WIN, "One single top bar, please!");
RCT t; xvt_vobj_get_client_rect(TASK_WIN, &t);
RCT r; xvt_vobj_get_client_rect(win(), &r);
if (r.bottom < t.bottom-2*ROWY) // Ridimensiono maschera piccola (non massimizzata)
{
const short bar_height = max(rct_bar.bottom - rct_bar.top, TOOL_SIZE + TOOL_TEXT * 12 + 12);
RCT rct_new; xvt_vobj_get_client_rect(parent, &rct_new);
rct_new.bottom += bar_height;
xvt_rect_offset(&rct_new, rct_win.left, rct_win.top-bar_height/2);
xvt_vobj_move(parent, &rct_new);
}
_toolbar = page;
xvt_pane_add(parent, _toolbar, "_TopBar_", 62, 0);
}
}
WINDOW TMask::create_bar(int height)
{
WINDOW w = NULL_WIN;
if (height < 0)
w = create_interface(win(), 0, height, 0, 0, "", this); // Bottom bar
else
{
const long flags = (TOOL_TEXT ? CTL_FLAG_PASSWORD : 0) | (CAMPI_SCAVATI ? 0 : WSF_NO_TASKBAR);
w = xvt_toolbar_create(-1, 0, 0, -1, TOOL_SIZE, flags, win()); // Top bar
XVT_COLOR_COMPONENT cc[4]; memset(cc, 0, sizeof(cc));
cc[0].type = XVT_COLOR_BLEND; cc[0].color = MASK_BACK_COLOR;
cc[1].type = XVT_COLOR_FOREGROUND; cc[1].color = PROMPT_COLOR;
xvt_ctl_set_colors(w, cc, XVT_COLOR_ACTION_SET);
XVT_IMAGE txt = get_background_texture();
if (txt != NULL)
xvt_ctl_set_texture(w, txt);
}
insert_bar(w); // Inserisce toolbar e crea notebook, se necessario
return w;
}
void TMask::insert_page(WINDOW page, int dove)
{
CHECKD(dove >= -1 && dove <= _pages, "Invalid page position:", dove);
// Per le pagine dopo la prima devo creare il notebook
if (_pages == 1 && _notebook == NULL_WIN)
create_book(false);
memset(_pagewin, 0, sizeof(_pagewin)); // Azzero lista pagine
if (_notebook != NULL_WIN) // property sheet
{
xvt_notebk_add_page(_notebook, page, NULL, NULL, dove);
_pages = xvt_notebk_get_num_tabs(_notebook);
// Ricostruisco lista pagine
for (short p = 0; p < _pages; p++)
_pagewin[p] = xvt_notebk_get_page(_notebook, p);
}
else // single page
{
CHECK(win() == NULL_WIN, "One single main page, please!");
set_win(page);
_pagewin[0] = page; // Assegno la prima ed unica pagina
_pages = 1;
}
}
WINDOW TMask::create_page(const char* title, int dove)
{
CHECKD(dove < 0 || dove < MAX_PAGES, "invalid page position ", dove);
WINDOW w = create_interface(notebook(), 0, 0, 0, 0, title, this);
insert_page(w, dove);
return w;
}
void TMask::set_focus()
{
TWindow::set_focus();
WINDOW w = curr_win();
if (w != win()) // Succede se ci sono notebook o toolbar
{
xvt_scr_set_focus_vobj(w);
xvt_vobj_raise(w);
}
}
// @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 (notebook() != NULL)
xvt_notebk_set_front_page(notebook(), _page);
}
if (_focus < 0 || fld(_focus).parent() != curr_win() || !fld(_focus).active())
{
_focus = find_first_active(curr_win());
if (_focus < 0 && toolwin() != NULL_WIN)
_focus = find_first_active(toolwin());
if (_focus < 0 && toolbar() != NULL_WIN)
_focus = find_first_active(toolbar());
}
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_EACH_MASK_FIELD(*this, i, c) if (gr == 0 || c->in_group(gr))
{
c->reset();
c->set_dirty(false);
}
}
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 = get(fld_id);
return atol(s);
}
bool TMask::get_bool(short fld_id) const
{
const TString& s = get(fld_id);
return s.full() && s != "0";
}
real TMask::get_real(short fld_id) const
{
const TString& s = get(fld_id);
return real(s);
}
TDate TMask::get_date(short fld_id) const
{
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
{
const 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)
{
TString16 s;
s << n;
set(fld_id, s, hit);
}
void TMask::set(short fld_id, const real& n, byte hit)
{
CHECK(efield(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 maschera
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);
// Maschera vecchia e decrepita senza toolbar: nascondo i bottoni
if (toolwin() != NULL_WIN && toolbar() == 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 se abilitare il 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 maxflds = fields();
bool full = false;
for (int f = 0; f < maxflds; f++)
{
TMask_field& c = fld(f);
if (c.is_editable() && c.shown() && c.in_key(key))
{
if (c.empty())
{
if (c.required())
return false;
}
else
full = true;
}
}
return full;
}
// @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)
{
FOR_EACH_MASK_FIELD((*this), i, f) if (f->is_loadable())
((TLoadable_field*)f)->autoload(r);
}
void TMask::autosave(TRelation& r) const
{
FOR_EACH_MASK_FIELD((*this), i, f) if (f->is_loadable())
{
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
if (f->field() != NULL)
{
const char* str = f->field()->read(r);
save = *str == '\0';
}
}
if (save)
((TLoadable_field*)f)->autosave(r);
}
TRectype& rec = r.curr();
if (rec.exist("DATAAGG"))
{
rec.put("DATAAGG", TDate(TODAY));
rec.put("UTENTE", user());
}
}
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)
{
const int es = _error_severity; // Memorizzo per azzerare subito
_error_severity = 0;
set_focus();
if (ADVANCED_GRAPHICS && ANIMATED_BOXES)
{
switch(es)
{
case 2: xvt_dm_popup_warning(_error_message); break;
case 3: xvt_dm_popup_error (_error_message); break;
default: xvt_dm_popup_message(_error_message); break;
}
}
else
{
switch(es)
{
case 2: xvt_dm_post_warning(_error_message); break;
case 3: xvt_dm_post_error (_error_message); break;
default: xvt_dm_post_message(_error_message); break;
}
}
}
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() : win();
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, page_win(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, page_win(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, page_win(page), flags, dx, 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), page_win(page), flags);
add_field(f);
return *f;
}
TCheckbutton_field& TMask::add_checkbutton (
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>
{
TCheckbutton_field* f = new TCheckbutton_field(this);
f->construct(id, prompt, x, y, dy, page_win(page), flags, dx);
if (bmpup > 0)
((TCheckbutton_control*)f->_ctl)->set_icon(bmpup, bmpdn);
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, page_win(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 Campo con codice valuta
// @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, page_win(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, page_win(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, page_win(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, page_win(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, page_win(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, page_win(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, page_win(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, page_win(page), flags, dx);
add_field(f);
return *f;
}
TButton_tool& TMask::add_button_tool(short id, const char* prompt, short bmpup)
{
if (toolbar() == NULL_WIN) // Se non c'e' ancora la toolbar, me l'invento adesso
create_bar(1);
CHECKD(id <= 0 || bmpup > 0, "Toolbar button needs a wonderful icon ", id);
TButton_tool* t = new TButton_tool(this);
t->construct(id, prompt, 0, 0, 0, toolbar(), "", 0, bmpup, 0);
add_field(t);
return *t;
}
// @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);
char* buffer = t.get_buffer();
while (fgets(buffer, t.size(), f) != NULL && t != "[EOM]")
{
if (t.not_empty())
{
t.rtrim();
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( ) );
}
}
}
}
bool TMask::make_profile_name(TFilename& f) const
{
f = source_file().name();
f.ext("ini");
if (!f.custom_path()) // Prova a cercare la configurazione in custom ...
{ // ... altrimenti riprova in config
f =::firm2dir(-1); // Directory dati
f.add("config"); // Directory config
f.add(source_file().name()); // Nome Maschera
f.ext("ini"); // Estensione
}
return f.exist();
}
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(0L);
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;
if (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);
if (var.items() > 0)
{
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;
}
bool TMask::kill_profile(int num)
{
TFilename prof;
make_profile_name(prof);
TConfig ini(prof, "Main");
if (num <= 0)
num = ini.get_int(user());
TString8 name; name << num;
const bool ok = ini.set_paragraph(name);
if (ok)
ini.remove_all();
return ok;
}
void TMask::load_defaults()
{
FOR_EACH_MASK_FIELD(*this, i, f) if (f->is_loadable())
{
const TString& def = f->get_default();
if (def.full())
f->set(def);
}
}
const char* TMask::get_caption(TString& str) const
{
char* title = NULL;
for (int i = 32; i <= 256; i *= 2)
{
title = str.get_buffer(i);
xvt_vobj_get_title(win(), title, i+1);
if (str.len() < i)
break;
}
return title;
}
void TMask::set_caption(const char* c)
{
TToken_string captions(c);
if (_notebook != NULL_WIN)
{
for (int p = 0; p < _pages; p++)
{
const char* title = captions.get();
if (title == NULL)
title = captions.get(0);
xvt_notebk_set_tab_title(_notebook, p, title);
}
}
else
xvt_vobj_set_title(win(), captions.get(0));
}
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
{
if (_error_message == msg)
return; // Ignora messaggio duplicato;
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
TMemo_field& m = add_memo(DLG_USER, 0, "", 1, 0,-1,-3);
m.set(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();
}
long TTimed_box::handler(WINDOW win, EVENT* ep)
{
if (ep->type == E_TIMER && ep->v.timer.id==_timer_id)
send_key(K_SPACE, _button_id);
return 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(TR("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(TR("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()
{}