checks.cpp Tolto include windows.h colors.cpp Tolto include windows.h controls.cpp Aggiunto cambiamento del font runtime dei TText_control execp.cpp Tolto include windows.h form.cpp Tolto include windows.h mask.cpp Corretta formattazione di due righe maskfld.cpp Aggiunto messaggio CHECK msksheet.cpp Tolto include windows.h relapp.cpp Tolto include windows.h strings.pp Corretto CHECK della TFixed_string::format() viswin.cpp Tolto include windows.h window.cpp Tolto include windows.h xvtility.cpp Corretto calcolo altezza righe delle maschere git-svn-id: svn://10.65.10.50/trunk@4085 c028cbd2-c16b-5b4b-a496-9718f37d4682
990 lines
21 KiB
C++
Executable File
990 lines
21 KiB
C++
Executable File
#include <mailbox.h>
|
|
#include <sheet.h>
|
|
#include <urldefid.h>
|
|
#include <relapp.h>
|
|
#include <utility.h>
|
|
|
|
#define XVT_INCL_NATIVE
|
|
#define STRICT
|
|
#include <xvtility.h>
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// TRelation_application
|
|
///////////////////////////////////////////////////////////
|
|
|
|
TRelation_application::TRelation_application()
|
|
: _mask(NULL), _search_id(-1), _lnflag(FALSE)
|
|
{ }
|
|
|
|
TRelation_application::~TRelation_application()
|
|
{ }
|
|
|
|
void TRelation_application::setkey()
|
|
{
|
|
if (has_filtered_cursor())
|
|
{
|
|
TEdit_field& f = get_search_field();
|
|
TCursor* cur = f.browse()->cursor();
|
|
cur->setkey();
|
|
return;
|
|
}
|
|
file().setkey(1);
|
|
}
|
|
|
|
|
|
// @doc INTERNAL
|
|
|
|
// @mfunc Setta i limiti
|
|
void TRelation_application::set_limits(
|
|
byte what) // @parm tipo di limite da assegnare al record
|
|
|
|
// @comm I limiti possibili sono:
|
|
// @flag 0 | Nessuna operazione
|
|
// @flag 1 | Primo record
|
|
// @flag 2 | Ultimo record
|
|
// @flag 3 | Entrambi
|
|
{
|
|
if (has_filtered_cursor())
|
|
{
|
|
TEdit_field& f = get_search_field();
|
|
|
|
TBrowse* b = f.browse();
|
|
TCursor* cur = b != NULL ? b->cursor() : NULL;
|
|
if (cur)
|
|
{
|
|
cur->setkey();
|
|
f.browse()->do_input(TRUE);
|
|
if (cur->items() == 0) _first = _last = -1;
|
|
else
|
|
{
|
|
if (what & 0x1)
|
|
{
|
|
*cur = 0;
|
|
_first = cur->file().recno();
|
|
}
|
|
if (what & 0x2)
|
|
{
|
|
*cur = cur->items() - 1;
|
|
_last = cur->file().recno();
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
|
|
file().setkey(1);
|
|
if (what & 0x1)
|
|
{
|
|
if (file().empty()) _first = 1;
|
|
else
|
|
{
|
|
file().first();
|
|
_first = file().recno();
|
|
}
|
|
}
|
|
if (what & 0x2)
|
|
{
|
|
if (file().empty()) _last = 1;
|
|
else
|
|
{
|
|
file().last();
|
|
_last = file().recno();
|
|
}
|
|
}
|
|
}
|
|
|
|
bool TRelation_application::create()
|
|
{
|
|
TApplication::create();
|
|
const bool ok = user_create();
|
|
if (ok)
|
|
{
|
|
write_enable();
|
|
_mask = get_mask(MODE_QUERY);
|
|
filter();
|
|
set_limits();
|
|
dispatch_e_menu(BAR_ITEM(1));
|
|
}
|
|
return ok;
|
|
}
|
|
|
|
|
|
bool TRelation_application::menu(MENU_TAG m)
|
|
{
|
|
if (m == BAR_ITEM(1))
|
|
return main_loop();
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
bool TRelation_application::destroy()
|
|
{
|
|
user_destroy();
|
|
return TApplication::destroy();
|
|
}
|
|
|
|
|
|
void TRelation_application::set_fixed()
|
|
{
|
|
TToken_string s(256, '=');
|
|
for (const char* f = _fixed.get(0); f && *f; f = _fixed.get())
|
|
{
|
|
s = f;
|
|
const int id = s.get_int(0);
|
|
s = s.get();
|
|
if (s.not_empty())
|
|
_mask->set(id, s);
|
|
|
|
if (_lnflag < 2)
|
|
_mask->disable(id);
|
|
}
|
|
}
|
|
|
|
|
|
void TRelation_application::enable_query()
|
|
{
|
|
const bool query = _mask->query_mode();
|
|
const bool keyon = query || get_relation()->status() == _isreinsert;
|
|
|
|
for (int i = _mask->fields() - 1; i >= 0; i--)
|
|
{
|
|
TMask_field& c = _mask->fld(i);
|
|
if (c.in_key(0) && c.enabled_default())
|
|
{
|
|
if (c.in_key(1))
|
|
c.enable(keyon);
|
|
if (c.is_edit())
|
|
{
|
|
TEdit_field& e = (TEdit_field&)c;
|
|
if (e.browse() != NULL)
|
|
e.enable_check(query);
|
|
}
|
|
}
|
|
}
|
|
|
|
set_fixed();
|
|
}
|
|
|
|
|
|
void TRelation_application::set_toolbar(bool all)
|
|
{
|
|
const int mode = _mask->mode();
|
|
int pos;
|
|
|
|
if (all)
|
|
{
|
|
pos = _mask->id2pos(DLG_SAVEREC);
|
|
if (pos >= 0) _mask->fld(pos).enable(mode != MODE_QUERY);
|
|
pos = _mask->id2pos(DLG_DELREC);
|
|
if (pos >= 0)
|
|
{
|
|
bool enabdel = mode == MODE_MOD;
|
|
if (enabdel)
|
|
{
|
|
TRelation& r = *get_relation();
|
|
const TRecnotype oldpos = r.lfile().recno();
|
|
enabdel = !protected_record(r.curr());
|
|
if (r.lfile().recno() != oldpos)
|
|
r.lfile().readat(oldpos);
|
|
}
|
|
_mask->fld(pos).enable(enabdel);
|
|
}
|
|
}
|
|
|
|
enable_query();
|
|
}
|
|
|
|
|
|
bool TRelation_application::save_and_new() const
|
|
{ return FALSE; }
|
|
|
|
int TRelation_application::set_mode(int mode)
|
|
{
|
|
static int _mode = NO_MODE;
|
|
if (mode < NO_MODE) mode = _mode;
|
|
|
|
const int m = ((TMaskmode)mode == NO_MODE) ? (int) MODE_QUERY : mode;
|
|
_mask->set_mode(m);
|
|
|
|
if (mode == _mode)
|
|
{
|
|
set_toolbar(FALSE); // Fast buttons update
|
|
}
|
|
else
|
|
{
|
|
set_toolbar(TRUE); // Full buttons update
|
|
_mode = mode;
|
|
}
|
|
|
|
const char* t = "";
|
|
switch(mode)
|
|
{
|
|
case MODE_QUERY:
|
|
t = "Ricerca"; break;
|
|
case MODE_MOD:
|
|
t = "Modifica"; break;
|
|
case NO_MODE:
|
|
t = "Ricerca/Inserimento"; break;
|
|
case MODE_INS:
|
|
t = "Inserimento"; break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
xvt_statbar_set(t, TRUE);
|
|
|
|
return _mode;
|
|
}
|
|
|
|
// @doc INTERNAL
|
|
|
|
// @mfunc Permette di autonumerare un record
|
|
//
|
|
// @rdesc Ritorna se e' riuscito a creare una nuova autonumerazione:
|
|
//
|
|
// @flag TRUE | La chiave non e' vuota
|
|
// @flag FALSE | Non e' riuscito ad autonumerare il documento
|
|
bool TRelation_application::autonum(
|
|
TMask* m, // @parm Maschera a cui applicare l'autonumerazione
|
|
bool rec) // @parm Indica se registrare la chiave anche sul record corrente
|
|
{
|
|
TToken_string k(get_next_key());
|
|
|
|
if (!rec && !m->query_mode())
|
|
m->reset();
|
|
_renum_message = "";
|
|
|
|
for (const char* n = k.get(0); n && *n; n = k.get())
|
|
{
|
|
const short id = atoi(n);
|
|
CHECKD (id > 0, "Identificatore di autonumerazione errato: ", id);
|
|
const char* val = k.get();
|
|
TMask_field& f = m->field(id);
|
|
if (rec || f.empty())
|
|
f.set(val);
|
|
if (rec)
|
|
((TEditable_field&)f).autosave(*get_relation());
|
|
if (_renum_message.empty() || f.in_key(1))
|
|
_renum_message.format("Il documento e' stato registrato con :\n %s = %s", (const char *) f.prompt(), (const char *) f.get());
|
|
}
|
|
return k.not_empty();
|
|
}
|
|
|
|
// @doc EXTERNAL
|
|
|
|
// @mfunc Entra in modo di ricerca
|
|
void TRelation_application::query_mode(
|
|
bool pre_ins) // @parm Indica in quale modo andare:
|
|
//
|
|
// @flag TRUE | Entra in modo MODE_QUERY_INSERT
|
|
// @flag FALSE | Entra in modo MODE_QUERY (default)
|
|
{
|
|
TMask* old = _mask;
|
|
const bool was_open = old != NULL && old->is_open();
|
|
const bool changing = changing_mask(MODE_QUERY);
|
|
|
|
if (changing && was_open)
|
|
old->close_modal();
|
|
|
|
_mask = get_mask(MODE_QUERY);
|
|
if (changing)
|
|
{
|
|
if (was_open)
|
|
_mask->open_modal();
|
|
set_limits();
|
|
}
|
|
|
|
_mask->set_mode(pre_ins ? MODE_QUERYINS : MODE_QUERY);
|
|
_mask->reset();
|
|
|
|
if (pre_ins)
|
|
{
|
|
set_mode(NO_MODE);
|
|
init_query_insert_mode(*_mask);
|
|
}
|
|
else
|
|
{
|
|
set_mode(MODE_QUERY);
|
|
init_query_mode(*_mask);
|
|
}
|
|
}
|
|
|
|
|
|
void TRelation_application::insert_mode()
|
|
{
|
|
bool try_auto = TRUE;
|
|
|
|
if (_mask->query_mode())
|
|
try_auto = test_key(1, FALSE) == FALSE;
|
|
|
|
if (try_auto && !autonum(_mask, FALSE))
|
|
{
|
|
query_insert_mode();
|
|
return;
|
|
}
|
|
|
|
const bool changing = changing_mask(MODE_INS);
|
|
TFilename workname; workname.temp("msk");
|
|
if (changing)
|
|
{
|
|
_mask->set_workfile(workname);
|
|
_mask->save();
|
|
_mask->close_modal();
|
|
}
|
|
_mask = get_mask(MODE_INS);
|
|
if (changing)
|
|
{
|
|
_mask->reset();
|
|
_mask->set_workfile(workname);
|
|
_mask->load();
|
|
::remove(workname);
|
|
_mask->open_modal();
|
|
}
|
|
|
|
set_mode(MODE_INS);
|
|
get_relation()->zero(); // Azzera tutta la relazione!
|
|
init_insert_mode(*_mask);
|
|
}
|
|
|
|
bool TRelation_application::modify_mode()
|
|
{
|
|
int err = get_relation()->read(_isequal, _testandlock);
|
|
if (err != NOERR)
|
|
{
|
|
if (err == _islocked)
|
|
message_box("I dati sono gia' in uso ad un altro programma");
|
|
else
|
|
error_box("Impossibile leggere i dati: errore %d", err);
|
|
query_mode();
|
|
return FALSE;
|
|
}
|
|
|
|
const bool changing = changing_mask(MODE_MOD);
|
|
if (changing)
|
|
_mask->close_modal();
|
|
|
|
_mask = get_mask(MODE_MOD);
|
|
|
|
if (changing)
|
|
_mask->open_modal();
|
|
|
|
set_mode(MODE_MOD);
|
|
|
|
err = read(*_mask);
|
|
if (err != NOERR)
|
|
{
|
|
query_mode();
|
|
return FALSE;
|
|
}
|
|
|
|
get_relation()->save_status();
|
|
init_modify_mode(*_mask);
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
TEdit_field& TRelation_application::get_search_field() const
|
|
{
|
|
short id = _search_id;
|
|
|
|
if (id <= 0)
|
|
{
|
|
const int max = _mask->fields();
|
|
for (int i = 0; i < max; i++)
|
|
{
|
|
const TMask_field& f = _mask->fld(i);
|
|
if (f.in_key(1) && f.required())
|
|
{
|
|
id = f.dlg();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return _mask->efield(id);
|
|
}
|
|
|
|
bool TRelation_application::search_mode()
|
|
{
|
|
if (_mask->mode() != MODE_QUERY)
|
|
query_mode();
|
|
|
|
TEdit_field* prima = &get_search_field();
|
|
while (prima)
|
|
{
|
|
if (prima->on_key(K_F9))
|
|
{
|
|
if (find(1))
|
|
return modify_mode();
|
|
}
|
|
|
|
TMask_field* dopo = &_mask->focus_field();
|
|
prima = (dopo == prima || !dopo->is_edit()) ? NULL : (TEdit_field*)dopo;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
// @doc INTERNAL
|
|
|
|
// @mfunc Controlla se una chiave e' completa ed esiste su file
|
|
//
|
|
// @rdesc Ritorna se la chave esiste sul file
|
|
bool TRelation_application::test_key(
|
|
byte k, // @parm Chiave da ricercare
|
|
bool err) // @parm Indica se visualizzare eventuali errori occorsi
|
|
{
|
|
bool onereq = FALSE, onefill = FALSE;
|
|
|
|
for (TEditable_field* e = _mask->get_key_field(k, TRUE);
|
|
e != NULL;
|
|
e = _mask->get_key_field(k, FALSE))
|
|
{
|
|
if (e->required())
|
|
{
|
|
onereq = TRUE;
|
|
if (e->empty())
|
|
{
|
|
if (err)
|
|
{
|
|
error_box("Manca un valore indispensabile per la ricerca");
|
|
_mask->first_focus(-e->dlg());
|
|
}
|
|
return FALSE;
|
|
}
|
|
}
|
|
else
|
|
/* if (k == 1 && !onereq && !onefill && c.get().not_empty()) */
|
|
if (!onereq && !onefill && e->is_edit() && !e->empty())
|
|
onefill = TRUE;
|
|
}
|
|
if (k == 1 && !onereq && !onefill)
|
|
{
|
|
if (err)
|
|
error_box("Manca un valore indispensabile per la ricerca");
|
|
return FALSE;
|
|
}
|
|
return onefill || onereq;
|
|
}
|
|
|
|
bool TRelation_application::find(byte k)
|
|
{
|
|
if (k == 0)
|
|
{
|
|
for (k = 1; k <= MAX_KEYS && !test_key(k, FALSE); k++);
|
|
if (k > MAX_KEYS)
|
|
return test_key(1, TRUE);
|
|
}
|
|
|
|
file().setkey(k);
|
|
file().zero();
|
|
for (TEditable_field* e = _mask->get_key_field(k, TRUE); e; e = _mask->get_key_field(k, FALSE))
|
|
{
|
|
if (e->shown()) // Ignora campi invisibili
|
|
e->autosave(*get_relation());
|
|
}
|
|
|
|
const int err = file().read(_isequal);
|
|
return err == NOERR;
|
|
}
|
|
|
|
|
|
bool TRelation_application::save(bool check_dirty)
|
|
{
|
|
static bool was_dirty = FALSE;
|
|
|
|
int err = NOERR;
|
|
const int mode = _mask->mode();
|
|
|
|
if (check_dirty)
|
|
{
|
|
const int dirty = _mask->dirty();
|
|
|
|
const char* ms = (mode == MODE_MOD) ? "le modifiche" : "i dati inseriti";
|
|
|
|
if (mode == MODE_QUERY)
|
|
{
|
|
const bool cont = !dirty || yesno_box("Annullare %s?", ms);
|
|
return cont;
|
|
}
|
|
|
|
if (!dirty && !was_dirty)
|
|
{
|
|
if (mode == MODE_MOD)
|
|
{
|
|
get_relation()->restore_status();
|
|
get_relation()->lfile().reread(_unlock); // Unlock main file
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
const KEY last = _mask->last_key();
|
|
const bool annulla = last == K_ESC || last == K_QUIT || last == K_F9;
|
|
const bool errore = dirty && _mask->field(dirty).dirty() > TRUE;
|
|
|
|
KEY k;
|
|
if (errore)
|
|
{
|
|
if (annulla)
|
|
{
|
|
TString w(80);
|
|
if (_mask->field(dirty).is_edit())
|
|
w = _mask->efield(dirty).get_warning();
|
|
if (w.empty())
|
|
w = "Campo inconsistente";
|
|
w << ": si desidera ";
|
|
switch (last)
|
|
{
|
|
case K_ESC:
|
|
w << "annullare?"; break;
|
|
case K_QUIT:
|
|
w << "uscire?"; break;
|
|
default:
|
|
w << "continuare?"; break;
|
|
}
|
|
k = yesno_box(w) ? K_NO : K_ESC;
|
|
if (k == K_ESC)
|
|
_mask->first_focus(-dirty);
|
|
}
|
|
else k = K_ESC;
|
|
}
|
|
else
|
|
k = yesnocancel_box("Registrare %s?", ms);
|
|
|
|
if (k == K_ESC || k == K_NO)
|
|
{
|
|
if (mode == MODE_MOD)
|
|
{
|
|
get_relation()->restore_status();
|
|
get_relation()->lfile().reread(_unlock); // Unlock main file
|
|
}
|
|
was_dirty = FALSE;
|
|
return k == K_NO;
|
|
}
|
|
|
|
if (annulla)
|
|
{
|
|
if (!_mask->check_fields()) // Exit with ESC didn't check values
|
|
{
|
|
_mask->first_focus(-_mask->focus_field().dlg());
|
|
was_dirty = TRUE;
|
|
return FALSE;
|
|
}
|
|
}
|
|
}
|
|
was_dirty = FALSE;
|
|
|
|
begin_wait();
|
|
if (mode == MODE_INS)
|
|
{
|
|
bool changed = TRUE;
|
|
bool changed_key = FALSE;
|
|
|
|
while (changed)
|
|
{
|
|
err = write(*_mask);
|
|
if (err == _isreinsert)
|
|
{
|
|
changed = autonum(_mask, TRUE);
|
|
if (!changed)
|
|
{
|
|
_mask->disable_starting_check();
|
|
enable_query(); // Abilita chiave 1 per rinumerazione manuale
|
|
}
|
|
else
|
|
changed_key = TRUE;
|
|
}
|
|
else
|
|
changed = FALSE;
|
|
}
|
|
if (err == NOERR)
|
|
{
|
|
if (changed_key)
|
|
message_box(_renum_message);
|
|
get_relation()->save_status();
|
|
set_limits();
|
|
get_relation()->restore_status();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
get_relation()->restore_status();
|
|
err = rewrite(*_mask);
|
|
}
|
|
end_wait();
|
|
|
|
switch(err)
|
|
{
|
|
case NOERR:
|
|
_recins = get_relation()->lfile().recno();
|
|
break;
|
|
case _isreinsert:
|
|
warning_box("Esiste gia' un documento con la stessa chiave");
|
|
break;
|
|
default:
|
|
error_box("Impossibile registrare i dati: errore %d", err);
|
|
break;
|
|
}
|
|
return err == NOERR;
|
|
}
|
|
|
|
|
|
int TRelation_application::read(TMask& m)
|
|
{
|
|
const TRelation &r = *get_relation();
|
|
m.autoload(r);
|
|
return NOERR;
|
|
}
|
|
|
|
|
|
int TRelation_application::write(const TMask& m)
|
|
{
|
|
TRelation &r = *get_relation();
|
|
m.autosave(r);
|
|
r.write();
|
|
return r.status();
|
|
}
|
|
|
|
|
|
int TRelation_application::rewrite(const TMask& m)
|
|
{
|
|
TRelation& r = *get_relation();
|
|
m.autosave(r);
|
|
r.rewrite();
|
|
return r.status();
|
|
}
|
|
|
|
// @doc INTERNAL
|
|
|
|
// @mfunc Cancella il record corrente
|
|
//
|
|
// @rdesc Ritorna se il record e' stato eliminato
|
|
bool TRelation_application::relation_remove()
|
|
|
|
// @comm Se la maschera e' in MODE_MOD non e' possibile cancellare il record e viene
|
|
// emesso un <f CHECK> di errore.
|
|
{
|
|
CHECK(_mask->mode() == MODE_MOD, "You can call remove in MODE_MOD only");
|
|
TRelation *r = get_relation();
|
|
|
|
r->restore_status();
|
|
|
|
if (protected_record(r->curr()))
|
|
return message_box("Registrazione non eliminabile");
|
|
|
|
if (yesno_box("Confermare l'eliminazione"))
|
|
{
|
|
r->restore_status();
|
|
const bool ok = remove();
|
|
if (ok)
|
|
set_limits();
|
|
else
|
|
return error_box("Errore di cancellazione %d", r->status());
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
bool TRelation_application::remove()
|
|
{
|
|
const int err = get_relation()->remove();
|
|
return err == NOERR;
|
|
}
|
|
|
|
bool TRelation_application::firm_change_enabled() const
|
|
{
|
|
bool ok = TApplication::firm_change_enabled();
|
|
ok &= (_mask == NULL || _mask->query_mode()) && _lnflag == 0;
|
|
return ok;
|
|
}
|
|
|
|
bool TRelation_application::main_loop()
|
|
{
|
|
_recins = -1;
|
|
|
|
query_mode();
|
|
_mask->open_modal();
|
|
|
|
KEY k;
|
|
|
|
// Provoca l'autopremimento per il messaggio di LINK
|
|
if (_lnflag) _mask->send_key(K_AUTO_ENTER, 0);
|
|
|
|
do
|
|
{
|
|
const bool change = firm_change_enabled();
|
|
// Dis/abilita cambio ditta
|
|
enable_menu_item(M_FILE_NEW, change);
|
|
// Dis/abilita cambio parametri
|
|
enable_menu_item(M_FILE_REVERT, change);
|
|
|
|
k = _mask->run();
|
|
|
|
switch (k)
|
|
{
|
|
case K_ESC:
|
|
if (save(TRUE))
|
|
query_mode();
|
|
if (_lnflag)
|
|
k = K_QUIT;
|
|
break;
|
|
case K_QUIT:
|
|
if (!save(TRUE))
|
|
k = K_ENTER;
|
|
break;
|
|
case K_ENTER:
|
|
if (find(0)) modify_mode();
|
|
else insert_mode();
|
|
break;
|
|
case K_SAVE:
|
|
if (save(FALSE))
|
|
{
|
|
if (_autoins_caller.not_empty())
|
|
{
|
|
k = K_QUIT;
|
|
}
|
|
else
|
|
{
|
|
if (save_and_new())
|
|
{
|
|
if (_mask->insert_mode())
|
|
insert_mode();
|
|
else
|
|
query_mode();
|
|
}
|
|
else
|
|
modify_mode();
|
|
}
|
|
}
|
|
break;
|
|
case K_INS:
|
|
if (_mask->query_mode() || save(TRUE))
|
|
{
|
|
const bool trovato = _mask->query_mode() && test_key(1, FALSE) && find(1);
|
|
if (trovato)
|
|
{
|
|
modify_mode();
|
|
warning_box("Documento gia' presente");
|
|
}
|
|
else
|
|
insert_mode();
|
|
}
|
|
break;
|
|
case K_DEL:
|
|
if (relation_remove())
|
|
query_mode();
|
|
if (_autoins_caller.not_empty())
|
|
{
|
|
if (_lnflag) _recins = 0;
|
|
k = K_QUIT;
|
|
}
|
|
break;
|
|
case K_F9:
|
|
if (_mask->query_mode() || save(TRUE))
|
|
search_mode();
|
|
break;
|
|
default:
|
|
if (save(TRUE))
|
|
{
|
|
setkey();
|
|
int err = ~NOERR;
|
|
switch (k)
|
|
{
|
|
case K_HOME:
|
|
err = file().readat(_first, _testandlock);
|
|
break;
|
|
case K_NEXT:
|
|
err = file().reread();
|
|
err = file().next(_testandlock);
|
|
break;
|
|
case K_PREV:
|
|
err = file().reread();
|
|
err = file().prev(_testandlock);
|
|
break;
|
|
case K_END:
|
|
err = file().readat(_last, _testandlock);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
if (err == NOERR || err == _islocked) modify_mode();
|
|
else query_mode();
|
|
}
|
|
break;
|
|
}
|
|
} while (k != K_QUIT);
|
|
|
|
if (_mask->is_open())
|
|
_mask->close_modal();
|
|
|
|
_mask->set_mode(NO_MODE);
|
|
|
|
if (autoins_caller().not_empty() && _recins >= 0)
|
|
{
|
|
TMessage msg(autoins_caller(), _lnflag ? MSG_LN : MSG_AI, format("%ld", _recins));
|
|
msg.send();
|
|
}
|
|
|
|
return k != K_QUIT;
|
|
}
|
|
|
|
bool TRelation_application::filter()
|
|
{
|
|
TMailbox mail;
|
|
TMessage* msg = mail.next_s(MSG_FS);
|
|
|
|
if (msg)
|
|
{
|
|
_mask = get_mask(MODE_MOD);
|
|
TToken_string body(msg->body());
|
|
|
|
short id = body.get_int();
|
|
while (id > 0)
|
|
{
|
|
_search_id = id;
|
|
TEdit_field& f = (TEdit_field&)_mask->field(id);
|
|
TCursor* cur = f.browse()->cursor();
|
|
TRectype& rec = cur->curr();
|
|
rec.zero();
|
|
|
|
TString80 t;
|
|
const char* s;
|
|
while((s = body.get()) != NULL)
|
|
{
|
|
t = s;
|
|
const int u = t.find('=');
|
|
if (u < 0)
|
|
{
|
|
id = atoi(t);
|
|
break;
|
|
}
|
|
_fixed.add(t);
|
|
const short fid = atoi(t.left(u));
|
|
const TFieldref* campo = _mask->field(fid).field();
|
|
if (campo != NULL)
|
|
campo->write(t.mid(u+1), rec);
|
|
}
|
|
cur->setfilter("");
|
|
cur->setregion(rec, rec);
|
|
if (s == NULL) id = 0;
|
|
}
|
|
}
|
|
|
|
mail.restart();
|
|
msg = mail.next_s(MSG_AI);
|
|
if (msg) _autoins_caller = msg->from();
|
|
|
|
mail.restart();
|
|
msg = mail.next_s(MSG_LN);
|
|
if (msg)
|
|
{
|
|
TToken_string body(msg->body());
|
|
const int key = body.get_int();
|
|
|
|
_autoins_caller = msg->from();
|
|
_lnflag = TRUE;
|
|
|
|
const char* v = body.get();
|
|
TString80 s;
|
|
for (int i = 0; v != NULL && i < _mask->fields(); i++)
|
|
{
|
|
TMask_field& f = _mask->fld(i);
|
|
|
|
if (f.active() && f.dlg() > 0 && f.in_key(key))
|
|
{
|
|
s = v;
|
|
_fixed.add(format("%d=%s", f.dlg(), (const char*)s));
|
|
v = body.get();
|
|
}
|
|
}
|
|
}
|
|
|
|
mail.restart();
|
|
msg = mail.next_s(MSG_ED);
|
|
if (msg)
|
|
{
|
|
TToken_string body(msg->body());
|
|
const int key = body.get_int();
|
|
|
|
_autoins_caller = msg->from();
|
|
_lnflag = 2;
|
|
|
|
TAssoc_array field_values;
|
|
const char * s;
|
|
TString80 t;
|
|
|
|
while((s = body.get()) != NULL)
|
|
{
|
|
t = s;
|
|
const int u = t.find('=');
|
|
|
|
CHECKS(u > 0, "Invalid edit message ", (const char *) body);
|
|
if (u > 0)
|
|
{
|
|
const TString v(t.mid(u + 1));
|
|
|
|
t.cut(u);
|
|
field_values.add(t, v);
|
|
}
|
|
}
|
|
|
|
for (int i = 0; i < _mask->fields(); i++)
|
|
{
|
|
TMask_field& f = _mask->fld(i);
|
|
const TFieldref * field = f.field();
|
|
|
|
if (field && f.in_key(key))
|
|
{
|
|
TString16 field_name(field->name());
|
|
const int from = field->from();
|
|
const int to = field->to();
|
|
|
|
if (to >= 0)
|
|
field_name << "[" << (from + 1);
|
|
const TString * v = (const TString *) field_values.objptr(field_name);
|
|
|
|
TString val;
|
|
if (v == NULL && to >= 0)
|
|
{
|
|
v = (const TString *)field_values.objptr(field->name());
|
|
if (v)
|
|
val = v->sub(from, to);
|
|
}
|
|
else
|
|
if (v) val = *v;
|
|
|
|
if (v)
|
|
_fixed.add(format("%d=%s", f.dlg(), (const char*)val));
|
|
}
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void TRelation_application::set_link(TMask & m, const char * keyexpr)
|
|
|
|
{
|
|
CHECK(keyexpr != NULL, "Invalid expression");
|
|
TToken_string body(keyexpr);
|
|
const int key = body.get_int();
|
|
|
|
_lnflag = TRUE;
|
|
|
|
const char* v = body.get();
|
|
|
|
const int max = m.fields();
|
|
for (int i = 0; i < max && v != NULL; i++)
|
|
{
|
|
TMask_field& f = m.fld(i);
|
|
|
|
if (f.active() && f.dlg() > 0 && f.in_key(key))
|
|
{
|
|
const TString s(v);
|
|
_fixed.add(format("%d=%s", f.dlg(), (const char*) s));
|
|
v = body.get();
|
|
}
|
|
}
|
|
}
|
|
|
|
|