Patch level : 10.0 274
Files correlati : ca2.exe Ricompilazione Demo : [ ] Commento : Corretto comportamento dei sorted_cursor per le maschere. Ora la ricerca viene fatta sulla chiave di sort. Aggiunta modalità batch delle transazioni. Viene generato un log e l'esecuzione non viene interrotta da segnalazioni ( Da collaudare meglio alla prima occasione). Resa possibile la visualizzazione di record bloccati da un altro utente. Queste funzionalità sono presenti nelle relapp dall patch 274 e successive. git-svn-id: svn://10.65.10.50/branches/R_10_00@23210 c028cbd2-c16b-5b4b-a496-9718f37d4682
This commit is contained in:
parent
3469b56f48
commit
24ed90d54e
@ -1,6 +1,8 @@
|
|||||||
#include <dongle.h>
|
#include <dongle.h>
|
||||||
#include <execp.h>
|
#include <execp.h>
|
||||||
|
#include <expr.h>
|
||||||
#include <msksheet.h>
|
#include <msksheet.h>
|
||||||
|
#include <postman.h>
|
||||||
#include <recarray.h>
|
#include <recarray.h>
|
||||||
#include <recset.h>
|
#include <recset.h>
|
||||||
#include <relapp.h>
|
#include <relapp.h>
|
||||||
@ -385,6 +387,67 @@ bool TBrowse::parse_copy(const TString& what, const TBrowse& b)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TBrowse::update_filter(TEdit_field * f)
|
||||||
|
{
|
||||||
|
if (!f->in_key(0))
|
||||||
|
{
|
||||||
|
TString rf = get_user_read_filter(); rf.trim();
|
||||||
|
|
||||||
|
if (rf.not_empty())
|
||||||
|
{
|
||||||
|
TExpression e(rf);
|
||||||
|
bool ok = true;
|
||||||
|
|
||||||
|
for (int i = e.numvar()-1; ok && i >= 0; i--)
|
||||||
|
{
|
||||||
|
TString s = e.varname(i);
|
||||||
|
TString id;
|
||||||
|
int fileid = 0;
|
||||||
|
int pos = s.find("->");
|
||||||
|
|
||||||
|
if (pos > 0)
|
||||||
|
{
|
||||||
|
id = s.left(pos); id.strip(" ");
|
||||||
|
fileid = name2log(id);
|
||||||
|
pos += 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pos = s.find('.');
|
||||||
|
if (pos > 0)
|
||||||
|
{
|
||||||
|
id = s.left(pos); id.strip(" ");
|
||||||
|
fileid = name2log(id);
|
||||||
|
pos++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
pos = 0;
|
||||||
|
}
|
||||||
|
if (fileid < CNF_GENERAL)
|
||||||
|
{
|
||||||
|
s.ltrim(pos);
|
||||||
|
int par = s.find('[', pos);
|
||||||
|
|
||||||
|
if (par >= 0)
|
||||||
|
s.cut(par);
|
||||||
|
TRelation * r = cursor()->relation();
|
||||||
|
ok = (fileid == 0 && r->curr().exist(s)) || (r->log2ind(fileid) >= 0 && r->curr(fileid).exist(s));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ok)
|
||||||
|
{
|
||||||
|
if (_filter.blank())
|
||||||
|
_filter = rf;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_filter.insert("(", 0);
|
||||||
|
_filter << ")&&(" << rf << ')';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void TBrowse::replace_cursor(TCursor* c)
|
void TBrowse::replace_cursor(TCursor* c)
|
||||||
{
|
{
|
||||||
if (_relation != NULL)
|
if (_relation != NULL)
|
||||||
|
@ -213,6 +213,9 @@ public:
|
|||||||
// @cmember Aggiorna la lista completa degli identificatori dei campi di output da un campo
|
// @cmember Aggiorna la lista completa degli identificatori dei campi di output da un campo
|
||||||
void copy_output(const TBrowse * b);
|
void copy_output(const TBrowse * b);
|
||||||
|
|
||||||
|
// @cmember Aggiorna il filtro con l'espressione per l'utente
|
||||||
|
void update_filter(TEdit_field * f);
|
||||||
|
|
||||||
// @cmember Cambia il cursore senza darne il possesso (come nella COPY USE)
|
// @cmember Cambia il cursore senza darne il possesso (come nella COPY USE)
|
||||||
void replace_cursor(TCursor* c);
|
void replace_cursor(TCursor* c);
|
||||||
|
|
||||||
|
@ -3,8 +3,44 @@
|
|||||||
#include <diction.h>
|
#include <diction.h>
|
||||||
#include <dongle.h>
|
#include <dongle.h>
|
||||||
#include <keys.h>
|
#include <keys.h>
|
||||||
|
#include <strings.h>
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
#define buildmsg() char msg[1024];va_list argptr;va_start(argptr,fmt);_vsnprintf_s(msg,sizeof(msg),_TRUNCATE,fmt,argptr);va_end(argptr);msg[1023] = '\0';
|
||||||
|
#else
|
||||||
|
#define buildmsg() char msg[1024];va_list argptr;va_start(argptr,fmt);vsprintf(msg,fmt,argptr);va_end(argptr)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static bool __batch = false;
|
||||||
|
TString_array __errors;
|
||||||
|
TString_array __warnings;
|
||||||
|
|
||||||
|
bool is_batch()
|
||||||
|
{
|
||||||
|
return __batch;
|
||||||
|
}
|
||||||
|
|
||||||
|
void batch(bool on)
|
||||||
|
{
|
||||||
|
__batch = on;
|
||||||
|
if (on)
|
||||||
|
{
|
||||||
|
__errors.destroy();
|
||||||
|
__warnings.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TString_array & errors()
|
||||||
|
{
|
||||||
|
return __errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
TString_array & warnings()
|
||||||
|
{
|
||||||
|
return __warnings;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#define buildmsg() char msg[1024];va_list argptr;va_start(argptr,fmt);vsnprintf_s(msg,sizeof(msg),_TRUNCATE,fmt,argptr);va_end(argptr);
|
|
||||||
|
|
||||||
// @doc EXTERNAL
|
// @doc EXTERNAL
|
||||||
|
|
||||||
@ -15,6 +51,9 @@ bool fatal_box(
|
|||||||
// @comm Il programma viene interrotto al momento in cui si e' verificato l'errore.
|
// @comm Il programma viene interrotto al momento in cui si e' verificato l'errore.
|
||||||
{
|
{
|
||||||
buildmsg();
|
buildmsg();
|
||||||
|
if (__batch)
|
||||||
|
__errors.add(msg);
|
||||||
|
else
|
||||||
xvt_dm_post_fatal_exit(msg);
|
xvt_dm_post_fatal_exit(msg);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -29,6 +68,9 @@ bool error_box(
|
|||||||
// e l'icona punto esclamativo.
|
// e l'icona punto esclamativo.
|
||||||
{
|
{
|
||||||
buildmsg();
|
buildmsg();
|
||||||
|
if (__batch)
|
||||||
|
__errors.add(msg);
|
||||||
|
else
|
||||||
xvt_dm_post_error(msg);
|
xvt_dm_post_error(msg);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -42,6 +84,9 @@ bool warning_box(
|
|||||||
// e l'icona punto di domanda.
|
// e l'icona punto di domanda.
|
||||||
{
|
{
|
||||||
buildmsg();
|
buildmsg();
|
||||||
|
if (__batch)
|
||||||
|
__warnings.add(msg);
|
||||||
|
else
|
||||||
xvt_dm_post_warning(msg);
|
xvt_dm_post_warning(msg);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -55,6 +100,9 @@ bool message_box(
|
|||||||
// e l'icona informazioni.
|
// e l'icona informazioni.
|
||||||
{
|
{
|
||||||
buildmsg();
|
buildmsg();
|
||||||
|
if (__batch)
|
||||||
|
__warnings.add(msg);
|
||||||
|
else
|
||||||
xvt_dm_post_message(msg);
|
xvt_dm_post_message(msg);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -68,6 +116,9 @@ bool sorry_box(
|
|||||||
// e l'icona informazioni.
|
// e l'icona informazioni.
|
||||||
{
|
{
|
||||||
buildmsg();
|
buildmsg();
|
||||||
|
if (__batch)
|
||||||
|
__warnings.add(msg);
|
||||||
|
else
|
||||||
xvt_dm_post_note(msg);
|
xvt_dm_post_note(msg);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -78,6 +129,11 @@ bool noyes_box(
|
|||||||
...) // @parmvar Uno o piu' parametri corrispondenti ai codici in <p fmt>
|
...) // @parmvar Uno o piu' parametri corrispondenti ai codici in <p fmt>
|
||||||
{
|
{
|
||||||
buildmsg();
|
buildmsg();
|
||||||
|
if (__batch)
|
||||||
|
{
|
||||||
|
__errors.add(msg);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
ASK_RESPONSE r = xvt_dm_post_ask("No", "Si", NULL, msg);
|
ASK_RESPONSE r = xvt_dm_post_ask("No", "Si", NULL, msg);
|
||||||
return r == RESP_DEFAULT;
|
return r == RESP_DEFAULT;
|
||||||
}
|
}
|
||||||
@ -88,6 +144,11 @@ int noyesall_box(
|
|||||||
...) // @parmvar Uno o piu' parametri corrispondenti ai codici in <p fmt>
|
...) // @parmvar Uno o piu' parametri corrispondenti ai codici in <p fmt>
|
||||||
{
|
{
|
||||||
buildmsg();
|
buildmsg();
|
||||||
|
if (__batch)
|
||||||
|
{
|
||||||
|
__errors.add(msg);
|
||||||
|
return K_NO;
|
||||||
|
}
|
||||||
ASK_RESPONSE r = xvt_dm_post_ask("No", "Si", "Si Tutti", msg);
|
ASK_RESPONSE r = xvt_dm_post_ask("No", "Si", "Si Tutti", msg);
|
||||||
return r == RESP_DEFAULT ? K_YES : (r == RESP_2 ? K_NO : K_SPACE);
|
return r == RESP_DEFAULT ? K_YES : (r == RESP_2 ? K_NO : K_SPACE);
|
||||||
}
|
}
|
||||||
@ -106,6 +167,11 @@ bool yesno_box(
|
|||||||
// @flag 0 | Se viene premuto il taso NO
|
// @flag 0 | Se viene premuto il taso NO
|
||||||
{
|
{
|
||||||
buildmsg();
|
buildmsg();
|
||||||
|
if (__batch)
|
||||||
|
{
|
||||||
|
__errors.add(msg);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
ASK_RESPONSE r = xvt_dm_post_ask("Si", "No", NULL, msg);
|
ASK_RESPONSE r = xvt_dm_post_ask("Si", "No", NULL, msg);
|
||||||
return r == RESP_DEFAULT;
|
return r == RESP_DEFAULT;
|
||||||
}
|
}
|
||||||
@ -116,6 +182,11 @@ int yesnoall_box(
|
|||||||
...) // @parmvar Uno o piu' parametri corrispondenti ai codici in <p fmt>
|
...) // @parmvar Uno o piu' parametri corrispondenti ai codici in <p fmt>
|
||||||
{
|
{
|
||||||
buildmsg();
|
buildmsg();
|
||||||
|
if (__batch)
|
||||||
|
{
|
||||||
|
__errors.add(msg);
|
||||||
|
return K_NO;
|
||||||
|
}
|
||||||
ASK_RESPONSE r = xvt_dm_post_ask("No", "Si", "No Tutti", msg);
|
ASK_RESPONSE r = xvt_dm_post_ask("No", "Si", "No Tutti", msg);
|
||||||
return r == RESP_DEFAULT ? K_NO : (r == RESP_2 ? K_YES : K_SPACE);
|
return r == RESP_DEFAULT ? K_NO : (r == RESP_2 ? K_YES : K_SPACE);
|
||||||
}
|
}
|
||||||
@ -170,6 +241,11 @@ int yesnocancel_box(
|
|||||||
// @xref <m yesno_box> <m yesnofatal_box>
|
// @xref <m yesno_box> <m yesnofatal_box>
|
||||||
{
|
{
|
||||||
buildmsg();
|
buildmsg();
|
||||||
|
if (__batch)
|
||||||
|
{
|
||||||
|
__errors.add(msg);
|
||||||
|
return K_NO;
|
||||||
|
}
|
||||||
ASK_RESPONSE r = xvt_dm_post_ask("Si", "No", "Annulla", msg);
|
ASK_RESPONSE r = xvt_dm_post_ask("Si", "No", "Annulla", msg);
|
||||||
return r == RESP_DEFAULT ? K_YES : (r == RESP_2 ? K_NO : K_ESC);
|
return r == RESP_DEFAULT ? K_YES : (r == RESP_2 ? K_NO : K_ESC);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,12 @@
|
|||||||
#ifndef __CHECKS_H
|
#ifndef __CHECKS_H
|
||||||
#define __CHECKS_H
|
#define __CHECKS_H
|
||||||
|
|
||||||
|
#ifndef __STDTYPES_H
|
||||||
|
#include <stdtypes.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class TString_array;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
@ -21,6 +27,11 @@ extern "C" {
|
|||||||
bool cantaccess_box(const char* filename);
|
bool cantaccess_box(const char* filename);
|
||||||
bool __trace(const char* fmt, ...);
|
bool __trace(const char* fmt, ...);
|
||||||
bool __tracemem(const char* fmt);
|
bool __tracemem(const char* fmt);
|
||||||
|
|
||||||
|
void batch(bool on = true);
|
||||||
|
bool is_batch();
|
||||||
|
TString_array & errors();
|
||||||
|
TString_array & warnings();
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -90,7 +90,7 @@ WINDOW TMask::curr_win() const
|
|||||||
return page_win(_page > 0 && _page < _pages ? _page : 0);
|
return page_win(_page > 0 && _page < _pages ? _page : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
TMask::TMask() : _mask_num(0)
|
TMask::TMask() : _mask_num(0), _sheet_first_selection_row(-1)
|
||||||
{ init_mask(); }
|
{ init_mask(); }
|
||||||
|
|
||||||
TMask::TMask(const char* title, int pages, int cols, int rows,
|
TMask::TMask(const char* title, int pages, int cols, int rows,
|
||||||
@ -870,6 +870,13 @@ long TMask::handler(WINDOW w, EVENT* ep)
|
|||||||
case 2: _last_sheet->reset_columns_order(); break;
|
case 2: _last_sheet->reset_columns_order(); break;
|
||||||
case 3: _last_sheet->on_key(K_F11); break;
|
case 3: _last_sheet->on_key(K_F11); break;
|
||||||
case 4: _last_sheet->esporta(); break;
|
case 4: _last_sheet->esporta(); break;
|
||||||
|
case 5: _last_sheet->clear_range_selection(); break;
|
||||||
|
case 6:
|
||||||
|
_last_sheet->select_range(_sheet_first_selection_row);
|
||||||
|
_sheet_first_selection_row = -1;
|
||||||
|
break;
|
||||||
|
case 7: _last_sheet->copy_rows(); break;
|
||||||
|
case 8: _last_sheet->paste_rows(); break;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
return 0L;
|
return 0L;
|
||||||
@ -2688,8 +2695,26 @@ void TMask::post_error_message(const char* msg, int sev)
|
|||||||
return; // Ignora messaggio duplicato;
|
return; // Ignora messaggio duplicato;
|
||||||
on_idle();
|
on_idle();
|
||||||
}
|
}
|
||||||
|
if (is_batch())
|
||||||
|
{
|
||||||
|
if (sev > 2)
|
||||||
|
errors().add(msg);
|
||||||
|
else
|
||||||
|
warnings().add(msg);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
_error_message = msg;
|
_error_message = msg;
|
||||||
_error_severity = sev;
|
_error_severity = sev;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
KEY TMask::check_mask()
|
||||||
|
|
||||||
|
// @comm Se la finestra non era aperta la apre in modo modale
|
||||||
|
{
|
||||||
|
start_run();
|
||||||
|
return stop_run(K_ENTER) ? K_ENTER : K_ESC;
|
||||||
}
|
}
|
||||||
|
|
||||||
// @doc INTERNAL
|
// @doc INTERNAL
|
||||||
|
@ -98,6 +98,9 @@ class TMask : public TWindow
|
|||||||
// @cmember:(INTERNAL) Puntatore allo sheet che contiene la maschera (puo' essere NULL)
|
// @cmember:(INTERNAL) Puntatore allo sheet che contiene la maschera (puo' essere NULL)
|
||||||
TSheet_field* _sheet;
|
TSheet_field* _sheet;
|
||||||
|
|
||||||
|
// @cmember:(INTERNAL) Numero della prima riga di selezione nello sheet
|
||||||
|
long _sheet_first_selection_row;
|
||||||
|
|
||||||
// @cmember:(INTERNAL) Handler per gestire i tasti speciali nelle maschere
|
// @cmember:(INTERNAL) Handler per gestire i tasti speciali nelle maschere
|
||||||
MASK_HANDLER _handler;
|
MASK_HANDLER _handler;
|
||||||
|
|
||||||
@ -475,6 +478,8 @@ public:
|
|||||||
{ return _toolwin; }
|
{ return _toolwin; }
|
||||||
WINDOW toolbar() const
|
WINDOW toolbar() const
|
||||||
{ return _toolbar; }
|
{ return _toolbar; }
|
||||||
|
// @cmember verifica la mascher senza eseguirla
|
||||||
|
KEY check_mask();
|
||||||
};
|
};
|
||||||
|
|
||||||
// @doc EXTERNAL
|
// @doc EXTERNAL
|
||||||
|
@ -805,6 +805,15 @@ bool TMask_field::yesno_box(const char* fmt, ...) const
|
|||||||
return yes;
|
return yes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool TMask_field::noyes_box(const char* fmt, ...) const
|
||||||
|
{
|
||||||
|
set_focus();
|
||||||
|
build_msg();
|
||||||
|
const bool yes = ::noyes_box("%s", _msg);
|
||||||
|
set_focus();
|
||||||
|
return yes;
|
||||||
|
}
|
||||||
|
|
||||||
KEY TMask_field::yesnocancel_box(const char* fmt, ...) const
|
KEY TMask_field::yesnocancel_box(const char* fmt, ...) const
|
||||||
{
|
{
|
||||||
set_focus();
|
set_focus();
|
||||||
@ -2035,7 +2044,6 @@ word TEdit_field::class_id() const
|
|||||||
|
|
||||||
void TEdit_field::set_len(short w)
|
void TEdit_field::set_len(short w)
|
||||||
{
|
{
|
||||||
CHECKD(w > 0 && w <= 50, "Invalid field length ", w);
|
|
||||||
_size = w;
|
_size = w;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2256,7 +2264,7 @@ bool TEdit_field::parse_item(TScanner& scanner)
|
|||||||
scanner.line();
|
scanner.line();
|
||||||
}
|
}
|
||||||
scanner.push();
|
scanner.push();
|
||||||
|
browse()->update_filter(this);
|
||||||
if (tablename.full())
|
if (tablename.full())
|
||||||
{
|
{
|
||||||
tablename.insert("MTB", 0);
|
tablename.insert("MTB", 0);
|
||||||
|
@ -256,6 +256,9 @@ public:
|
|||||||
// @cmember Ritorna true se si tratta di campo fantasma
|
// @cmember Ritorna true se si tratta di campo fantasma
|
||||||
bool ghost() const
|
bool ghost() const
|
||||||
{ return _flags.ghost; }
|
{ return _flags.ghost; }
|
||||||
|
// @cmember Ritorna true se il campo e' un numero romano
|
||||||
|
bool persistent() const
|
||||||
|
{ return _flags.persistent; }
|
||||||
|
|
||||||
// @cmember Controlla se il campo appartiene ad una chiave di ricerca
|
// @cmember Controlla se il campo appartiene ad una chiave di ricerca
|
||||||
virtual bool in_key(word) const
|
virtual bool in_key(word) const
|
||||||
@ -403,6 +406,8 @@ public:
|
|||||||
virtual bool error_box(const char* fmt, ...) const;
|
virtual bool error_box(const char* fmt, ...) const;
|
||||||
// @cmember Crea una yesno-box relativamente al campo (chiama <f yesno_box>)
|
// @cmember Crea una yesno-box relativamente al campo (chiama <f yesno_box>)
|
||||||
virtual bool yesno_box(const char* fmt, ...) const;
|
virtual bool yesno_box(const char* fmt, ...) const;
|
||||||
|
// @cmember Crea una noyes-box relativamente al campo (chiama <f yesno_box>)
|
||||||
|
virtual bool noyes_box(const char* fmt, ...) const;
|
||||||
// @cmember Crea una yesnocancel-box relativamente al campo (chiama <f yesnocancel_box>)
|
// @cmember Crea una yesnocancel-box relativamente al campo (chiama <f yesnocancel_box>)
|
||||||
virtual KEY yesnocancel_box(const char* fmt, ...) const;
|
virtual KEY yesnocancel_box(const char* fmt, ...) const;
|
||||||
|
|
||||||
|
@ -25,6 +25,11 @@ class TCell_property : public TObject
|
|||||||
public:
|
public:
|
||||||
void set(COLOR back, COLOR fore) { _back = back; _fore = fore; }
|
void set(COLOR back, COLOR fore) { _back = back; _fore = fore; }
|
||||||
bool get(COLOR& back, COLOR& fore) const;
|
bool get(COLOR& back, COLOR& fore) const;
|
||||||
|
|
||||||
|
virtual TCell_property & copy(const TCell_property & p);
|
||||||
|
virtual TObject* dup() const { return new TCell_property(*this); }
|
||||||
|
|
||||||
|
TCell_property(const TCell_property & p);
|
||||||
TCell_property();
|
TCell_property();
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -39,6 +44,19 @@ bool TCell_property::get(COLOR& back, COLOR& fore) const
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TCell_property & TCell_property::copy(const TCell_property & p)
|
||||||
|
{
|
||||||
|
_back = p._back;
|
||||||
|
_fore = p._fore;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
TCell_property::TCell_property(const TCell_property & p)
|
||||||
|
{
|
||||||
|
copy
|
||||||
|
(p);
|
||||||
|
}
|
||||||
|
|
||||||
TCell_property::TCell_property() : _back(COLOR_INVALID), _fore(COLOR_INVALID)
|
TCell_property::TCell_property() : _back(COLOR_INVALID), _fore(COLOR_INVALID)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
@ -58,10 +76,33 @@ public:
|
|||||||
|
|
||||||
TBit_array & disabled() { return _disabled;}
|
TBit_array & disabled() { return _disabled;}
|
||||||
const TBit_array & disabled() const { return _disabled;}
|
const TBit_array & disabled() const { return _disabled;}
|
||||||
|
|
||||||
|
virtual TRow_property & copy(const TRow_property & r);
|
||||||
|
virtual TObject* dup() const { return new TRow_property(*this); }
|
||||||
|
|
||||||
|
TRow_property(const TRow_property & p);
|
||||||
TRow_property();
|
TRow_property();
|
||||||
virtual ~TRow_property() { }
|
virtual ~TRow_property() { }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
TRow_property & TRow_property::copy(const TRow_property & p)
|
||||||
|
{
|
||||||
|
_disabled = p._disabled;
|
||||||
|
_back = p._back;
|
||||||
|
_fore = p._fore;
|
||||||
|
_height = p._height;
|
||||||
|
if (p._cell_prop != NULL)
|
||||||
|
_cell_prop = new TArray(*p._cell_prop);
|
||||||
|
else
|
||||||
|
_cell_prop = NULL;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
TRow_property::TRow_property(const TRow_property & p)
|
||||||
|
{
|
||||||
|
copy(p);
|
||||||
|
}
|
||||||
|
|
||||||
TRow_property::TRow_property()
|
TRow_property::TRow_property()
|
||||||
: _back(COLOR_INVALID), _fore(COLOR_INVALID), _height(-1), _cell_prop(NULL)
|
: _back(COLOR_INVALID), _fore(COLOR_INVALID), _height(-1), _cell_prop(NULL)
|
||||||
{ }
|
{ }
|
||||||
@ -146,13 +187,18 @@ class TSpreadsheet : public TControl
|
|||||||
|
|
||||||
// @cmember:(INTERNAL) Array di TToken_strings contenenti le righe
|
// @cmember:(INTERNAL) Array di TToken_strings contenenti le righe
|
||||||
TString_array _str;
|
TString_array _str;
|
||||||
|
// @cmember:(INTERNAL) Array di TToken_strings contenenti le righe copiate
|
||||||
|
TString_array _copied_rows;
|
||||||
// @cmember:(INTERNAL) Array delle colonne disattivate (solo visualizzazione)
|
// @cmember:(INTERNAL) Array delle colonne disattivate (solo visualizzazione)
|
||||||
TBit_array _column_disabled;
|
TBit_array _column_disabled;
|
||||||
|
|
||||||
|
// @cmember:(INTERNAL) righe selezionate
|
||||||
|
int _from;
|
||||||
|
int _to;
|
||||||
|
|
||||||
// @cmember:(INTERNAL) Array delle proprieta' delle righe
|
// @cmember:(INTERNAL) Array delle proprieta' delle righe
|
||||||
TArray _properties;
|
TArray _properties;
|
||||||
// @cmember:(INTERNAL) Array delle proprieta' standard di tutte le righe
|
TArray * _saved_properties;
|
||||||
TRow_property* _row_properties;
|
|
||||||
|
|
||||||
// @cmember:(INTERNAL) Maschera in cui e' contenuto lo spreadsheet
|
// @cmember:(INTERNAL) Maschera in cui e' contenuto lo spreadsheet
|
||||||
TMask _mask;
|
TMask _mask;
|
||||||
@ -403,6 +449,12 @@ public:
|
|||||||
|
|
||||||
bool point2cell(const PNT& pnt, short& id, long& row) const;
|
bool point2cell(const PNT& pnt, short& id, long& row) const;
|
||||||
|
|
||||||
|
bool get_range_selection(int & from, int & to) const ;
|
||||||
|
void clear_range_selection();
|
||||||
|
void select_range(int row);
|
||||||
|
void copy_rows();
|
||||||
|
void paste_rows();
|
||||||
|
|
||||||
// @cmember Costruttore
|
// @cmember Costruttore
|
||||||
TSpreadsheet(WINDOW parent, short dlg, short x, short y, short dx, short dy, const char* maskname, int maskno, const char* head, TSheet_field* owner);
|
TSpreadsheet(WINDOW parent, short dlg, short x, short y, short dx, short dy, const char* maskname, int maskno, const char* head, TSheet_field* owner);
|
||||||
// @cmember Distruttore
|
// @cmember Distruttore
|
||||||
@ -436,8 +488,8 @@ TSpreadsheet::TSpreadsheet(
|
|||||||
_edit_field(NULL), _cur_row(0), _cur_rec(0), _cur_col(1),
|
_edit_field(NULL), _cur_row(0), _cur_rec(0), _cur_col(1),
|
||||||
_row_dirty(false), _cell_dirty(false), _check_enabled(true),
|
_row_dirty(false), _cell_dirty(false), _check_enabled(true),
|
||||||
_needs_update(-1), _selection_posted(-1), _ignore_button(0), _save_columns_order(false),
|
_needs_update(-1), _selection_posted(-1), _ignore_button(0), _save_columns_order(false),
|
||||||
_f9_target(NULL), _auto_append(false), _first_nav_column_id(-1),_last_nav_column_id(-1),
|
_f9_target(NULL), _auto_append(false), _first_nav_column_id(-1), _last_nav_column_id(-1),
|
||||||
_row_properties(NULL)
|
_from(-1), _to(-1), _saved_properties(NULL)
|
||||||
{
|
{
|
||||||
int m_width[MAX_COL], v_width[MAX_COL];
|
int m_width[MAX_COL], v_width[MAX_COL];
|
||||||
int fixed_cols = 0; // Number of fixed columns
|
int fixed_cols = 0; // Number of fixed columns
|
||||||
@ -512,6 +564,15 @@ TSpreadsheet::TSpreadsheet(
|
|||||||
|
|
||||||
XI_OBJ* itf = get_interface(parent);
|
XI_OBJ* itf = get_interface(parent);
|
||||||
XI_RCT rct = coord2rct(itf, x, y, dx, dy);
|
XI_RCT rct = coord2rct(itf, x, y, dx, dy);
|
||||||
|
|
||||||
|
if (x > 0 && dx < 0)
|
||||||
|
{
|
||||||
|
RCT max_rct; xvt_vobj_get_client_rect((WINDOW)xi_get_window(itf), &max_rct);
|
||||||
|
const short MAXX = max_rct.right;
|
||||||
|
|
||||||
|
if (MAXX > 80 * CHARX)
|
||||||
|
rct.left += (MAXX - 80 * CHARX) / 2;
|
||||||
|
}
|
||||||
rct.right -= 2*XI_FU_MULTIPLE; // toglie scroll-bar
|
rct.right -= 2*XI_FU_MULTIPLE; // toglie scroll-bar
|
||||||
|
|
||||||
// Controlla se posso bloccare anche questa colonna
|
// Controlla se posso bloccare anche questa colonna
|
||||||
@ -547,6 +608,9 @@ TSpreadsheet::TSpreadsheet(
|
|||||||
l->active_back_color = FOCUS_BACK_COLOR;
|
l->active_back_color = FOCUS_BACK_COLOR;
|
||||||
l->white_space_color = MASK_DARK_COLOR;
|
l->white_space_color = MASK_DARK_COLOR;
|
||||||
l->rule_color = MASK_DARK_COLOR;
|
l->rule_color = MASK_DARK_COLOR;
|
||||||
|
#ifdef LINUX
|
||||||
|
l->scroll_on_thumb_track = true;
|
||||||
|
#endif
|
||||||
|
|
||||||
// Definizione della prima colonna (numero di riga)
|
// Definizione della prima colonna (numero di riga)
|
||||||
word attr = XI_ATR_RJUST;
|
word attr = XI_ATR_RJUST;
|
||||||
@ -640,7 +704,8 @@ TSpreadsheet::TSpreadsheet(
|
|||||||
|
|
||||||
TSpreadsheet::~TSpreadsheet()
|
TSpreadsheet::~TSpreadsheet()
|
||||||
{
|
{
|
||||||
delete _row_properties;
|
if (_saved_properties != NULL)
|
||||||
|
delete _saved_properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
TMask& TSpreadsheet::sheet_mask() const
|
TMask& TSpreadsheet::sheet_mask() const
|
||||||
@ -2346,21 +2411,15 @@ void TSpreadsheet::set_row_height(const int row, const int height)
|
|||||||
TRow_property* TSpreadsheet::get_property(int row, bool create)
|
TRow_property* TSpreadsheet::get_property(int row, bool create)
|
||||||
{
|
{
|
||||||
if (row < 0)
|
if (row < 0)
|
||||||
{
|
row = 0;
|
||||||
if (_row_properties == NULL && create)
|
|
||||||
_row_properties = new TRow_property;
|
|
||||||
return _row_properties;
|
|
||||||
}
|
|
||||||
|
|
||||||
TRow_property* p = (TRow_property*)_properties.objptr(row);
|
TRow_property* p = (TRow_property*)_properties.objptr(row);
|
||||||
if (p == NULL)
|
|
||||||
{
|
if (p == NULL && create)
|
||||||
if (create)
|
|
||||||
{
|
{
|
||||||
p = new TRow_property;
|
p = new TRow_property;
|
||||||
_properties.add(p, row);
|
_properties.add(p, row);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2639,6 +2698,11 @@ bool TSpreadsheet::error_box(const char* msg)
|
|||||||
const int r = _cur_row;
|
const int r = _cur_row;
|
||||||
const int c = _cur_col;
|
const int c = _cur_col;
|
||||||
|
|
||||||
|
if (is_batch())
|
||||||
|
{
|
||||||
|
errors().add(msg);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (ADVANCED_GRAPHICS && ANIMATED_BOXES)
|
if (ADVANCED_GRAPHICS && ANIMATED_BOXES)
|
||||||
xvt_dm_popup_error(msg);
|
xvt_dm_popup_error(msg);
|
||||||
else
|
else
|
||||||
@ -2691,6 +2755,101 @@ bool TSpreadsheet::point2cell(const PNT& pnt, short& id, long& row) const
|
|||||||
return inside;
|
return inside;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool TSpreadsheet::get_range_selection(int & from, int & to) const
|
||||||
|
{
|
||||||
|
from = _from;
|
||||||
|
to = _to;
|
||||||
|
return _from >= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TSpreadsheet::clear_range_selection()
|
||||||
|
{
|
||||||
|
_from = _to = -1;
|
||||||
|
if (_saved_properties)
|
||||||
|
{
|
||||||
|
const int it = items();
|
||||||
|
for (int r = 0; r < it; r++)
|
||||||
|
{
|
||||||
|
TRow_property* prop = (TRow_property*)_saved_properties->objptr(r);
|
||||||
|
COLOR back = NORMAL_BACK_COLOR;
|
||||||
|
COLOR fore = NORMAL_COLOR;
|
||||||
|
|
||||||
|
if (prop != NULL)
|
||||||
|
prop->get(-1, back, fore);
|
||||||
|
set_back_and_fore_color(back, fore, r, -1);
|
||||||
|
}
|
||||||
|
delete _saved_properties;
|
||||||
|
_saved_properties = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TSpreadsheet::select_range(int row)
|
||||||
|
{
|
||||||
|
int from = _from;
|
||||||
|
int to = _to;
|
||||||
|
|
||||||
|
if (row < 0)
|
||||||
|
row = selected();
|
||||||
|
if (_saved_properties == NULL)
|
||||||
|
_saved_properties = new TArray(_properties);
|
||||||
|
|
||||||
|
if (_from < 0)
|
||||||
|
_from = _to = row;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (row < _from)
|
||||||
|
from = _from = row;
|
||||||
|
else
|
||||||
|
from = _to = row;
|
||||||
|
}
|
||||||
|
if (from < 0)
|
||||||
|
from = 0;
|
||||||
|
if (from >_from)
|
||||||
|
from = _from;
|
||||||
|
if (to < 0)
|
||||||
|
to = items();
|
||||||
|
if (to < _to)
|
||||||
|
to = _to;
|
||||||
|
for (int r = from; r <= to; r++)
|
||||||
|
{
|
||||||
|
TRow_property* prop = (TRow_property*)_saved_properties->objptr(r);
|
||||||
|
COLOR back = NORMAL_BACK_COLOR;
|
||||||
|
COLOR fore = NORMAL_COLOR;
|
||||||
|
|
||||||
|
if (prop != NULL)
|
||||||
|
prop->get(-1, back, fore);
|
||||||
|
if (r >= _from && r <= _to)
|
||||||
|
back = blend_colors(back, FOCUS_BACK_COLOR, 0.75);
|
||||||
|
set_back_and_fore_color(back, fore, r, -1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TSpreadsheet::copy_rows()
|
||||||
|
{
|
||||||
|
int from = _from > 0 ? _from : 0;
|
||||||
|
int to = _to < items() - 1 ? _to : items() - 1;
|
||||||
|
|
||||||
|
_copied_rows.destroy();
|
||||||
|
for (int i = from; i <= to; i++)
|
||||||
|
_copied_rows.add(_str.row(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
void TSpreadsheet::paste_rows()
|
||||||
|
{
|
||||||
|
int row = selected();
|
||||||
|
int nrows = _copied_rows.items();
|
||||||
|
|
||||||
|
if (row >= _str.items() - 1)
|
||||||
|
{
|
||||||
|
row = _str.items() - 1;
|
||||||
|
_str.add(_copied_rows.row(--nrows));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = nrows - 1; i >= 0; i--)
|
||||||
|
_str.insert(_copied_rows.row(i), row + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////
|
||||||
// TSheet_field
|
// TSheet_field
|
||||||
///////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////
|
||||||
@ -3692,6 +3851,47 @@ static TString& clean_white_space(TString& str)
|
|||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool TSheet_field::get_range_selection(int &from, int & to) const
|
||||||
|
{
|
||||||
|
TSpreadsheet* s = (TSpreadsheet*)_ctl;
|
||||||
|
|
||||||
|
return s->get_range_selection(from, to);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TSheet_field::clear_range_selection()
|
||||||
|
{
|
||||||
|
TSpreadsheet* s = (TSpreadsheet*)_ctl;
|
||||||
|
|
||||||
|
s->clear_range_selection();
|
||||||
|
force_update();
|
||||||
|
s->set_focus_cell(s->_cur_row, s->_cur_col);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TSheet_field::select_range(int row)
|
||||||
|
{
|
||||||
|
TSpreadsheet* s = (TSpreadsheet*)_ctl;
|
||||||
|
|
||||||
|
s->select_range(row);
|
||||||
|
force_update();
|
||||||
|
s->set_focus_cell(s->_cur_row, s->_cur_col);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TSheet_field::copy_rows()
|
||||||
|
{
|
||||||
|
TSpreadsheet* s = (TSpreadsheet*)_ctl;
|
||||||
|
|
||||||
|
s->copy_rows();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TSheet_field::paste_rows()
|
||||||
|
{
|
||||||
|
TSpreadsheet* s = (TSpreadsheet*)_ctl;
|
||||||
|
|
||||||
|
s->paste_rows();
|
||||||
|
on_key(K_CTRL + 'V');
|
||||||
|
force_update();
|
||||||
|
s->set_focus_cell(s->_cur_row, s->_cur_col);
|
||||||
|
}
|
||||||
///////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////
|
||||||
// TSheet_recordset
|
// TSheet_recordset
|
||||||
///////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////
|
||||||
|
@ -285,6 +285,12 @@ public:
|
|||||||
// @cmember Trasferisce i valori dalla riga alla maschera <p n>
|
// @cmember Trasferisce i valori dalla riga alla maschera <p n>
|
||||||
void update_mask(int n) { row2mask(n, row(n)); }
|
void update_mask(int n) { row2mask(n, row(n)); }
|
||||||
|
|
||||||
|
bool get_range_selection(int & from, int & to) const ;
|
||||||
|
void clear_range_selection();
|
||||||
|
void select_range(int row = -1);
|
||||||
|
void copy_rows();
|
||||||
|
void paste_rows();
|
||||||
|
|
||||||
bool esporta() const;
|
bool esporta() const;
|
||||||
|
|
||||||
// @cmember Restituisce il numero della colonna corrente
|
// @cmember Restituisce il numero della colonna corrente
|
||||||
|
@ -16,7 +16,8 @@
|
|||||||
|
|
||||||
TRelation_application::TRelation_application()
|
TRelation_application::TRelation_application()
|
||||||
: _mask(NULL), _search_id(-1), _lnflag(0),
|
: _mask(NULL), _search_id(-1), _lnflag(0),
|
||||||
_autodelete(0), _navigating(false)
|
_autodelete(0), _navigating(false),
|
||||||
|
_locked(false)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
TRelation_application::~TRelation_application()
|
TRelation_application::~TRelation_application()
|
||||||
@ -34,16 +35,22 @@ bool TRelation_application::has_filtered_cursor() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
TCursor& TRelation_application::get_filtered_cursor() const
|
TCursor * TRelation_application::get_filtered_cursor() const
|
||||||
{
|
{
|
||||||
|
if (has_filtered_cursor())
|
||||||
|
{
|
||||||
const TEdit_field& f = get_search_field();
|
const TEdit_field& f = get_search_field();
|
||||||
return *f.browse()->cursor();
|
|
||||||
|
return f.browse()->cursor();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TRelation_application::setkey()
|
void TRelation_application::setkey()
|
||||||
{
|
{
|
||||||
if (has_filtered_cursor())
|
if (has_filtered_cursor())
|
||||||
get_filtered_cursor().setkey();
|
get_filtered_cursor()->setkey();
|
||||||
else
|
else
|
||||||
file().setkey(1);
|
file().setkey(1);
|
||||||
}
|
}
|
||||||
@ -99,19 +106,19 @@ void TRelation_application::set_limits(
|
|||||||
if (f.browse() != NULL)
|
if (f.browse() != NULL)
|
||||||
f.browse()->do_input(true);
|
f.browse()->do_input(true);
|
||||||
|
|
||||||
TCursor& cur = get_filtered_cursor();
|
TCursor* cur = get_filtered_cursor();
|
||||||
cur.setkey();
|
cur->setkey();
|
||||||
if (cur.items() > 0)
|
if (cur->items() > 0)
|
||||||
{
|
{
|
||||||
TBaseisamfile& f = cur.file();
|
TBaseisamfile& f = cur->file();
|
||||||
if (what & 0x1)
|
if (what & 0x1)
|
||||||
{
|
{
|
||||||
cur = 0;
|
*cur = 0;
|
||||||
_first = f.recno();
|
_first = f.recno();
|
||||||
}
|
}
|
||||||
if (what & 0x2)
|
if (what & 0x2)
|
||||||
{
|
{
|
||||||
cur = cur.items() - 1;
|
*cur = cur->items() - 1;
|
||||||
_last = f.recno();
|
_last = f.recno();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -270,7 +277,7 @@ void TRelation_application::enable_query()
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool TRelation_application::can_I_write(const TRelation* rel) const
|
bool TRelation_application::can_I_write(const TRelation* rel) const
|
||||||
{ return user_can_write(rel); }
|
{ return !_locked && user_can_write(rel); }
|
||||||
|
|
||||||
bool TRelation_application::can_I_read(const TRelation* rel) const
|
bool TRelation_application::can_I_read(const TRelation* rel) const
|
||||||
{ return user_can_read(rel); }
|
{ return user_can_read(rel); }
|
||||||
@ -542,24 +549,30 @@ void TRelation_application::insert_mode()
|
|||||||
bool TRelation_application::modify_mode()
|
bool TRelation_application::modify_mode()
|
||||||
{
|
{
|
||||||
TRelation* rel = get_relation();
|
TRelation* rel = get_relation();
|
||||||
|
const TReclock block = can_I_write(rel) ? _testandlock : _nolock;
|
||||||
|
int err = rel->read(_isequal, block);
|
||||||
|
|
||||||
if (!can_I_read(rel))
|
if (!can_I_read(rel))
|
||||||
{
|
{
|
||||||
warning_box(TR("I dati non sono accessibili per l'utente %s"), (const char*)user());
|
warning_box(TR("I dati non sono accessibili per l'utente %s"), (const char*)user());
|
||||||
query_mode();
|
query_mode();
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
_locked = false;
|
||||||
const TReclock block = can_I_write(rel) ? _testandlock : _nolock;
|
|
||||||
int err = rel->read(_isequal, block);
|
|
||||||
if (err != NOERR)
|
if (err != NOERR)
|
||||||
{
|
{
|
||||||
if (err == _islocked)
|
if (err == _islocked)
|
||||||
message_box(TR("I dati sono giŕ usati da un altro utente"));
|
{
|
||||||
|
_locked = true;
|
||||||
|
message_box(TR("I dati sono già usati da un altro programma, scrittura disabilitata"));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
error_box(FR("Impossibile leggere i dati: errore %d"), err);
|
error_box(FR("Impossibile leggere i dati: errore %d"), err);
|
||||||
if (!is_transaction())
|
if (!is_transaction())
|
||||||
query_mode();
|
query_mode();
|
||||||
return FALSE;
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool changing = changing_mask(MODE_MOD);
|
const bool changing = changing_mask(MODE_MOD);
|
||||||
@ -890,7 +903,9 @@ int TRelation_application::delete_mode()
|
|||||||
r.restore_status();
|
r.restore_status();
|
||||||
can_delete = remove();
|
can_delete = remove();
|
||||||
}
|
}
|
||||||
|
cur.freeze(false);
|
||||||
query_mode();
|
query_mode();
|
||||||
|
cur.freeze(true);
|
||||||
}
|
}
|
||||||
_autodelete = FALSE;
|
_autodelete = FALSE;
|
||||||
}
|
}
|
||||||
@ -1395,6 +1410,13 @@ void TRelation_application::main_loop()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_curr_trans_mode == TM_BATCH)
|
||||||
|
{
|
||||||
|
batch();
|
||||||
|
k = _mask->check_mask();
|
||||||
|
batch(false);
|
||||||
|
}
|
||||||
|
else
|
||||||
k = _mask->run();
|
k = _mask->run();
|
||||||
|
|
||||||
switch (k)
|
switch (k)
|
||||||
@ -1445,7 +1467,7 @@ void TRelation_application::main_loop()
|
|||||||
else
|
else
|
||||||
insert_mode();
|
insert_mode();
|
||||||
}
|
}
|
||||||
if (_curr_trans_mode == TM_AUTOMATIC)
|
if (_curr_trans_mode == TM_AUTOMATIC || _curr_trans_mode == TM_BATCH)
|
||||||
_mask->send_key(K_CTRL+'R', 0);
|
_mask->send_key(K_CTRL+'R', 0);
|
||||||
break;
|
break;
|
||||||
case K_SAVE:
|
case K_SAVE:
|
||||||
@ -1489,7 +1511,7 @@ void TRelation_application::main_loop()
|
|||||||
else
|
else
|
||||||
insert_mode();
|
insert_mode();
|
||||||
}
|
}
|
||||||
if (_curr_trans_mode == TM_AUTOMATIC)
|
if (_curr_trans_mode == TM_AUTOMATIC || _curr_trans_mode == TM_BATCH)
|
||||||
_mask->send_key(K_CTRL+'R', 0);
|
_mask->send_key(K_CTRL+'R', 0);
|
||||||
break;
|
break;
|
||||||
case K_DEL:
|
case K_DEL:
|
||||||
@ -1525,32 +1547,82 @@ void TRelation_application::main_loop()
|
|||||||
err = file().readat(_first, _testandlock);
|
err = file().readat(_first, _testandlock);
|
||||||
break;
|
break;
|
||||||
case K_NEXT:
|
case K_NEXT:
|
||||||
err = file().reread();
|
|
||||||
if (has_filtered_cursor())
|
|
||||||
{
|
{
|
||||||
TCursor& cur = get_filtered_cursor();
|
TCursor* c = get_filtered_cursor();
|
||||||
cur.curr() = file().curr();
|
|
||||||
cur.read();
|
if (!has_filtered_cursor() || c->curr().num() != file().curr().num())
|
||||||
++cur;
|
{
|
||||||
file().curr() = cur.curr();
|
for (TEdit_field* e = (TEdit_field *) _mask->get_key_field(1, TRUE); e; e = (TEdit_field *) _mask->get_key_field(1, FALSE))
|
||||||
err = get_relation()->read(_isequal, _testandlock);
|
{
|
||||||
|
if (e->shown() && e->browse() != NULL) // Ignora campi invisibili o senza check
|
||||||
|
{
|
||||||
|
TCursor* b = e->browse()->cursor();
|
||||||
|
|
||||||
|
if (b && b->curr().num() == file().curr().num())
|
||||||
|
{
|
||||||
|
c = b;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TCursor* cur = c ;
|
||||||
|
|
||||||
|
if (c == NULL)
|
||||||
|
cur = new TCursor(get_relation());
|
||||||
|
|
||||||
|
err = file().reread();
|
||||||
|
cur->curr() = file().curr();
|
||||||
|
cur->read();
|
||||||
|
++(*cur);
|
||||||
|
while (cur->pos() < cur->items() && !can_I_read(cur->relation()))
|
||||||
|
++(*cur);
|
||||||
|
file().curr() = cur->curr();
|
||||||
|
if (can_I_read(cur->relation()))
|
||||||
|
err = get_relation()->read(_isequal, _testandlock);
|
||||||
|
if (c == NULL)
|
||||||
|
delete cur;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
err = file().next(_testandlock);
|
|
||||||
break;
|
break;
|
||||||
case K_PREV:
|
case K_PREV:
|
||||||
file().reread();
|
|
||||||
if (has_filtered_cursor())
|
|
||||||
{
|
{
|
||||||
TCursor& cur = get_filtered_cursor();
|
TCursor* c = get_filtered_cursor();
|
||||||
cur.curr() = file().curr();
|
|
||||||
cur.read();
|
if (!has_filtered_cursor() || c->curr().num() != file().curr().num())
|
||||||
--cur;
|
{
|
||||||
file().curr() = cur.curr();
|
for (TEdit_field* e = (TEdit_field *) _mask->get_key_field(1, TRUE); e; e = (TEdit_field *) _mask->get_key_field(1, FALSE))
|
||||||
err = get_relation()->read(_isequal, _testandlock);
|
{
|
||||||
|
if (e->shown() && e->browse() != NULL) // Ignora campi invisibili o senza check
|
||||||
|
{
|
||||||
|
TCursor* b = e->browse()->cursor();
|
||||||
|
|
||||||
|
if (b && b->curr().num() == file().curr().num())
|
||||||
|
{
|
||||||
|
c = b;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TCursor* cur = c ;
|
||||||
|
|
||||||
|
if (c == NULL)
|
||||||
|
cur = new TCursor(get_relation());
|
||||||
|
|
||||||
|
file().reread();
|
||||||
|
cur->curr() = file().curr();
|
||||||
|
cur->read();
|
||||||
|
--(*cur);
|
||||||
|
while (cur->pos() > 0 && !can_I_read(cur->relation()))
|
||||||
|
--(*cur);
|
||||||
|
file().curr() = cur->curr();
|
||||||
|
if (can_I_read(cur->relation()))
|
||||||
|
err = get_relation()->read(_isequal, _testandlock);
|
||||||
|
if (c == NULL)
|
||||||
|
delete cur;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
err = file().prev(_testandlock);
|
|
||||||
break;
|
break;
|
||||||
case K_END:
|
case K_END:
|
||||||
err = file().readat(_last, _testandlock);
|
err = file().readat(_last, _testandlock);
|
||||||
@ -1601,6 +1673,18 @@ void TRelation_application::main_loop()
|
|||||||
ini.set("Result", err == NOERR ? "CANCEL" : "ERROR");
|
ini.set("Result", err == NOERR ? "CANCEL" : "ERROR");
|
||||||
ini.set("Error", err);
|
ini.set("Error", err);
|
||||||
}
|
}
|
||||||
|
if (_curr_trans_mode == TM_BATCH)
|
||||||
|
{
|
||||||
|
TString_array & errs = errors();
|
||||||
|
|
||||||
|
FOR_EACH_ARRAY_ROW(errs, r, s)
|
||||||
|
ini.set("ErrMsg", *s, "Main", false, r);
|
||||||
|
|
||||||
|
TString_array & warns = warnings();
|
||||||
|
|
||||||
|
FOR_EACH_ARRAY_ROW(warns, r1, s1)
|
||||||
|
ini.set("WarningMsg", *s1, "Main", false, r1);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
_trans_counter++;
|
_trans_counter++;
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#define TM_INTERACTIVE 'I'
|
#define TM_INTERACTIVE 'I'
|
||||||
#define TM_AUTOMATIC 'A'
|
#define TM_AUTOMATIC 'A'
|
||||||
#define TM_REMAIN 'R'
|
#define TM_REMAIN 'R'
|
||||||
|
#define TM_BATCH 'B'
|
||||||
// @doc EXTERNAL
|
// @doc EXTERNAL
|
||||||
|
|
||||||
// @class TRelation_application | Classe per la gestione di una applicazione di manutenzione di uno
|
// @class TRelation_application | Classe per la gestione di una applicazione di manutenzione di uno
|
||||||
@ -74,6 +75,7 @@ class TRelation_application : public TSkeleton_application
|
|||||||
int _autodelete;
|
int _autodelete;
|
||||||
// @cmember:(INTERNAL) Flag di navigazione tramite toolbar
|
// @cmember:(INTERNAL) Flag di navigazione tramite toolbar
|
||||||
bool _navigating;
|
bool _navigating;
|
||||||
|
bool _locked;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// @cmember:(INTERNAL) Carica la transazione corrente (protocollo via .ini)
|
// @cmember:(INTERNAL) Carica la transazione corrente (protocollo via .ini)
|
||||||
@ -106,7 +108,7 @@ private:
|
|||||||
bool autonum(TMask* m, bool rec);
|
bool autonum(TMask* m, bool rec);
|
||||||
// @cmember:(INTERNAL) Controlla se il <c TCursor> ha un filtro
|
// @cmember:(INTERNAL) Controlla se il <c TCursor> ha un filtro
|
||||||
virtual bool has_filtered_cursor() const;
|
virtual bool has_filtered_cursor() const;
|
||||||
virtual TCursor& get_filtered_cursor() const;
|
virtual TCursor* get_filtered_cursor() const;
|
||||||
|
|
||||||
// @cmember:(INTERNAL) Sistema il bottone ricerca se necessario
|
// @cmember:(INTERNAL) Sistema il bottone ricerca se necessario
|
||||||
void set_find_button();
|
void set_find_button();
|
||||||
@ -195,7 +197,7 @@ protected:
|
|||||||
|
|
||||||
// @cmember Richiede se il record corrente e' protetto (non cancellabile)
|
// @cmember Richiede se il record corrente e' protetto (non cancellabile)
|
||||||
virtual bool protected_record(TRectype&)
|
virtual bool protected_record(TRectype&)
|
||||||
{ return false; }
|
{ return _locked; }
|
||||||
|
|
||||||
// @cmember Richiede se il record corrente e' protetto (non cancellabile)
|
// @cmember Richiede se il record corrente e' protetto (non cancellabile)
|
||||||
virtual bool protected_record(TRelation &);
|
virtual bool protected_record(TRelation &);
|
||||||
@ -205,7 +207,7 @@ protected:
|
|||||||
|
|
||||||
// @cmember Inizializza la maschera per il modo ricerca
|
// @cmember Inizializza la maschera per il modo ricerca
|
||||||
virtual void init_query_mode(TMask&)
|
virtual void init_query_mode(TMask&)
|
||||||
{ }
|
{ _locked = false; }
|
||||||
// @cmember Inizializza la maschera per il modo ricerca ed inserimento (chiama <mf TRelation_application::init_query_mode>)
|
// @cmember Inizializza la maschera per il modo ricerca ed inserimento (chiama <mf TRelation_application::init_query_mode>)
|
||||||
virtual void init_query_insert_mode(TMask& m)
|
virtual void init_query_insert_mode(TMask& m)
|
||||||
{ init_query_mode(m); }
|
{ init_query_mode(m); }
|
||||||
|
@ -1533,7 +1533,7 @@ void TCursor::setkey(int nkey)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int TCursor::test(TIsamop op, TReclock lockop) const
|
int TCursor::test(TIsamop op, TReclock lockop)
|
||||||
{
|
{
|
||||||
TLocalisamfile& curfile = file();
|
TLocalisamfile& curfile = file();
|
||||||
const TRectype& currec = curfile.curr();
|
const TRectype& currec = curfile.curr();
|
||||||
@ -2049,7 +2049,9 @@ const char* TSorted_cursor::fill_sort_key(TString& k)
|
|||||||
{
|
{
|
||||||
const bool is_up = is_upper(s);
|
const bool is_up = is_upper(s);
|
||||||
const char last = s.right(1)[0];
|
const char last = s.right(1)[0];
|
||||||
if (last == '-' || last == '+')
|
const bool align = last == '*';
|
||||||
|
|
||||||
|
if (last == '-' || last == '+' || align)
|
||||||
s.rtrim(1);
|
s.rtrim(1);
|
||||||
|
|
||||||
const TFieldref f(s,0);
|
const TFieldref f(s,0);
|
||||||
@ -2072,7 +2074,7 @@ const char* TSorted_cursor::fill_sort_key(TString& k)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// if (is_up) // Test inutile: tutte le chiavi sono maiuscole 08-02-2016
|
if (is_up) // Test inutile: tutte le chiavi sono maiuscole 08-02-2016
|
||||||
sf.upper();
|
sf.upper();
|
||||||
}
|
}
|
||||||
switch (fld_type)
|
switch (fld_type)
|
||||||
@ -2080,9 +2082,24 @@ const char* TSorted_cursor::fill_sort_key(TString& k)
|
|||||||
case _boolfld:
|
case _boolfld:
|
||||||
case _charfld:
|
case _charfld:
|
||||||
case _memofld:
|
case _memofld:
|
||||||
case _alfafld: sf.left_just(fld_len); break;
|
case _alfafld: sf.left_just(fld_len > 0 ? fld_len : 50); break;
|
||||||
|
case _intfld:
|
||||||
|
case _longfld:
|
||||||
|
case _intzerofld:
|
||||||
|
case _longzerofld: sf.right_just(fld_len > 0 ? fld_len : 50); break;
|
||||||
case _datefld: break; // Gia' lungo 8!
|
case _datefld: break; // Gia' lungo 8!
|
||||||
default : sf.right_just(fld_len); break;
|
case _realfld:
|
||||||
|
if (align)
|
||||||
|
{
|
||||||
|
real r(sf);
|
||||||
|
sf = r.string(fld_len > 0 ? fld_len : 50, fld_len > 0 ? (fld_len-4)/2 : 10);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
sf.right_just(fld_len > 0 ? fld_len : 50);
|
||||||
|
break;
|
||||||
|
default :
|
||||||
|
sf.left_just(fld_len > 0 ? fld_len : 50);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
k << sf;
|
k << sf;
|
||||||
}
|
}
|
||||||
@ -2103,6 +2120,96 @@ bool TSorted_cursor::changed()
|
|||||||
return rt;
|
return rt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int TSorted_cursor::test(TIsamop op, TReclock lockop)
|
||||||
|
|
||||||
|
{
|
||||||
|
int err = NOERR;
|
||||||
|
|
||||||
|
if (items() == 0L)
|
||||||
|
{
|
||||||
|
err = _isemptyfile;
|
||||||
|
file().setstatus(err);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
TString256 searching; fill_sort_key(searching);
|
||||||
|
searching.rtrim();
|
||||||
|
const int cmplen = searching.len();
|
||||||
|
|
||||||
|
TRecnotype first = 0L;
|
||||||
|
TRecnotype last = items()-1;
|
||||||
|
TRecnotype found = -1L;
|
||||||
|
|
||||||
|
FOR_EACH_ARRAY_ROW(fpkey(), i, s)
|
||||||
|
{
|
||||||
|
const int cmp = searching.compare(*s, cmplen);
|
||||||
|
if (cmp <= 0)
|
||||||
|
last = (i + 1) * pagesize() - 1;
|
||||||
|
else
|
||||||
|
first = i * pagesize();
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool ghiacciato = !frozen();
|
||||||
|
if (ghiacciato) freeze(true);
|
||||||
|
|
||||||
|
TString256 testing;
|
||||||
|
while (first <= last)
|
||||||
|
{
|
||||||
|
const TRecnotype test = (first+last)/2;
|
||||||
|
TCursor::operator=(test); // verif
|
||||||
|
fill_sort_key(testing);
|
||||||
|
const int cmp = searching.compare(testing, cmplen);
|
||||||
|
if (cmp == 0)
|
||||||
|
{
|
||||||
|
if (op != _isgreat)
|
||||||
|
{
|
||||||
|
if (found < 0l || test < found)
|
||||||
|
found = test;
|
||||||
|
last = test-1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
first = test+1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (cmp < 0)
|
||||||
|
{
|
||||||
|
last = test-1;
|
||||||
|
if (op != _isequal)
|
||||||
|
{
|
||||||
|
if (found < 0l || test < found)
|
||||||
|
found = test;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
first = test+1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found >= 0L)
|
||||||
|
{
|
||||||
|
TCursor::operator=(found); // verif
|
||||||
|
file().setstatus(NOERR);
|
||||||
|
if (lockop != _nolock)
|
||||||
|
lock(lockop);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
found = items()-1;
|
||||||
|
if (found >= 0)
|
||||||
|
TCursor::operator=(found);
|
||||||
|
err = op == _isequal ? _iskeynotfound : _iseof;
|
||||||
|
file().setstatus(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ghiacciato)
|
||||||
|
freeze(false);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
TRecnotype TSorted_cursor::read(TIsamop op, TReclock lockop)
|
TRecnotype TSorted_cursor::read(TIsamop op, TReclock lockop)
|
||||||
{
|
{
|
||||||
TString256 searching; fill_sort_key(searching);
|
TString256 searching; fill_sort_key(searching);
|
||||||
|
@ -367,8 +367,8 @@ public:
|
|||||||
// @cmember Ritorna il descrittore della tabella
|
// @cmember Ritorna il descrittore della tabella
|
||||||
TRectype& curr(const char * tab) const
|
TRectype& curr(const char * tab) const
|
||||||
{ return _if->lfile(tab).curr(); }
|
{ return _if->lfile(tab).curr(); }
|
||||||
//@cmember Testa la presenza di un record senza spostare il cursore
|
//@cmember Testa la presenza di un record
|
||||||
int test(TIsamop op = _isequal, TReclock lockop = _nolock) const;
|
virtual int test(TIsamop op = _isequal, TReclock lockop = _nolock);
|
||||||
// @cmember Legge il record
|
// @cmember Legge il record
|
||||||
virtual TRecnotype read(TIsamop op = _isgteq, TReclock lockop = _nolock);
|
virtual TRecnotype read(TIsamop op = _isgteq, TReclock lockop = _nolock);
|
||||||
// @cmember Mette un lock sul record
|
// @cmember Mette un lock sul record
|
||||||
@ -508,6 +508,10 @@ public:
|
|||||||
// @cmember Si sposta alla posizione <p nr>
|
// @cmember Si sposta alla posizione <p nr>
|
||||||
TRecnotype operator =(const TRecnotype nr)
|
TRecnotype operator =(const TRecnotype nr)
|
||||||
{ return TCursor::operator =(nr); }
|
{ return TCursor::operator =(nr); }
|
||||||
|
|
||||||
|
//@cmember Testa la presenza di un record
|
||||||
|
virtual int test(TIsamop op = _isequal, TReclock lockop = _nolock);
|
||||||
|
|
||||||
// @cmember Trova l'indice del record corrente
|
// @cmember Trova l'indice del record corrente
|
||||||
virtual TRecnotype read(TIsamop op = _isgteq, TReclock lockop = _nolock);
|
virtual TRecnotype read(TIsamop op = _isgteq, TReclock lockop = _nolock);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user