1996-05-08 11:09:13 +00:00
|
|
|
|
#include <colors.h>
|
|
|
|
|
#include <controls.h>
|
|
|
|
|
#include <keys.h>
|
1995-09-25 11:39:10 +00:00
|
|
|
|
#include <msksheet.h>
|
|
|
|
|
#include <urldefid.h>
|
|
|
|
|
#include <utility.h>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////
|
|
|
|
|
// TSpreadsheet
|
|
|
|
|
///////////////////////////////////////////////////////////
|
|
|
|
|
|
1995-12-29 12:09:48 +00:00
|
|
|
|
// @doc INTERNAL
|
1995-09-25 11:39:10 +00:00
|
|
|
|
|
|
|
|
|
// @class TSpreadsheet | Classe per la creazione di uno spreadsheet all'interno
|
|
|
|
|
// di una maschera
|
|
|
|
|
//
|
|
|
|
|
// @base public | TWindow
|
1996-05-08 11:09:13 +00:00
|
|
|
|
class TSpreadsheet : public TControl
|
1995-09-25 11:39:10 +00:00
|
|
|
|
{
|
|
|
|
|
// @author:(INTERNAL) Guido
|
|
|
|
|
|
|
|
|
|
// @cfriend TSheet_field
|
|
|
|
|
friend class TSheet_field;
|
|
|
|
|
|
1996-02-05 19:00:53 +00:00
|
|
|
|
// @access:(INTERNAL) Private Member
|
1995-09-25 11:39:10 +00:00
|
|
|
|
|
1996-02-05 19:00:53 +00:00
|
|
|
|
// @cmember:(INTERNAL) Array di TToken_strings contenenti le righe
|
1995-09-25 11:39:10 +00:00
|
|
|
|
TString_array _str;
|
1996-02-05 19:00:53 +00:00
|
|
|
|
// @cmember:(INTERNAL) Array delle colonne disattivate (solo visualizzazione)
|
1995-09-25 11:39:10 +00:00
|
|
|
|
TBit_array _column_disabled;
|
1996-02-05 19:00:53 +00:00
|
|
|
|
// @cmember:(INTERNAL) Array dell celle disattivate (solo visualizzazione)
|
1995-09-25 11:39:10 +00:00
|
|
|
|
TArray _disabled;
|
|
|
|
|
|
1996-02-05 19:00:53 +00:00
|
|
|
|
// @cmember:(INTERNAL) Maschera in cui e' contenuto lo spreadsheet
|
1995-09-25 11:39:10 +00:00
|
|
|
|
TMask _mask;
|
1996-02-05 19:00:53 +00:00
|
|
|
|
// @cmember:(INTERNAL) Numero di colonne presenti nello spreadsheet
|
1995-09-25 11:39:10 +00:00
|
|
|
|
int _columns;
|
1996-02-05 19:00:53 +00:00
|
|
|
|
// @cmember:(INTERNAL) Indica se e' attivo lo spreadsheet
|
1995-09-25 11:39:10 +00:00
|
|
|
|
bool _active;
|
|
|
|
|
|
1996-02-05 19:00:53 +00:00
|
|
|
|
// @cmember:(INTERNAL) Funzione per la gestione di una riga dello sheet (vedi <t SPREADSHEET_NOTIFY>)
|
1995-09-25 11:39:10 +00:00
|
|
|
|
SPREADSHEET_NOTIFY _notify;
|
1996-05-08 11:09:13 +00:00
|
|
|
|
|
1996-02-05 19:00:53 +00:00
|
|
|
|
// @cmember:(INTERNAL) Campo corrente che si sta editando
|
1996-05-08 11:09:13 +00:00
|
|
|
|
TOperable_field* _edit_field;
|
1996-02-05 19:00:53 +00:00
|
|
|
|
// @cmember:(INTERNAL) Coordinata della riga della cella corrente
|
1995-09-25 11:39:10 +00:00
|
|
|
|
int _cur_row;
|
1996-02-05 19:00:53 +00:00
|
|
|
|
// @cmember:(INTERNAL) Numero del record sul file al quale fa riferimento la cella corrente
|
1995-09-25 11:39:10 +00:00
|
|
|
|
int _cur_rec;
|
1996-02-05 19:00:53 +00:00
|
|
|
|
// @cmember:(INTERNAL) Coordinata della colonna della cella corrente
|
1995-09-25 11:39:10 +00:00
|
|
|
|
int _cur_col;
|
1996-02-05 19:00:53 +00:00
|
|
|
|
// @cmember:(INTERNAL) Indica se la riga corrente e' stat modificata
|
1995-09-25 11:39:10 +00:00
|
|
|
|
bool _row_dirty;
|
1996-02-05 19:00:53 +00:00
|
|
|
|
// @cmember:(INTERNAL) Indica se la cella corrente e' stat modificata
|
1996-01-11 15:51:56 +00:00
|
|
|
|
bool _cell_dirty;
|
1996-02-05 19:00:53 +00:00
|
|
|
|
// @cmember:(INTERNAL) Permette di gestire i check OFF_ROW e OFF_CELL
|
1995-09-25 11:39:10 +00:00
|
|
|
|
bool _check_enabled;
|
1996-02-05 19:00:53 +00:00
|
|
|
|
// @cmember:(INTERNAL) Numero della riga che necessita aggiornamento (vengono aggiornate
|
1995-09-25 11:39:10 +00:00
|
|
|
|
// nella <mf TSpreadsheet::on_idle>)
|
|
|
|
|
int _needs_update;
|
|
|
|
|
|
1996-02-05 19:00:53 +00:00
|
|
|
|
// @cmember:(INTERNAL) Inizializza lo spreadsheet
|
1995-09-25 11:39:10 +00:00
|
|
|
|
void init();
|
1996-02-05 19:00:53 +00:00
|
|
|
|
// @cmember:(INTERNAL) Funzione che intercetta gli eventi dello spreadsheet
|
1995-09-25 11:39:10 +00:00
|
|
|
|
friend void XVT_CALLCONV1 xiev_handler(XI_OBJ *itf, XI_EVENT *xiev);
|
|
|
|
|
|
|
|
|
|
// @access Protected Member
|
|
|
|
|
protected:
|
|
|
|
|
//@cmember Gestisce gli eventi delle celle (chiamata dal <mf TSpreadsheet::xiev_handler>)
|
1996-05-08 11:09:13 +00:00
|
|
|
|
virtual bool event_handler(XI_OBJ* itf, XI_EVENT* xiev);
|
1995-10-25 09:43:56 +00:00
|
|
|
|
|
|
|
|
|
//@cmember Copia una cella nel corrispondente campo della maschera e ne ritorna il contenuto
|
|
|
|
|
const char* copy_cell2field(XI_OBJ* cell = NULL);
|
|
|
|
|
|
1995-09-29 16:25:36 +00:00
|
|
|
|
//@cmember Gestisce l'uscita delle celle (chiamata dal <mf TSpreadsheet::list_handler>)
|
1995-10-25 09:43:56 +00:00
|
|
|
|
bool off_cell_handler(XI_OBJ* cell = NULL);
|
1995-09-29 16:25:36 +00:00
|
|
|
|
|
1995-09-25 11:39:10 +00:00
|
|
|
|
// @cmember Ritorna il campo della maschera corrispondente alla cella dello
|
|
|
|
|
// spreadsheet indicata da <p pos>
|
1996-05-08 11:09:13 +00:00
|
|
|
|
TOperable_field* col2field(int pos) const;
|
1995-09-25 11:39:10 +00:00
|
|
|
|
// @cmember Ritorna il campo della maschera corrispondente alla cella dello
|
|
|
|
|
// spreadsheet indicata da <p cell> (chiama <mf TMask::col2field>)
|
1996-05-08 11:09:13 +00:00
|
|
|
|
TOperable_field* cell2field(const XI_OBJ* cell) const;
|
1995-12-20 16:17:48 +00:00
|
|
|
|
// @cmember Ritorna la posizione della colonna con identificatore <p cid>
|
|
|
|
|
int cid2col(short cid) const;
|
|
|
|
|
// @cmember Ritorna la colonna corrispondente al campo <p f> della maschera
|
1996-05-08 11:09:13 +00:00
|
|
|
|
int field2col(const TOperable_field* f) const;
|
1995-12-20 16:17:48 +00:00
|
|
|
|
|
1995-09-25 11:39:10 +00:00
|
|
|
|
// @cmember Aggiorna il record sullo spreadsheet
|
|
|
|
|
void update_rec(int rec);
|
1996-05-08 11:09:13 +00:00
|
|
|
|
TOperable_field* field(short id) const;
|
1995-09-25 11:39:10 +00:00
|
|
|
|
|
|
|
|
|
// @cmember Converte il numero del record nel corrispondente numero della riga
|
|
|
|
|
int rec2row(int rec);
|
|
|
|
|
// @cmember Converte il numero della riga riga nel corrispondente
|
|
|
|
|
// numero della riga
|
|
|
|
|
int row2rec(int& row);
|
|
|
|
|
// @cmember Setta la posizione (riga e colonna) del focus sullo spreadsheet.
|
|
|
|
|
// Ritorna il numero del record corrente
|
|
|
|
|
int set_pos(int row, int col)
|
|
|
|
|
{ _cur_col = col; _cur_row = row; return _cur_rec = row2rec(_cur_row); }
|
|
|
|
|
|
|
|
|
|
// @cmember Chiama la funzione specificata con la <mf TSpreadsheet::set_notify>
|
|
|
|
|
bool notify(int row, KEY k);
|
|
|
|
|
// @cmember Chiama la funzione specificata con la <mf TSpreadsheet::set_notify>
|
|
|
|
|
// ogni volta che c'e' una modifica nello spreadsheet
|
|
|
|
|
void notify_change();
|
|
|
|
|
// @cmember Permette di fare tutti gli aggiornamenti necessari (indicati in
|
|
|
|
|
// <p _needs_update>)
|
|
|
|
|
void on_idle();
|
1995-11-09 08:07:36 +00:00
|
|
|
|
|
|
|
|
|
// @cmember Cerca la colonna col
|
1996-05-08 11:09:13 +00:00
|
|
|
|
XI_OBJ* find_column(int col) const;
|
|
|
|
|
|
|
|
|
|
TSheet_field& owner() const { return (TSheet_field&)*_fld; }
|
1995-09-25 11:39:10 +00:00
|
|
|
|
|
|
|
|
|
// @access Public Member
|
|
|
|
|
public:
|
|
|
|
|
// @cmember Modifica a video la riga
|
1996-05-08 11:09:13 +00:00
|
|
|
|
void update(int row);
|
|
|
|
|
// @cmember Ritorna la disabilitazione della colonna <p col>
|
|
|
|
|
bool column_disabled(int col) { return _column_disabled[col]; }
|
1995-09-25 11:39:10 +00:00
|
|
|
|
|
|
|
|
|
// @cmember Ritorna il contenuto della riga <p n>-esima
|
|
|
|
|
TToken_string& row(int n)
|
|
|
|
|
{ return _str.row(n); }
|
1995-10-31 11:37:59 +00:00
|
|
|
|
// @cmember Aggiunge una riga allo spreadsheet passata come puntatore
|
1995-09-25 11:39:10 +00:00
|
|
|
|
// (vedi <mf TArray::add>)
|
|
|
|
|
int add(const TToken_string& s)
|
|
|
|
|
{ return _str.add(s); }
|
|
|
|
|
// @cmember Aggiunge una riga allo spreadsheet (vedi <mf TArray::add>)
|
|
|
|
|
int add(TToken_string* s)
|
|
|
|
|
{ return _str.add(s); }
|
|
|
|
|
// @cmember Inserisce un record in una posizione stabilita
|
|
|
|
|
int insert(int rec);
|
|
|
|
|
// @cmember Elimina il record <p rec>
|
1996-01-11 11:42:57 +00:00
|
|
|
|
bool destroy(int rec = -1, bool update_sheet = TRUE);
|
1995-09-25 11:39:10 +00:00
|
|
|
|
// @cmember Ritorna l'array di tutte le stringhe delle righe
|
|
|
|
|
TString_array& rows_array()
|
|
|
|
|
{ return _str; }
|
1995-11-14 16:04:38 +00:00
|
|
|
|
|
|
|
|
|
// @cmember Trova una colonna abilitata a partire da colonna
|
1995-12-01 11:49:11 +00:00
|
|
|
|
int find_enabled_column(int rec, int colonna, int direction) const;
|
1995-09-25 11:39:10 +00:00
|
|
|
|
// @cmember Permette di mettere il focus su una cella
|
|
|
|
|
void set_focus_cell(int riga, int colonna);
|
|
|
|
|
// @cmember Abilita/disabilita tutto lo spreadsheet (vedi <mf TMask::activate>)
|
|
|
|
|
void activate(bool on);
|
|
|
|
|
// @cmember Permette di abilitare/disabiltare una colonna
|
|
|
|
|
void enable_column(int col, bool on = TRUE);
|
|
|
|
|
// @cmember Permette di eliminare una colonna dallo spreadsheet
|
|
|
|
|
void delete_column(const int col) const;
|
|
|
|
|
// @cmember Sposta la colonna dalla posizione <p fromindex> alla posizione
|
|
|
|
|
// <p toindex>
|
|
|
|
|
void move_column(const int fromindex, const int toindex) const;
|
1996-05-08 11:09:13 +00:00
|
|
|
|
// @cmember Permette di invertire la posizione di due colonne
|
1995-09-25 11:39:10 +00:00
|
|
|
|
void swap_columns(const int fromid, const int toid) const;
|
|
|
|
|
// @cmember Permette di invertire la posiozne di due righe
|
|
|
|
|
void swap_rows(const int fromindex, const int toindex);
|
|
|
|
|
|
|
|
|
|
// @cmember Setta la larghezza della colonna
|
|
|
|
|
void set_column_width(const int col, const int width) const;
|
|
|
|
|
// @cmember Setta il titolo della colonna
|
|
|
|
|
void set_column_header(const int col, const TString& header) const;
|
1995-11-09 08:07:36 +00:00
|
|
|
|
// @cmember Setta l'allinemento di una colonna
|
|
|
|
|
void set_column_justify(int col, bool right);
|
1995-09-25 11:39:10 +00:00
|
|
|
|
// @cmember Permette di abilitare/disabilitare una singola cella
|
|
|
|
|
void enable_cell(int row, int column, bool on = TRUE);
|
|
|
|
|
// @cmember Controlla se una cella e' disabilitata
|
|
|
|
|
bool cell_disabled(int row, int column) const;
|
|
|
|
|
|
|
|
|
|
// @cmember Ritorna la maschera che appartiene allo spreadsheet
|
1995-10-06 16:38:58 +00:00
|
|
|
|
TMask& sheet_mask() const;
|
|
|
|
|
|
1995-09-25 11:39:10 +00:00
|
|
|
|
// @cmember Ritorna la maschera cui appartiene lo spreadsheet
|
|
|
|
|
TMask& mask() const;
|
|
|
|
|
|
|
|
|
|
// @cmember Ricopia i campi della maschera nel record <p n>-esimo ed
|
|
|
|
|
// aggiorna il display
|
|
|
|
|
void mask2str(int n);
|
|
|
|
|
// @cmember Ricopia i campi del record <p n>-esimo nella maschera ed
|
|
|
|
|
// aggiorna il display
|
|
|
|
|
void str2mask(int n);
|
|
|
|
|
// @cmember Apre la maschera della riga <p n>-esima editando la riga
|
|
|
|
|
KEY edit(int n);
|
|
|
|
|
|
|
|
|
|
// @cmember Ritorna il numero di righe dello sheet
|
|
|
|
|
int items() const
|
|
|
|
|
{ return _str.items(); }
|
|
|
|
|
// @cmember Ritorna il record corrente
|
|
|
|
|
int selected() const
|
|
|
|
|
{ return _cur_rec; }
|
|
|
|
|
// @cmember Seleziona una riga dandogli il focus
|
1996-01-11 15:51:56 +00:00
|
|
|
|
void select(int r, bool scrollto);
|
1995-09-25 11:39:10 +00:00
|
|
|
|
// @cmember Ritorna il numero di colonne presenti enllo spreadsheet
|
|
|
|
|
int columns() const
|
|
|
|
|
{ return _columns; }
|
|
|
|
|
|
|
|
|
|
// @cmember Controlla se e' stato modificato una cella dello spreadsheet
|
|
|
|
|
bool dirty() const
|
1996-05-08 11:09:13 +00:00
|
|
|
|
{ return owner().dirty(); }
|
1995-09-25 11:39:10 +00:00
|
|
|
|
// @cmember Permette di indicare se e' stata modificata una cella dello spreadsheet
|
|
|
|
|
void set_dirty(bool spork = TRUE)
|
1996-05-08 11:09:13 +00:00
|
|
|
|
{ owner().set_dirty(spork); }
|
1995-09-25 11:39:10 +00:00
|
|
|
|
|
|
|
|
|
// @cmember Ritorna il valore della variabile active
|
|
|
|
|
bool active() const
|
|
|
|
|
{ return _active; }
|
|
|
|
|
// @cmember Ritorna se e' possibile lasciare il focus dallo spreadsheet (TRUE se e' possibile)
|
|
|
|
|
bool test_focus_change();
|
|
|
|
|
|
|
|
|
|
// @cmember Setta il membro <p _notify> on il valore <p n>
|
|
|
|
|
void set_notify(SPREADSHEET_NOTIFY n)
|
|
|
|
|
{ _notify = n; }
|
|
|
|
|
|
|
|
|
|
// @cmember Costruttore
|
1996-05-08 11:09:13 +00:00
|
|
|
|
TSpreadsheet(WINDOW parent, short dlg, short x, short y, short dx, short dy, const char* maskname, int maskno, const char* head, TSheet_field* owner);
|
1995-09-25 11:39:10 +00:00
|
|
|
|
// @cmember Distruttore
|
|
|
|
|
virtual ~TSpreadsheet();
|
|
|
|
|
};
|
|
|
|
|
|
1996-02-05 19:00:53 +00:00
|
|
|
|
// @doc INTERNAL
|
1995-09-25 11:39:10 +00:00
|
|
|
|
|
|
|
|
|
// @mfunc Costruttore
|
|
|
|
|
TSpreadsheet::TSpreadsheet(
|
1996-05-08 11:09:13 +00:00
|
|
|
|
WINDOW parent, // @parm Finestra alla quale appartiene lo spreadsheet
|
|
|
|
|
short dlg, // @parm Identificatore del campo
|
1995-09-25 11:39:10 +00:00
|
|
|
|
short x, // @parm Coordinata x (in caratteri) nel quale posizionare lo spreadsheet
|
|
|
|
|
short y, // @parm Coordinata y (in caratteri) nel quale posizionare lo spreadsheet
|
|
|
|
|
short dx, // @parm Larghezza (in caratteri) dello spreasheet
|
|
|
|
|
short dy, // @parm Lunghezza (in caratteri) dello spreasheet
|
|
|
|
|
const char* maskname, // @parm Nome del file della maschera
|
|
|
|
|
int maskno, // @parm Numero identificativo della maschera nel file
|
1996-05-08 11:09:13 +00:00
|
|
|
|
const char* head, // @parm Titolo delle colonne
|
1995-09-25 11:39:10 +00:00
|
|
|
|
TSheet_field* o) // @parm Indica il campo della maschera che contiene lo spreadsheet
|
1996-05-08 11:09:13 +00:00
|
|
|
|
:
|
|
|
|
|
_mask(maskname, maskno), _notify(NULL),
|
1995-12-23 09:43:52 +00:00
|
|
|
|
_cur_row(0), _cur_col(1), _cur_rec(0), _edit_field(NULL), _active(TRUE),
|
1996-01-19 13:02:25 +00:00
|
|
|
|
_row_dirty(FALSE), _check_enabled(TRUE),
|
1995-09-25 11:39:10 +00:00
|
|
|
|
_needs_update(-1)
|
|
|
|
|
{
|
|
|
|
|
const int NUMBER_WIDTH = 3;
|
|
|
|
|
const int MAX_COL = 32;
|
|
|
|
|
int m_width[MAX_COL], v_width[MAX_COL];
|
|
|
|
|
int fixed_columns = 1; // Number of fixed columns
|
|
|
|
|
|
1996-05-08 11:09:13 +00:00
|
|
|
|
TControl::_fld = o;
|
1995-10-06 16:38:58 +00:00
|
|
|
|
sheet_mask().set_sheet(o);
|
1995-09-25 11:39:10 +00:00
|
|
|
|
|
|
|
|
|
// Calcolo larghezza massima tabella
|
|
|
|
|
|
|
|
|
|
TToken_string header(head);
|
|
|
|
|
TToken_string new_header(256);
|
|
|
|
|
int i = 0, tot_width = NUMBER_WIDTH+1;
|
|
|
|
|
int f_width = tot_width<<1; // Stima larghezza colonne fisse
|
|
|
|
|
int max_width = f_width; // Stima larghezza della colonna piu' grande
|
|
|
|
|
|
|
|
|
|
for (const char* h = header.get(); h; h = header.get(), i++)
|
|
|
|
|
{
|
|
|
|
|
CHECKD(i < MAX_COL, "Tu meni calumns in scit: ", i);
|
|
|
|
|
|
|
|
|
|
const int cid = FIRST_FIELD+i; // Column & Field ID
|
1996-05-08 11:09:13 +00:00
|
|
|
|
const TOperable_field* f = field(cid); // Field on mask
|
1995-09-25 11:39:10 +00:00
|
|
|
|
CHECKD(f, "The spreadsheet mask needs ALSO field ", cid);
|
|
|
|
|
|
1996-05-08 11:09:13 +00:00
|
|
|
|
TString testa(h);
|
1995-09-25 11:39:10 +00:00
|
|
|
|
const int at = testa.find('@');
|
1996-05-08 11:09:13 +00:00
|
|
|
|
int m = f->size(); // Memory width
|
|
|
|
|
int v = m; // Video width
|
1995-09-25 11:39:10 +00:00
|
|
|
|
if (at >= 0)
|
|
|
|
|
{
|
|
|
|
|
const TString& wi = testa.mid(at+1);
|
1996-05-08 11:09:13 +00:00
|
|
|
|
v = atoi(wi);
|
1995-09-25 11:39:10 +00:00
|
|
|
|
if (wi.find('F') >= 0)
|
|
|
|
|
{
|
|
|
|
|
fixed_columns++;
|
1996-05-08 11:09:13 +00:00
|
|
|
|
f_width += v+1;
|
1995-09-25 11:39:10 +00:00
|
|
|
|
}
|
|
|
|
|
testa.cut(at);
|
1996-05-13 07:31:27 +00:00
|
|
|
|
v = max(at, v+(f->has_query_button() ? 1 : 0));
|
1995-09-25 11:39:10 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
1996-05-13 07:31:27 +00:00
|
|
|
|
v = max(testa.len(), m+(f->has_query_button() ? 1 : 0));
|
1995-09-25 11:39:10 +00:00
|
|
|
|
}
|
|
|
|
|
if (v > 69)
|
|
|
|
|
v = 69;
|
1996-05-08 11:09:13 +00:00
|
|
|
|
m = f->size();
|
1995-09-25 11:39:10 +00:00
|
|
|
|
|
|
|
|
|
m_width[i] = m+1; // m = number of allowed chars
|
|
|
|
|
v_width[i] = v+1; // v = width of column
|
|
|
|
|
if (v >= max_width) max_width = v+1;
|
|
|
|
|
|
|
|
|
|
tot_width += v_width[i];
|
|
|
|
|
|
|
|
|
|
new_header.add(testa);
|
|
|
|
|
}
|
|
|
|
|
_columns = i;
|
|
|
|
|
|
1996-05-08 11:09:13 +00:00
|
|
|
|
RCT rct; coord2rct(parent, x, y, dx, dy, rct);
|
|
|
|
|
rct.right -= 2*XI_FU_MULTIPLE; // toglie scroll-bar
|
|
|
|
|
|
|
|
|
|
// Controlla se ci sono troppe colonne fisse
|
|
|
|
|
if ((f_width+max_width)*XI_FU_MULTIPLE > rct.right)
|
1995-09-25 11:39:10 +00:00
|
|
|
|
fixed_columns = 1;
|
1996-05-08 11:09:13 +00:00
|
|
|
|
|
|
|
|
|
XI_OBJ* itf = get_interface(parent);
|
1995-09-25 11:39:10 +00:00
|
|
|
|
|
1996-05-08 11:09:13 +00:00
|
|
|
|
XI_OBJ_DEF* listdef = xi_add_list_def(NULL, dlg,
|
|
|
|
|
rct.top, rct.left, rct.bottom-rct.top,
|
1995-09-25 11:39:10 +00:00
|
|
|
|
XI_ATR_ENABLED | XI_ATR_VISIBLE,
|
|
|
|
|
NORMAL_COLOR, NORMAL_BACK_COLOR, // normal
|
|
|
|
|
NORMAL_COLOR, DISABLED_BACK_COLOR, // disabled
|
1996-04-11 09:54:41 +00:00
|
|
|
|
FOCUS_COLOR, // active
|
1996-05-08 11:09:13 +00:00
|
|
|
|
0);
|
1995-09-25 11:39:10 +00:00
|
|
|
|
|
1996-05-08 11:09:13 +00:00
|
|
|
|
CHECK(listdef, "Can't create spreadsheet definition");
|
|
|
|
|
listdef->app_data = (long)this;
|
|
|
|
|
XI_LIST_DEF* l = listdef->v.list;
|
|
|
|
|
l->width = rct.right - rct.left;
|
|
|
|
|
l->min_heading_height = xi_button_calc_height_font_id(xvt_default_font());
|
|
|
|
|
l->sizable_columns = TRUE;
|
|
|
|
|
l->movable_columns = TRUE;
|
|
|
|
|
l->scroll_bar = TRUE;
|
|
|
|
|
l->scroll_bar_button = TRUE;
|
|
|
|
|
l->fixed_columns = fixed_columns;
|
|
|
|
|
l->active_back_color = FOCUS_BACK_COLOR;
|
|
|
|
|
l->white_space_color = MASK_DARK_COLOR;
|
|
|
|
|
|
|
|
|
|
// Definizione della prima colonna (numero di riga)
|
1995-09-25 11:39:10 +00:00
|
|
|
|
word attr = XI_ATR_RJUST;
|
1995-10-06 16:38:58 +00:00
|
|
|
|
if (sheet_mask().id2pos(FIRST_FIELD -1) != -1)
|
1995-09-25 11:39:10 +00:00
|
|
|
|
attr |= XI_ATR_SELECTABLE;
|
|
|
|
|
|
1996-05-08 11:09:13 +00:00
|
|
|
|
XI_OBJ_DEF* coldef = xi_add_column_def(listdef, 0, attr, 0,
|
|
|
|
|
NUMBER_WIDTH * XI_FU_MULTIPLE, NUMBER_WIDTH+1,
|
1995-09-25 11:39:10 +00:00
|
|
|
|
attr & XI_ATR_SELECTABLE ? "X" : "");
|
1996-05-08 11:09:13 +00:00
|
|
|
|
|
|
|
|
|
coldef->app_data = (long)this;
|
1995-09-25 11:39:10 +00:00
|
|
|
|
coldef->v.column->heading_platform = TRUE;
|
|
|
|
|
coldef->v.column->column_platform = TRUE;
|
|
|
|
|
|
|
|
|
|
if (attr & XI_ATR_SELECTABLE)
|
|
|
|
|
{
|
|
|
|
|
coldef->v.column->icon_rid = ICO_SEARCH;
|
1996-05-08 11:09:13 +00:00
|
|
|
|
coldef->v.column->icon_x = 2;
|
|
|
|
|
if (listdef->v.list->min_heading_height < 20)
|
|
|
|
|
listdef->v.list->min_heading_height = 20;
|
1995-09-25 11:39:10 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
coldef->v.column->center_heading = TRUE;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (h = new_header.get(0), i = 0; h; h = new_header.get(), i++)
|
|
|
|
|
{
|
1996-05-08 11:09:13 +00:00
|
|
|
|
const TString testo(h);
|
1995-09-25 11:39:10 +00:00
|
|
|
|
const int cid = FIRST_FIELD+i; // Column & Field ID
|
1996-05-08 11:09:13 +00:00
|
|
|
|
const TOperable_field* f = field(cid); // Field on mask
|
1995-09-25 11:39:10 +00:00
|
|
|
|
const int acqua = f->class_id();
|
|
|
|
|
|
1996-05-08 11:09:13 +00:00
|
|
|
|
long flags = XI_ATR_EDITMENU | XI_ATR_AUTOSCROLL |
|
|
|
|
|
XI_ATR_FOCUSBORDER | XI_ATR_AUTOSELECT;
|
1995-09-25 11:39:10 +00:00
|
|
|
|
switch (acqua)
|
|
|
|
|
{
|
|
|
|
|
case CLASS_EDIT_FIELD:
|
|
|
|
|
if (f->right_justified())
|
|
|
|
|
flags |= XI_ATR_RJUST;
|
|
|
|
|
break;
|
|
|
|
|
case CLASS_REAL_FIELD:
|
|
|
|
|
flags |= XI_ATR_RJUST;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
1996-05-08 11:09:13 +00:00
|
|
|
|
if (f->active()) flags |= XI_ATR_ENABLED;
|
1995-09-25 11:39:10 +00:00
|
|
|
|
else _column_disabled.set(i);
|
|
|
|
|
|
1996-05-08 11:09:13 +00:00
|
|
|
|
coldef = xi_add_column_def(listdef, cid, flags, cid,
|
|
|
|
|
v_width[i] * XI_FU_MULTIPLE, m_width[i],
|
1995-09-25 11:39:10 +00:00
|
|
|
|
(char*)(const char*)testo);
|
1996-05-08 11:09:13 +00:00
|
|
|
|
|
|
|
|
|
coldef->app_data = (long)this;
|
1995-09-25 11:39:10 +00:00
|
|
|
|
coldef->v.column->heading_platform = TRUE;
|
|
|
|
|
coldef->v.column->center_heading = TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
1996-01-11 15:51:56 +00:00
|
|
|
|
// Create the whole thing!
|
1996-05-08 11:09:13 +00:00
|
|
|
|
_obj = xi_create(itf, listdef);
|
|
|
|
|
xi_dequeue(); // Flush events in XOL
|
|
|
|
|
xi_tree_free(listdef); // Free definitions
|
|
|
|
|
|
|
|
|
|
CHECKD(_obj, "Can't create spreadsheet ", owner().dlg());
|
|
|
|
|
|
|
|
|
|
update_tab_cid();
|
1995-09-25 11:39:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TSpreadsheet::~TSpreadsheet()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
1995-10-06 16:38:58 +00:00
|
|
|
|
TMask& TSpreadsheet::sheet_mask() const
|
1995-10-12 15:04:26 +00:00
|
|
|
|
{
|
1996-05-08 11:09:13 +00:00
|
|
|
|
return ((TSpreadsheet*)this)->_mask;
|
1995-10-06 16:38:58 +00:00
|
|
|
|
}
|
|
|
|
|
|
1995-09-25 11:39:10 +00:00
|
|
|
|
|
|
|
|
|
// Converts a row number in the correspondig record number
|
|
|
|
|
int TSpreadsheet::row2rec(int& row)
|
|
|
|
|
{
|
|
|
|
|
int rows;
|
1996-05-08 11:09:13 +00:00
|
|
|
|
const long* handle = xi_get_list_info(_obj, &rows);
|
1995-09-25 11:39:10 +00:00
|
|
|
|
|
|
|
|
|
if (row < 0)
|
|
|
|
|
row = 0;
|
|
|
|
|
else
|
1996-01-19 13:02:25 +00:00
|
|
|
|
{
|
1995-09-25 11:39:10 +00:00
|
|
|
|
if (row >= rows)
|
|
|
|
|
row = rows-1;
|
1996-01-19 13:02:25 +00:00
|
|
|
|
}
|
|
|
|
|
const int r = (int)handle[row];
|
1995-09-25 11:39:10 +00:00
|
|
|
|
|
1995-10-31 14:01:20 +00:00
|
|
|
|
CHECKD(r >= 0 && r < items(), "Sheet line out of range: ", row);
|
1995-09-25 11:39:10 +00:00
|
|
|
|
|
|
|
|
|
return r;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Converts a row number in the correspondig record number
|
|
|
|
|
int TSpreadsheet::rec2row(int record)
|
|
|
|
|
{
|
|
|
|
|
int rows;
|
1996-05-08 11:09:13 +00:00
|
|
|
|
const long* rec = xi_get_list_info(_obj, &rows);
|
1995-09-25 11:39:10 +00:00
|
|
|
|
int r = int(record - rec[0]);
|
|
|
|
|
if (r < 0 || r >= rows)
|
|
|
|
|
r = -1;
|
|
|
|
|
|
|
|
|
|
return r;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Retrieves the corresponding field of the mask from a spredsheet cell
|
1996-05-08 11:09:13 +00:00
|
|
|
|
TOperable_field* TSpreadsheet::col2field(int pos) const
|
1995-09-25 11:39:10 +00:00
|
|
|
|
{
|
|
|
|
|
int num;
|
1996-05-08 11:09:13 +00:00
|
|
|
|
XI_OBJ** column = xi_get_member_list(_obj, &num);
|
1995-09-25 11:39:10 +00:00
|
|
|
|
CHECKD(pos >= 0 && pos < num, "Bad column number", pos);
|
|
|
|
|
|
1996-05-08 11:09:13 +00:00
|
|
|
|
TOperable_field* good = NULL;
|
1995-09-25 11:39:10 +00:00
|
|
|
|
for (short id = column[pos]->cid; ; id += 100)
|
|
|
|
|
{
|
1996-05-08 11:09:13 +00:00
|
|
|
|
TOperable_field* f = field(id);
|
1995-09-25 11:39:10 +00:00
|
|
|
|
if (f == NULL) break; // Search failed
|
|
|
|
|
good = f; // We've found a field with the proper ID ...
|
|
|
|
|
if (f->active()) break; // ... and it's active: end of search
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CHECKD(good, "Can't find field corresponding to column ", pos);
|
|
|
|
|
return good;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Retrieves the corresponding field of the mask from a spredsheet cell
|
1996-05-08 11:09:13 +00:00
|
|
|
|
TOperable_field* TSpreadsheet::cell2field(const XI_OBJ* cell) const
|
1995-09-25 11:39:10 +00:00
|
|
|
|
{
|
|
|
|
|
return col2field(cell->v.cell.column);
|
|
|
|
|
}
|
|
|
|
|
|
1995-12-20 16:17:48 +00:00
|
|
|
|
int TSpreadsheet::cid2col(short cid) const
|
|
|
|
|
{
|
|
|
|
|
CHECKD(cid >= FIRST_FIELD, "Bad column id ", cid);
|
|
|
|
|
int num;
|
1996-05-08 11:09:13 +00:00
|
|
|
|
XI_OBJ** column = xi_get_member_list(_obj, &num);
|
1995-12-20 16:17:48 +00:00
|
|
|
|
for (int c = num-1; c > 1; c--)
|
|
|
|
|
{
|
|
|
|
|
if (column[c]->cid == cid)
|
1996-05-08 11:09:13 +00:00
|
|
|
|
return c;
|
1995-12-20 16:17:48 +00:00
|
|
|
|
}
|
1996-05-08 11:09:13 +00:00
|
|
|
|
return 0;
|
1995-12-20 16:17:48 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-05-08 11:09:13 +00:00
|
|
|
|
int TSpreadsheet::field2col(const TOperable_field* f) const
|
1995-12-20 16:17:48 +00:00
|
|
|
|
{
|
|
|
|
|
const short cid = FIRST_FIELD + (f->dlg() % 100) - 1;
|
|
|
|
|
return cid2col(cid);
|
|
|
|
|
}
|
|
|
|
|
|
1995-09-25 11:39:10 +00:00
|
|
|
|
void TSpreadsheet::update_rec(int rec)
|
|
|
|
|
{
|
|
|
|
|
const int riga = rec2row(rec);
|
|
|
|
|
if (riga >= 0)
|
|
|
|
|
{
|
1995-10-25 09:43:56 +00:00
|
|
|
|
const bool has_focus = rec == selected() &&
|
1996-05-08 11:09:13 +00:00
|
|
|
|
mask().focus_field().dlg() == owner().dlg();
|
1995-10-25 09:43:56 +00:00
|
|
|
|
if (has_focus)
|
1996-05-08 11:09:13 +00:00
|
|
|
|
xi_set_focus(get_interface());
|
1995-10-11 11:42:19 +00:00
|
|
|
|
|
1995-09-25 11:39:10 +00:00
|
|
|
|
XI_OBJ row;
|
1996-05-08 11:09:13 +00:00
|
|
|
|
XI_MAKE_ROW(&row, _obj, riga);
|
1995-09-25 11:39:10 +00:00
|
|
|
|
xi_cell_request(&row); // Update internal values
|
1995-10-11 11:42:19 +00:00
|
|
|
|
|
1995-10-25 09:43:56 +00:00
|
|
|
|
if (has_focus)
|
1995-10-11 11:42:19 +00:00
|
|
|
|
{
|
|
|
|
|
str2mask(_cur_rec);
|
|
|
|
|
set_focus_cell(riga, _cur_col);
|
|
|
|
|
}
|
1995-09-25 11:39:10 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
1995-11-14 16:04:38 +00:00
|
|
|
|
// Cerca una colonna abilitata a partire da colonna
|
|
|
|
|
// La prima cella utilizzabile ha indice 1
|
1995-12-20 16:17:48 +00:00
|
|
|
|
// rec e' un numero di record assoluto
|
|
|
|
|
// colonna e' un numero di colonna a video: puo' succedere che la 3 corrisponda al campo 107
|
1995-12-01 11:49:11 +00:00
|
|
|
|
int TSpreadsheet::find_enabled_column(int rec, int colonna, int direction) const
|
|
|
|
|
{
|
|
|
|
|
CHECKD(direction == +1 || direction == -1, "Bad column search direction", direction);
|
1995-11-18 11:09:38 +00:00
|
|
|
|
|
1995-12-20 16:17:48 +00:00
|
|
|
|
int num;
|
1996-05-08 11:09:13 +00:00
|
|
|
|
XI_OBJ** column = xi_get_member_list(_obj, &num);
|
1995-12-23 09:43:52 +00:00
|
|
|
|
if (colonna <= 0 || colonna >= num)
|
|
|
|
|
colonna = 1;
|
1995-11-14 16:04:38 +00:00
|
|
|
|
|
1995-12-23 09:43:52 +00:00
|
|
|
|
int c = colonna;
|
|
|
|
|
do
|
1995-12-01 11:49:11 +00:00
|
|
|
|
{
|
1995-12-20 16:17:48 +00:00
|
|
|
|
const short n = column[c]->cid - FIRST_FIELD;
|
|
|
|
|
if (!cell_disabled(rec, n))
|
1995-12-01 11:49:11 +00:00
|
|
|
|
return c;
|
1995-12-23 09:43:52 +00:00
|
|
|
|
|
|
|
|
|
c += direction;
|
|
|
|
|
if (c >= num)
|
|
|
|
|
c = 1;
|
|
|
|
|
else
|
|
|
|
|
if (c <= 0)
|
|
|
|
|
c = num-1;
|
|
|
|
|
}
|
|
|
|
|
while (c != colonna);
|
1995-11-14 16:04:38 +00:00
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
1995-12-20 16:17:48 +00:00
|
|
|
|
|
1995-12-01 11:49:11 +00:00
|
|
|
|
// riga (da 0), colonna (0 = numero, 1 = prima cella, ...)
|
1995-09-25 11:39:10 +00:00
|
|
|
|
void TSpreadsheet::set_focus_cell(int riga, int colonna)
|
1995-10-11 11:42:19 +00:00
|
|
|
|
{
|
1996-05-08 11:09:13 +00:00
|
|
|
|
xi_set_focus(get_interface());
|
1995-10-11 11:42:19 +00:00
|
|
|
|
|
1995-11-14 16:04:38 +00:00
|
|
|
|
const int rec = row2rec(riga);
|
1995-12-01 11:49:11 +00:00
|
|
|
|
colonna = find_enabled_column(rec, colonna, +1);
|
1995-11-14 16:04:38 +00:00
|
|
|
|
|
|
|
|
|
if (colonna > 0)
|
1996-01-22 10:02:16 +00:00
|
|
|
|
{
|
1996-01-22 11:07:49 +00:00
|
|
|
|
XI_OBJ cell;
|
1996-05-08 11:09:13 +00:00
|
|
|
|
XI_MAKE_CELL(&cell, _obj, riga, colonna);
|
1996-01-22 11:07:49 +00:00
|
|
|
|
xi_set_focus(&cell);
|
1995-09-25 11:39:10 +00:00
|
|
|
|
|
1995-10-11 11:42:19 +00:00
|
|
|
|
_edit_field = col2field(_cur_col = colonna);
|
1995-11-14 16:04:38 +00:00
|
|
|
|
if (rec != _cur_rec)
|
1995-10-11 11:42:19 +00:00
|
|
|
|
{
|
1995-11-14 16:04:38 +00:00
|
|
|
|
_cur_rec = rec;
|
1995-10-11 11:42:19 +00:00
|
|
|
|
_cur_row = riga;
|
1996-05-08 11:09:13 +00:00
|
|
|
|
/* Guy! str2mask(_cur_rec); */
|
1995-10-11 11:42:19 +00:00
|
|
|
|
_row_dirty = FALSE;
|
1995-09-25 11:39:10 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
1996-02-05 19:00:53 +00:00
|
|
|
|
// @doc INTERNAL
|
1995-09-25 11:39:10 +00:00
|
|
|
|
|
|
|
|
|
// @mfunc Inserisce un record in una posizione stabilita
|
|
|
|
|
//
|
|
|
|
|
// @rdesc Ritorna la posizione nella quale e' stato inserito il record. Se non riesce ad inserirlo
|
|
|
|
|
// ritorna -1.
|
|
|
|
|
int TSpreadsheet::insert(
|
|
|
|
|
int rec) // @parm Numero del record da inserire nello spreadsheet
|
|
|
|
|
|
|
|
|
|
// @comm Non e' possibile inserire un nuovo record nel caso nello spreadsheet vi siano
|
|
|
|
|
// almeno 999 righe oppure se lo spreadsheet non e' attivo.
|
|
|
|
|
{
|
|
|
|
|
static bool ininsert = FALSE;
|
|
|
|
|
|
1995-10-25 09:43:56 +00:00
|
|
|
|
if (ininsert || items() >= 999)
|
1995-09-25 11:39:10 +00:00
|
|
|
|
return -1;
|
|
|
|
|
|
1996-05-08 11:09:13 +00:00
|
|
|
|
if (rec < 0 && items() > 0 && !owner().append() )
|
1995-09-25 11:39:10 +00:00
|
|
|
|
rec = _cur_rec + 1;
|
|
|
|
|
|
|
|
|
|
ininsert = TRUE;
|
1995-10-25 09:43:56 +00:00
|
|
|
|
int r = _str.insert(new TToken_string(80), rec);
|
1995-09-25 11:39:10 +00:00
|
|
|
|
|
|
|
|
|
const bool ok = notify(r, K_INS);
|
1995-10-25 09:43:56 +00:00
|
|
|
|
if (ok)
|
|
|
|
|
{
|
|
|
|
|
_disabled.insert(NULL, r);
|
1996-05-08 11:09:13 +00:00
|
|
|
|
xi_insert_row(_obj, INT_MAX);
|
|
|
|
|
xi_cell_request(_obj);
|
1995-09-25 11:39:10 +00:00
|
|
|
|
|
1995-10-25 09:43:56 +00:00
|
|
|
|
// Notifica che l'inserimento <20> terminato
|
|
|
|
|
notify(r, K_CTRL + K_INS);
|
|
|
|
|
}
|
|
|
|
|
else
|
1995-09-25 11:39:10 +00:00
|
|
|
|
{
|
|
|
|
|
_str.destroy(r);
|
1995-10-25 09:43:56 +00:00
|
|
|
|
r = -1;
|
1995-09-25 11:39:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ininsert = FALSE;
|
|
|
|
|
return r;
|
|
|
|
|
}
|
|
|
|
|
|
1996-02-05 19:00:53 +00:00
|
|
|
|
// @doc INTERNAL
|
1995-09-25 11:39:10 +00:00
|
|
|
|
|
|
|
|
|
// @mfunc Elimina una riga
|
|
|
|
|
//
|
|
|
|
|
// @rdesc Ritorna il risultato dell'operazione:
|
|
|
|
|
//
|
|
|
|
|
// @flag TRUE | Se la riga esisteve e quindi e' stata eliminata
|
|
|
|
|
// @flag FALSE | Se la riga non esisteve
|
|
|
|
|
bool TSpreadsheet::destroy(
|
1996-01-11 11:42:57 +00:00
|
|
|
|
int rec, // @parm Numero della riga da eliminare
|
|
|
|
|
bool update_sheet) // @parm Aggiornamento visuale dell sheet
|
1995-09-25 11:39:10 +00:00
|
|
|
|
|
|
|
|
|
// @comm Se il parametro <p rec> assume valore -1 vengono eliminate tutte le righe presenti
|
|
|
|
|
// nello spreadsheet
|
|
|
|
|
{
|
|
|
|
|
static bool indestroy = FALSE;
|
|
|
|
|
|
|
|
|
|
if ( indestroy )
|
1995-10-25 09:43:56 +00:00
|
|
|
|
return FALSE;
|
1995-09-25 11:39:10 +00:00
|
|
|
|
|
|
|
|
|
indestroy = TRUE;
|
|
|
|
|
bool ok = TRUE;
|
|
|
|
|
|
|
|
|
|
if (rec < 0)
|
|
|
|
|
{
|
|
|
|
|
_disabled.destroy();
|
|
|
|
|
_str.destroy();
|
|
|
|
|
set_dirty(_row_dirty = FALSE);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
_disabled.destroy(rec, TRUE); // Destroy enable info
|
|
|
|
|
ok = _str.destroy(rec, TRUE); // Destroy line
|
|
|
|
|
}
|
|
|
|
|
|
1996-01-11 11:42:57 +00:00
|
|
|
|
if (ok && mask().is_running() && update_sheet)
|
1995-09-25 11:39:10 +00:00
|
|
|
|
update(-1);
|
|
|
|
|
|
|
|
|
|
indestroy = FALSE;
|
|
|
|
|
return ok;
|
|
|
|
|
}
|
|
|
|
|
|
1996-02-05 19:00:53 +00:00
|
|
|
|
// @doc INTERNAL
|
1995-09-25 11:39:10 +00:00
|
|
|
|
|
|
|
|
|
// @mfunc Modifica a video la riga
|
|
|
|
|
void TSpreadsheet::update(
|
1996-01-11 15:51:56 +00:00
|
|
|
|
int rec) // @parm Numero della riga da modificare
|
1995-09-25 11:39:10 +00:00
|
|
|
|
|
|
|
|
|
// @comm Se il valore di <p row> e' minore di 0 viene aggiornato l'intero spreadsheet
|
|
|
|
|
{
|
1996-01-11 15:51:56 +00:00
|
|
|
|
if (rec < 0)
|
1995-09-25 11:39:10 +00:00
|
|
|
|
{
|
1996-05-08 11:09:13 +00:00
|
|
|
|
xi_cell_request(_obj); // Update cell values
|
1996-01-11 15:51:56 +00:00
|
|
|
|
|
1996-01-19 13:02:25 +00:00
|
|
|
|
int num = 0;
|
1996-05-08 11:09:13 +00:00
|
|
|
|
const long* handle = xi_get_list_info(_obj, &num);
|
1996-01-19 13:02:25 +00:00
|
|
|
|
|
|
|
|
|
int first = 0, last = 0;
|
1996-05-08 11:09:13 +00:00
|
|
|
|
bool scroll = items() == 0; // || !owner().mask().is_running();
|
1996-01-19 13:02:25 +00:00
|
|
|
|
if (!scroll)
|
|
|
|
|
{
|
1996-05-08 11:09:13 +00:00
|
|
|
|
xi_get_visible_rows(_obj, &first, &last);
|
1996-01-19 13:02:25 +00:00
|
|
|
|
scroll = items() < handle[first];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (scroll)
|
1996-05-08 11:09:13 +00:00
|
|
|
|
xi_scroll(_obj, XI_SCROLL_FIRST);
|
1996-01-11 15:51:56 +00:00
|
|
|
|
else
|
1996-05-08 11:09:13 +00:00
|
|
|
|
xi_scroll_rec(_obj, handle[first], NORMAL_COLOR, XI_ATR_ENABLED | XI_ATR_AUTOSELECT, 0);
|
1996-01-19 13:02:25 +00:00
|
|
|
|
|
|
|
|
|
_needs_update = -1; // Clear pending row update
|
1995-09-25 11:39:10 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
1996-01-11 15:51:56 +00:00
|
|
|
|
update_rec(rec);
|
1995-09-25 11:39:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void TSpreadsheet::notify_change()
|
|
|
|
|
{
|
|
|
|
|
if (!_row_dirty)
|
1996-05-08 11:09:13 +00:00
|
|
|
|
{
|
|
|
|
|
/* Guy! */
|
|
|
|
|
str2mask(_cur_rec);
|
1995-09-25 11:39:10 +00:00
|
|
|
|
notify(_cur_rec, K_SPACE);
|
|
|
|
|
_row_dirty = TRUE;
|
|
|
|
|
set_dirty();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
1995-10-25 09:43:56 +00:00
|
|
|
|
const char* TSpreadsheet::copy_cell2field(XI_OBJ* cell)
|
|
|
|
|
{
|
1996-01-12 17:46:11 +00:00
|
|
|
|
const char* txt;
|
1995-10-25 09:43:56 +00:00
|
|
|
|
|
|
|
|
|
if (cell == NULL)
|
|
|
|
|
{
|
|
|
|
|
XI_OBJ cella;
|
1996-05-08 11:09:13 +00:00
|
|
|
|
XI_MAKE_CELL(&cella, _obj, _cur_row, _cur_col);
|
1996-01-12 17:46:11 +00:00
|
|
|
|
txt = xi_get_text(&cella, NULL, -1);
|
1995-10-25 09:43:56 +00:00
|
|
|
|
}
|
1996-01-12 17:46:11 +00:00
|
|
|
|
else
|
|
|
|
|
txt = xi_get_text(cell, NULL, -1);
|
1996-05-08 11:09:13 +00:00
|
|
|
|
if (_edit_field->is_editable())
|
|
|
|
|
{
|
|
|
|
|
const TString& val = ((TEditable_field*)_edit_field)->win2raw(txt);
|
|
|
|
|
_edit_field->set(val);
|
|
|
|
|
_edit_field->set_dirty(); // Get it dirty!
|
|
|
|
|
}
|
|
|
|
|
return _edit_field->get();
|
1995-10-25 09:43:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
1995-09-29 16:25:36 +00:00
|
|
|
|
bool TSpreadsheet::off_cell_handler(XI_OBJ *cell)
|
|
|
|
|
{
|
|
|
|
|
bool ok = TRUE;
|
|
|
|
|
if (_edit_field != NULL)
|
|
|
|
|
{
|
1995-10-25 09:43:56 +00:00
|
|
|
|
const char* nuo = copy_cell2field(cell);
|
1995-09-29 16:25:36 +00:00
|
|
|
|
if (_edit_field->on_key(_edit_field->is_edit() ? K_TAB : K_SPACE) == FALSE) // Test it
|
1996-01-12 17:46:11 +00:00
|
|
|
|
ok = *nuo == '\0'; // Se e' vuoto lascia stare
|
1996-01-11 15:51:56 +00:00
|
|
|
|
else
|
|
|
|
|
_cell_dirty = FALSE;
|
1995-09-29 16:25:36 +00:00
|
|
|
|
mask2str(_cur_rec); // Update sheet row
|
|
|
|
|
}
|
|
|
|
|
return ok;
|
1995-09-25 11:39:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Certified 75%
|
1996-05-08 11:09:13 +00:00
|
|
|
|
bool TSpreadsheet::event_handler(XI_OBJ* itf, XI_EVENT *xiev)
|
1995-09-25 11:39:10 +00:00
|
|
|
|
{
|
1996-05-08 11:09:13 +00:00
|
|
|
|
static KEY _lastab = K_TAB;
|
|
|
|
|
|
|
|
|
|
BOOLEAN& refused = xiev->refused;
|
1995-09-25 11:39:10 +00:00
|
|
|
|
|
|
|
|
|
switch (xiev->type)
|
|
|
|
|
{
|
|
|
|
|
case XIE_GET_FIRST:
|
|
|
|
|
if (items() > 0L)
|
|
|
|
|
{
|
|
|
|
|
long n = items() * (long)xiev->v.rec_request.percent / 100L;
|
|
|
|
|
if (n < 0L) n = 0L;
|
|
|
|
|
xiev->v.rec_request.data_rec = n;
|
|
|
|
|
}
|
|
|
|
|
else
|
1996-05-08 11:09:13 +00:00
|
|
|
|
refused = TRUE;
|
1995-09-25 11:39:10 +00:00
|
|
|
|
break;
|
|
|
|
|
case XIE_GET_LAST:
|
|
|
|
|
xiev->v.rec_request.data_rec = items()-1;
|
|
|
|
|
break;
|
|
|
|
|
case XIE_GET_PREV:
|
|
|
|
|
case XIE_GET_NEXT:
|
|
|
|
|
{
|
|
|
|
|
const long n = xiev->v.rec_request.spec_rec + (xiev->type == XIE_GET_NEXT ? +1 : -1) ;
|
|
|
|
|
if (n < 0 || n >= items())
|
1996-05-08 11:09:13 +00:00
|
|
|
|
refused = TRUE;
|
1995-09-25 11:39:10 +00:00
|
|
|
|
else
|
|
|
|
|
xiev->v.rec_request.data_rec = n;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case XIE_CELL_REQUEST:
|
|
|
|
|
{
|
|
|
|
|
const int rec = (int)xiev->v.cell_request.rec;
|
|
|
|
|
const char* src = NULL;
|
|
|
|
|
int nm;
|
|
|
|
|
XI_OBJ** obj = xi_get_member_list(xiev->v.cell_request.list, &nm);
|
|
|
|
|
const int num = xiev->v.cell_request.col_nbr;
|
|
|
|
|
const int cid = obj[num]->cid;
|
|
|
|
|
|
|
|
|
|
if (cid >= FIRST_FIELD)
|
|
|
|
|
{
|
|
|
|
|
if (rec < items())
|
|
|
|
|
{
|
|
|
|
|
const int col = cid - FIRST_FIELD;
|
1996-05-08 11:09:13 +00:00
|
|
|
|
const TOperable_field* f = field(cid);
|
|
|
|
|
if (f->is_editable())
|
1995-09-25 11:39:10 +00:00
|
|
|
|
{
|
1996-05-08 11:09:13 +00:00
|
|
|
|
const TEditable_field* e = (const TEditable_field*)f;
|
|
|
|
|
src = row(rec).get(col); // Set value for cell
|
1995-10-02 11:09:12 +00:00
|
|
|
|
if (src && *src)
|
1996-05-08 11:09:13 +00:00
|
|
|
|
src = e->raw2win(src); // Get formatted string
|
|
|
|
|
|
|
|
|
|
if (cell_disabled(rec, col))
|
|
|
|
|
xiev->v.cell_request.back_color = DISABLED_BACK_COLOR;
|
|
|
|
|
else
|
1996-05-13 07:31:27 +00:00
|
|
|
|
if (e->has_query_button())
|
1996-05-08 11:09:13 +00:00
|
|
|
|
{
|
|
|
|
|
xiev->v.cell_request.button = TRUE;
|
|
|
|
|
xiev->v.cell_request.button_on_focus = TRUE;
|
|
|
|
|
}
|
|
|
|
|
}
|
1995-09-25 11:39:10 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
src = format("%d", rec+1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char* dst = xiev->v.cell_request.s;
|
|
|
|
|
if (src && *src)
|
|
|
|
|
{
|
1996-01-05 15:19:23 +00:00
|
|
|
|
const int len = xiev->v.cell_request.len;
|
1995-09-25 11:39:10 +00:00
|
|
|
|
strncpy(dst, src, len);
|
1996-05-08 11:09:13 +00:00
|
|
|
|
dst[len-1] = '\0';
|
1995-09-25 11:39:10 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
*dst = '\0';
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case XIE_CHG_CELL:
|
|
|
|
|
if (_edit_field && !_cell_dirty)
|
|
|
|
|
{
|
|
|
|
|
notify_change();
|
|
|
|
|
_cell_dirty = TRUE;
|
1995-10-31 14:01:20 +00:00
|
|
|
|
_edit_field->set_dirty();
|
1995-09-25 11:39:10 +00:00
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case XIE_BUTTON:
|
|
|
|
|
if (xiev->v.xi_obj->type == XIT_CELL)
|
1996-05-08 11:09:13 +00:00
|
|
|
|
dispatch_e_char(parent(), K_F9);
|
1995-09-25 11:39:10 +00:00
|
|
|
|
else
|
|
|
|
|
if (xiev->v.xi_obj->type == XIT_LIST)
|
1996-05-08 11:09:13 +00:00
|
|
|
|
{
|
|
|
|
|
owner().mask().notify_focus_field(owner().dlg());
|
|
|
|
|
insert(-1);
|
|
|
|
|
}
|
1995-09-25 11:39:10 +00:00
|
|
|
|
break;
|
|
|
|
|
case XIE_SELECT:
|
|
|
|
|
if (xiev->v.xi_obj->type == XIT_ROW)
|
1995-09-29 16:25:36 +00:00
|
|
|
|
{
|
1995-09-25 11:39:10 +00:00
|
|
|
|
_check_enabled = FALSE;
|
1995-10-12 15:04:26 +00:00
|
|
|
|
if (_cell_dirty)
|
1995-10-25 09:43:56 +00:00
|
|
|
|
off_cell_handler();
|
1995-09-29 16:25:36 +00:00
|
|
|
|
|
1995-09-25 11:39:10 +00:00
|
|
|
|
const int oldrec = _cur_rec;
|
1996-01-12 17:46:11 +00:00
|
|
|
|
set_pos(xiev->v.select.xi_obj->v.row, 1);
|
1995-09-25 11:39:10 +00:00
|
|
|
|
if (oldrec != _cur_rec)
|
1995-09-29 16:25:36 +00:00
|
|
|
|
{
|
1995-09-25 11:39:10 +00:00
|
|
|
|
_row_dirty = FALSE;
|
1995-10-25 09:43:56 +00:00
|
|
|
|
on_idle(); // Forces update delayed by str2mask
|
1995-09-29 16:25:36 +00:00
|
|
|
|
}
|
1995-09-25 11:39:10 +00:00
|
|
|
|
|
1996-05-08 11:09:13 +00:00
|
|
|
|
const int button_pos = sheet_mask().id2pos(FIRST_FIELD-1);
|
1995-12-07 11:14:10 +00:00
|
|
|
|
if (button_pos >= 0)
|
1995-09-25 11:39:10 +00:00
|
|
|
|
{
|
1996-05-08 11:09:13 +00:00
|
|
|
|
TMask_field& button = sheet_mask().fld(button_pos);
|
1995-09-29 16:25:36 +00:00
|
|
|
|
if (button.active())
|
|
|
|
|
{
|
1996-05-08 11:09:13 +00:00
|
|
|
|
str2mask(_cur_rec);
|
1995-09-29 16:25:36 +00:00
|
|
|
|
button.on_hit();
|
1996-05-08 11:09:13 +00:00
|
|
|
|
if (sheet_mask().dirty())
|
1995-09-29 16:25:36 +00:00
|
|
|
|
{
|
|
|
|
|
notify_change();
|
|
|
|
|
mask2str(_cur_rec);
|
|
|
|
|
}
|
|
|
|
|
}
|
1995-09-25 11:39:10 +00:00
|
|
|
|
}
|
|
|
|
|
_check_enabled = TRUE;
|
1996-05-08 11:09:13 +00:00
|
|
|
|
owner().highlight();
|
1995-09-25 11:39:10 +00:00
|
|
|
|
}
|
1996-05-08 11:09:13 +00:00
|
|
|
|
refused = TRUE;
|
1995-09-25 11:39:10 +00:00
|
|
|
|
break;
|
|
|
|
|
case XIE_DBL_CELL:
|
|
|
|
|
{
|
|
|
|
|
_check_enabled = FALSE;
|
|
|
|
|
|
|
|
|
|
const int oldrec = _cur_rec;
|
|
|
|
|
if ( xiev->v.xi_obj != NULL )
|
|
|
|
|
{
|
|
|
|
|
set_pos(xiev->v.xi_obj->v.cell.row, xiev->v.xi_obj->v.cell.column);
|
1995-12-20 16:17:48 +00:00
|
|
|
|
}
|
1995-09-25 11:39:10 +00:00
|
|
|
|
|
|
|
|
|
if (oldrec != _cur_rec || !_row_dirty)
|
|
|
|
|
{
|
|
|
|
|
_row_dirty = FALSE;
|
|
|
|
|
notify_change();
|
|
|
|
|
}
|
|
|
|
|
const KEY k = edit(_cur_rec);
|
|
|
|
|
if (k == K_ENTER)
|
|
|
|
|
{
|
|
|
|
|
update_rec(_cur_rec);
|
|
|
|
|
_row_dirty = TRUE;
|
|
|
|
|
} else
|
|
|
|
|
if (k == K_DEL)
|
|
|
|
|
{
|
|
|
|
|
_row_dirty = _cell_dirty = FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
1995-10-25 09:43:56 +00:00
|
|
|
|
if (_cur_rec >= items())
|
|
|
|
|
{
|
|
|
|
|
_row_dirty = _cell_dirty = FALSE;
|
1996-01-04 14:53:23 +00:00
|
|
|
|
_cur_rec = items()-1;
|
|
|
|
|
_cur_row = 0; _cur_col = 1;
|
1995-10-25 09:43:56 +00:00
|
|
|
|
}
|
1996-01-04 14:53:23 +00:00
|
|
|
|
if (_cur_rec >= 0 && _cur_rec < items())
|
1995-09-25 11:39:10 +00:00
|
|
|
|
set_focus_cell(_cur_row, _cur_col);
|
|
|
|
|
_check_enabled = TRUE;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case XIE_ON_LIST:
|
1996-05-08 11:09:13 +00:00
|
|
|
|
owner().mask().notify_focus_field(owner().dlg());
|
1995-09-25 11:39:10 +00:00
|
|
|
|
break;
|
|
|
|
|
case XIE_OFF_LIST:
|
1995-10-25 09:43:56 +00:00
|
|
|
|
on_idle();
|
1995-09-25 11:39:10 +00:00
|
|
|
|
break;
|
|
|
|
|
case XIE_ON_ROW:
|
|
|
|
|
if (_check_enabled)
|
1996-05-08 11:09:13 +00:00
|
|
|
|
{
|
|
|
|
|
// Setta _cur_rec in base a alla riga e cella correnti
|
1995-09-25 11:39:10 +00:00
|
|
|
|
set_pos(xiev->v.xi_obj->v.row, _cur_col);
|
|
|
|
|
if (_cur_rec < items() && notify(_cur_rec, K_TAB))
|
|
|
|
|
{
|
1996-05-08 11:09:13 +00:00
|
|
|
|
/* Guy! str2mask(_cur_rec); */
|
1995-09-25 11:39:10 +00:00
|
|
|
|
_row_dirty = FALSE;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
_cur_row = _cur_rec = 0;
|
1996-05-08 11:09:13 +00:00
|
|
|
|
refused = TRUE;
|
1995-09-25 11:39:10 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case XIE_OFF_ROW:
|
1995-09-26 11:47:07 +00:00
|
|
|
|
if (_check_enabled)
|
|
|
|
|
{
|
|
|
|
|
_check_enabled = FALSE; // Avoid recursion!
|
1995-12-29 11:57:26 +00:00
|
|
|
|
if (_row_dirty && active())
|
1995-09-26 11:47:07 +00:00
|
|
|
|
{
|
|
|
|
|
bool ok = sheet_mask().check_fields();
|
|
|
|
|
if (ok)
|
|
|
|
|
{
|
|
|
|
|
mask2str(_cur_rec); // Update sheet with mask contents
|
|
|
|
|
ok = notify(_cur_rec, K_ENTER); // Notify edit
|
1996-01-03 12:12:03 +00:00
|
|
|
|
_row_dirty = FALSE; // Avoid double notifications!
|
1995-09-26 11:47:07 +00:00
|
|
|
|
}
|
|
|
|
|
if (ok)
|
1995-10-06 13:55:48 +00:00
|
|
|
|
{
|
1995-09-26 11:47:07 +00:00
|
|
|
|
xvt_statbar_refresh();
|
1995-10-06 13:55:48 +00:00
|
|
|
|
}
|
1995-09-26 11:47:07 +00:00
|
|
|
|
else
|
|
|
|
|
{
|
1996-05-08 11:09:13 +00:00
|
|
|
|
refused = TRUE;
|
1995-09-26 11:47:07 +00:00
|
|
|
|
}
|
1995-10-25 09:43:56 +00:00
|
|
|
|
}
|
1996-05-08 11:09:13 +00:00
|
|
|
|
if (!refused)
|
1995-10-25 09:43:56 +00:00
|
|
|
|
{
|
|
|
|
|
// Notifica l'abbandono della riga
|
|
|
|
|
notify(_cur_rec, K_CTRL+K_TAB);
|
1995-09-25 11:39:10 +00:00
|
|
|
|
}
|
|
|
|
|
_check_enabled = TRUE;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case XIE_ON_CELL:
|
|
|
|
|
if (_check_enabled)
|
|
|
|
|
{
|
1996-05-08 11:09:13 +00:00
|
|
|
|
TOperable_field* f = cell2field(xiev->v.xi_obj);
|
1995-12-20 16:17:48 +00:00
|
|
|
|
const int logical_column = (f->dlg()-FIRST_FIELD) % 100;
|
|
|
|
|
const int physical_column = xiev->v.xi_obj->v.cell.column;
|
|
|
|
|
if (cell_disabled(_cur_rec, logical_column)) // If the cell is disabled ...
|
1995-12-01 11:49:11 +00:00
|
|
|
|
{
|
|
|
|
|
const int dir = _lastab == K_TAB ? +1 : -1;
|
1995-12-20 16:17:48 +00:00
|
|
|
|
const int nex = find_enabled_column(_cur_rec, physical_column, dir);
|
1995-12-01 11:49:11 +00:00
|
|
|
|
if (nex > 0) // If at least one enabled cell exists
|
|
|
|
|
{
|
|
|
|
|
set_focus_cell(_cur_row, nex);
|
1995-10-06 13:26:53 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
1996-05-08 11:09:13 +00:00
|
|
|
|
refused = TRUE;
|
1995-09-25 11:39:10 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
_edit_field = f;
|
1995-12-20 16:17:48 +00:00
|
|
|
|
_cur_col = physical_column;
|
1995-09-25 11:39:10 +00:00
|
|
|
|
_edit_field->set_focusdirty(_cell_dirty = FALSE);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case XIE_OFF_CELL:
|
1995-09-29 16:25:36 +00:00
|
|
|
|
if (_edit_field && _check_enabled && _cell_dirty)
|
1995-09-25 11:39:10 +00:00
|
|
|
|
{
|
|
|
|
|
_check_enabled = FALSE;
|
1995-09-29 16:25:36 +00:00
|
|
|
|
XI_OBJ* cell = xiev->v.xi_obj;
|
1996-05-08 11:09:13 +00:00
|
|
|
|
refused = !off_cell_handler(cell);
|
1995-09-25 11:39:10 +00:00
|
|
|
|
_check_enabled = TRUE;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case XIE_GET_PERCENT:
|
|
|
|
|
{
|
|
|
|
|
const long rec = xiev->v.get_percent.record;
|
1995-12-23 09:43:52 +00:00
|
|
|
|
long n = items(); if (n <= 0) n = 1;
|
1995-09-25 11:39:10 +00:00
|
|
|
|
xiev->v.get_percent.percent = int(rec * 100L / n);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case XIE_CLEANUP:
|
|
|
|
|
break;
|
1996-05-08 11:09:13 +00:00
|
|
|
|
case XIE_CHAR_CELL:
|
|
|
|
|
if (_edit_field)
|
1995-09-25 11:39:10 +00:00
|
|
|
|
{
|
1996-05-08 11:09:13 +00:00
|
|
|
|
const KEY k = xiev_to_key(xiev);
|
|
|
|
|
switch(k)
|
1995-09-25 11:39:10 +00:00
|
|
|
|
{
|
|
|
|
|
case K_F1:
|
|
|
|
|
_check_enabled = FALSE; // Disable checks
|
1995-10-11 11:42:19 +00:00
|
|
|
|
_edit_field->on_key(k);
|
1995-09-25 11:39:10 +00:00
|
|
|
|
set_focus_cell(_cur_row, _cur_col);
|
|
|
|
|
_check_enabled = TRUE; // Enable checks
|
|
|
|
|
break;
|
|
|
|
|
case K_F8:
|
|
|
|
|
case K_F9:
|
1995-10-25 09:43:56 +00:00
|
|
|
|
if (_edit_field != NULL)
|
1996-05-08 11:09:13 +00:00
|
|
|
|
{
|
|
|
|
|
/* Guy! */
|
|
|
|
|
notify_change();
|
1995-10-25 09:43:56 +00:00
|
|
|
|
copy_cell2field();
|
1996-05-08 11:09:13 +00:00
|
|
|
|
}
|
1995-10-25 09:43:56 +00:00
|
|
|
|
case K_F2:
|
|
|
|
|
case K_F3:
|
1995-09-25 11:39:10 +00:00
|
|
|
|
case K_F11:
|
|
|
|
|
if (_check_enabled && active())
|
|
|
|
|
{
|
|
|
|
|
_check_enabled = FALSE; // Disable checks
|
|
|
|
|
notify_change();
|
1996-05-08 11:09:13 +00:00
|
|
|
|
bool ok = TRUE;
|
|
|
|
|
|
1996-05-10 09:26:40 +00:00
|
|
|
|
if (_edit_field->is_kind_of(CLASS_LIST_FIELD) && k == K_F9) // list
|
1996-05-08 11:09:13 +00:00
|
|
|
|
{
|
|
|
|
|
XI_OBJ cell; XI_MAKE_CELL(&cell, _obj, _cur_row, _cur_col);
|
1996-05-10 09:26:40 +00:00
|
|
|
|
// droppa giu'
|
1996-05-08 11:09:13 +00:00
|
|
|
|
TList_field& lst = (TList_field&)(*_edit_field);
|
1996-05-10 09:26:40 +00:00
|
|
|
|
TDropDownList ddl(&cell, lst.get_values(), lst.size(), TRUE);
|
1996-05-08 11:09:13 +00:00
|
|
|
|
ddl.open();
|
|
|
|
|
while (ddl.is_open())
|
1996-05-10 09:26:40 +00:00
|
|
|
|
do_events();
|
|
|
|
|
// sdroppa su
|
|
|
|
|
copy_cell2field(); /* ci vuole ma non basta */
|
1996-05-08 11:09:13 +00:00
|
|
|
|
}
|
|
|
|
|
else // edit_field
|
1995-09-25 11:39:10 +00:00
|
|
|
|
{
|
1996-05-08 11:09:13 +00:00
|
|
|
|
ok = _edit_field->on_key(k);
|
|
|
|
|
|
|
|
|
|
if (!ok && k == K_F9) // Ricerca non completata?
|
1995-09-25 11:39:10 +00:00
|
|
|
|
{
|
1996-05-08 11:09:13 +00:00
|
|
|
|
_edit_field = &sheet_mask().focus_field();
|
|
|
|
|
const int col = field2col(_edit_field);
|
|
|
|
|
|
|
|
|
|
if (col != _cur_col) // Ricerca alternativa
|
|
|
|
|
{
|
|
|
|
|
_cur_col = col;
|
|
|
|
|
dispatch_e_char(parent(), K_F9);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
1995-09-25 11:39:10 +00:00
|
|
|
|
if (ok)
|
|
|
|
|
{
|
|
|
|
|
mask2str(_cur_rec);
|
1995-10-25 09:43:56 +00:00
|
|
|
|
on_idle(); // Update immediately!
|
1995-09-25 11:39:10 +00:00
|
|
|
|
}
|
1995-10-25 09:43:56 +00:00
|
|
|
|
_check_enabled = TRUE; // Re-enable checks
|
1995-09-25 11:39:10 +00:00
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case K_PREV:
|
|
|
|
|
case K_NEXT:
|
|
|
|
|
case K_ESC:
|
1996-05-08 11:09:13 +00:00
|
|
|
|
if (xi_move_focus(get_interface()))
|
1995-09-25 11:39:10 +00:00
|
|
|
|
dispatch_e_char(parent(), k);
|
|
|
|
|
break;
|
|
|
|
|
case K_ENTER:
|
1996-05-08 11:09:13 +00:00
|
|
|
|
case K_SHIFT+K_ENTER:
|
|
|
|
|
case K_CTRL+K_ENTER:
|
|
|
|
|
if (xi_move_focus(get_interface()))
|
|
|
|
|
dispatch_e_char(parent(), (k == K_ENTER || k == K_CTRL+K_ENTER) ? K_TAB : K_BTAB);
|
1995-09-25 11:39:10 +00:00
|
|
|
|
break;
|
|
|
|
|
case K_CTRL+K_PREV:
|
1996-05-08 11:09:13 +00:00
|
|
|
|
xi_scroll(_obj, XI_SCROLL_PGUP);
|
1995-09-25 11:39:10 +00:00
|
|
|
|
break;
|
|
|
|
|
case K_CTRL+K_NEXT:
|
1996-05-08 11:09:13 +00:00
|
|
|
|
xi_scroll(_obj, XI_SCROLL_PGDOWN);
|
1995-09-25 11:39:10 +00:00
|
|
|
|
break;
|
|
|
|
|
case K_CTRL+K_HOME:
|
1996-05-08 11:09:13 +00:00
|
|
|
|
xi_scroll(_obj, XI_SCROLL_FIRST);
|
1995-09-25 11:39:10 +00:00
|
|
|
|
break;
|
|
|
|
|
case K_CTRL+K_END:
|
1996-05-08 11:09:13 +00:00
|
|
|
|
xi_scroll(_obj, XI_SCROLL_LAST);
|
1995-09-25 11:39:10 +00:00
|
|
|
|
break;
|
|
|
|
|
default:
|
1996-05-08 11:09:13 +00:00
|
|
|
|
if (is_edit_key(k) && !_edit_field->on_key(k))
|
|
|
|
|
{
|
|
|
|
|
refused = TRUE;
|
|
|
|
|
beep();
|
1996-05-10 09:26:40 +00:00
|
|
|
|
}
|
|
|
|
|
else if(_edit_field->is_kind_of(CLASS_LIST_FIELD))
|
|
|
|
|
{
|
|
|
|
|
XI_OBJ cell;
|
|
|
|
|
XI_MAKE_CELL(&cell, _obj, _cur_row, _cur_col);
|
|
|
|
|
TList_field& lst = ((TList_field&)*_edit_field);
|
|
|
|
|
|
|
|
|
|
if (k < 128 && isalnum(k))
|
|
|
|
|
{
|
|
|
|
|
lst.select_by_initial(k);
|
|
|
|
|
xi_set_text(&cell, (char*)lst.raw2win(lst.get()));
|
|
|
|
|
}
|
|
|
|
|
else if (k == K_RIGHT)
|
|
|
|
|
{
|
|
|
|
|
lst.select_next();
|
|
|
|
|
xi_set_text(&cell, (char*)lst.raw2win(lst.get()));
|
|
|
|
|
}
|
|
|
|
|
else if (k == K_LEFT)
|
|
|
|
|
{
|
|
|
|
|
lst.select_prev();
|
|
|
|
|
xi_set_text(&cell, (char*)lst.raw2win(lst.get()));
|
|
|
|
|
}
|
|
|
|
|
refused = TRUE;
|
1996-05-08 11:09:13 +00:00
|
|
|
|
}
|
1995-09-25 11:39:10 +00:00
|
|
|
|
break;
|
|
|
|
|
}
|
1996-05-08 11:09:13 +00:00
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case XIE_XVT_EVENT:
|
|
|
|
|
if (xiev->v.xvte.type == E_CHAR)
|
|
|
|
|
{
|
|
|
|
|
const KEY k = e_char_to_key(&xiev->v.xvte);
|
|
|
|
|
switch (k)
|
|
|
|
|
{
|
|
|
|
|
case K_ROWEDIT:
|
|
|
|
|
xiev->type = XIE_DBL_CELL;
|
|
|
|
|
xiev->v.xi_obj = NULL;
|
|
|
|
|
event_handler(itf, xiev);
|
|
|
|
|
break;
|
|
|
|
|
case K_TAB:
|
|
|
|
|
case K_BTAB:
|
|
|
|
|
_lastab = k;
|
|
|
|
|
break;
|
|
|
|
|
case K_UP:
|
|
|
|
|
case K_DOWN:
|
|
|
|
|
_lastab = (_cur_col == 2) ? K_BTAB : K_TAB;
|
|
|
|
|
break;
|
|
|
|
|
case K_ENTER:
|
|
|
|
|
case K_SHIFT+K_ENTER:
|
|
|
|
|
if (xi_move_focus(get_interface()))
|
|
|
|
|
dispatch_e_char(parent(), k == K_ENTER ? K_TAB : K_BTAB);
|
|
|
|
|
break;
|
|
|
|
|
case K_ESC:
|
|
|
|
|
if (xi_move_focus(get_interface()))
|
|
|
|
|
dispatch_e_char(parent(), k);
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
1995-09-25 11:39:10 +00:00
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
1996-05-08 11:09:13 +00:00
|
|
|
|
|
|
|
|
|
return !refused;
|
1995-09-25 11:39:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TSpreadsheet::activate(bool on)
|
|
|
|
|
{
|
|
|
|
|
_active = on;
|
|
|
|
|
|
1996-05-08 11:09:13 +00:00
|
|
|
|
const dword old = xi_get_attrib(_obj);
|
1995-09-25 11:39:10 +00:00
|
|
|
|
dword att = on ? (old & ~XI_ATR_NAVIGATE) : (old | XI_ATR_NAVIGATE);
|
|
|
|
|
if (old != att)
|
|
|
|
|
{
|
|
|
|
|
int num;
|
1996-05-08 11:09:13 +00:00
|
|
|
|
XI_OBJ** columns = xi_get_member_list(_obj, &num);
|
1995-09-25 11:39:10 +00:00
|
|
|
|
|
1996-05-08 11:09:13 +00:00
|
|
|
|
xi_move_focus(get_interface()); // Set focus to interface
|
1995-09-25 11:39:10 +00:00
|
|
|
|
if (on)
|
|
|
|
|
att |= XI_ATR_TABWRAP;
|
|
|
|
|
else
|
|
|
|
|
att &= ~XI_ATR_TABWRAP;
|
|
|
|
|
|
1996-05-08 11:09:13 +00:00
|
|
|
|
xi_set_attrib(_obj, att);
|
1995-09-25 11:39:10 +00:00
|
|
|
|
|
|
|
|
|
for (int col = 1; col < num; col++)
|
|
|
|
|
{
|
|
|
|
|
XI_OBJ* column = columns[col];
|
|
|
|
|
att = xi_get_attrib(column);
|
|
|
|
|
if (on)
|
|
|
|
|
{
|
|
|
|
|
att &= ~XI_ATR_READONLY;
|
|
|
|
|
att |= XI_ATR_AUTOSELECT;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
att |= XI_ATR_READONLY;
|
|
|
|
|
att &= ~XI_ATR_AUTOSELECT;
|
|
|
|
|
}
|
|
|
|
|
xi_set_attrib(column, att); // Set new attributes
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
1996-01-11 15:51:56 +00:00
|
|
|
|
void TSpreadsheet::select(int rec, bool scrollto)
|
1995-10-11 11:42:19 +00:00
|
|
|
|
{
|
1996-01-11 15:51:56 +00:00
|
|
|
|
if (!scrollto)
|
1996-01-19 13:02:25 +00:00
|
|
|
|
{
|
|
|
|
|
int rows;
|
1996-05-08 11:09:13 +00:00
|
|
|
|
const long* handle = xi_get_list_info(_obj, &rows);
|
1996-01-19 13:02:25 +00:00
|
|
|
|
|
|
|
|
|
int first = 0, last = 0;
|
1996-05-08 11:09:13 +00:00
|
|
|
|
xi_get_visible_rows(_obj, &first, &last);
|
1996-01-19 13:02:25 +00:00
|
|
|
|
|
|
|
|
|
scrollto = rec < handle[first] || rec > handle[last];
|
|
|
|
|
}
|
1996-01-11 15:51:56 +00:00
|
|
|
|
|
1996-01-19 13:02:25 +00:00
|
|
|
|
if (scrollto)
|
1996-05-08 11:09:13 +00:00
|
|
|
|
xi_scroll_rec(_obj, rec, NORMAL_COLOR, XI_ATR_ENABLED | XI_ATR_AUTOSELECT, 0);
|
1996-01-11 15:51:56 +00:00
|
|
|
|
|
|
|
|
|
const int row = rec2row(rec);
|
1996-05-08 11:09:13 +00:00
|
|
|
|
const bool has_focus = mask().focus_field().dlg() == owner().dlg();
|
1996-01-22 11:07:49 +00:00
|
|
|
|
if (has_focus)
|
|
|
|
|
{
|
|
|
|
|
_cur_rec = -1;
|
|
|
|
|
set_focus_cell(row, 1);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
_edit_field = col2field(_cur_col = 1);
|
|
|
|
|
_cur_rec = rec;
|
|
|
|
|
_cur_row = row;
|
|
|
|
|
str2mask(_cur_rec);
|
|
|
|
|
_row_dirty = FALSE;
|
|
|
|
|
}
|
1996-01-11 15:51:56 +00:00
|
|
|
|
notify(rec, K_TAB);
|
1995-09-25 11:39:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
1995-12-07 11:14:10 +00:00
|
|
|
|
void TSpreadsheet::on_idle()
|
|
|
|
|
{
|
|
|
|
|
if (_needs_update >= 0)
|
|
|
|
|
{
|
|
|
|
|
if (_needs_update < items())
|
|
|
|
|
update_rec(_needs_update);
|
|
|
|
|
_needs_update = -1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
1996-02-05 19:00:53 +00:00
|
|
|
|
// @doc INTERNAL
|
|
|
|
|
|
1995-12-07 11:14:10 +00:00
|
|
|
|
// @mfunc Cerca la colonna col
|
|
|
|
|
XI_OBJ* TSpreadsheet::find_column(
|
1996-01-31 17:19:02 +00:00
|
|
|
|
int col) const // @parm Indice o identificatore colonna
|
1995-12-07 11:14:10 +00:00
|
|
|
|
{
|
|
|
|
|
CHECKD(col >= 0, "Bad column ", col);
|
1995-12-23 09:43:52 +00:00
|
|
|
|
if (col < FIRST_FIELD) // Se e' un indice trasformalo in identificatore
|
1995-12-07 11:14:10 +00:00
|
|
|
|
col += FIRST_FIELD;
|
1995-12-23 09:43:52 +00:00
|
|
|
|
else
|
|
|
|
|
if (col >= FIRST_FIELD+100) // Riportalo nel range 101 - 199
|
|
|
|
|
col = FIRST_FIELD + (col % 100) -1;
|
|
|
|
|
|
1995-12-07 11:14:10 +00:00
|
|
|
|
int num;
|
1996-05-08 11:09:13 +00:00
|
|
|
|
XI_OBJ** columns = xi_get_member_list(_obj, &num);
|
1995-12-23 09:43:52 +00:00
|
|
|
|
for (int c = num-1; c > 0; c--)
|
1995-12-07 11:14:10 +00:00
|
|
|
|
{
|
|
|
|
|
if (columns[c]->cid == col)
|
|
|
|
|
break;
|
|
|
|
|
}
|
1995-12-20 16:17:48 +00:00
|
|
|
|
|
1995-12-23 09:43:52 +00:00
|
|
|
|
if (c <= 0)
|
1995-12-07 11:14:10 +00:00
|
|
|
|
{
|
|
|
|
|
yesnofatal_box("Can't find column with id=%d", col);
|
1995-12-23 09:43:52 +00:00
|
|
|
|
c = 1;
|
1995-12-07 11:14:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return columns[c];
|
|
|
|
|
}
|
|
|
|
|
|
1995-09-25 11:39:10 +00:00
|
|
|
|
|
|
|
|
|
TMask& TSpreadsheet::mask() const
|
|
|
|
|
{
|
|
|
|
|
TMask* m = (TMask*)xvt_vobj_get_data(parent());
|
|
|
|
|
return *m;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Ritorna il campo con l'identificatore dato della maschera dello sheet
|
1996-05-08 11:09:13 +00:00
|
|
|
|
TOperable_field* TSpreadsheet::field(short id) const
|
1995-09-25 11:39:10 +00:00
|
|
|
|
{
|
1995-10-06 16:38:58 +00:00
|
|
|
|
const int pos = sheet_mask().id2pos(id);
|
1996-05-08 11:09:13 +00:00
|
|
|
|
return pos < 0 ? NULL : (TOperable_field*)&sheet_mask().fld(pos);
|
1995-09-25 11:39:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Ricopia i campi della maschera nel record dato ed aggiorna il display
|
|
|
|
|
void TSpreadsheet::mask2str(int rec)
|
1995-12-23 09:43:52 +00:00
|
|
|
|
{
|
1995-09-25 11:39:10 +00:00
|
|
|
|
TToken_string& r = row(rec);
|
1996-05-08 11:09:13 +00:00
|
|
|
|
|
|
|
|
|
owner().mask2row(rec, r);
|
|
|
|
|
|
1995-09-25 11:39:10 +00:00
|
|
|
|
if (_needs_update != rec)
|
|
|
|
|
{
|
|
|
|
|
if (_needs_update >= 0)
|
1996-05-08 11:09:13 +00:00
|
|
|
|
update_rec(_needs_update); // Double update!
|
1995-09-25 11:39:10 +00:00
|
|
|
|
_needs_update = rec;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Certified 50%
|
1996-02-05 19:00:53 +00:00
|
|
|
|
// @doc INTERNAL
|
|
|
|
|
|
1995-09-25 11:39:10 +00:00
|
|
|
|
// @mfunc Permette di abilitare/disabilitare una singola cella
|
|
|
|
|
void TSpreadsheet::enable_cell(
|
|
|
|
|
int row, // @parm Riga della cella da abilitare/disabilitare
|
|
|
|
|
int column, // @parm Colonna della cella da abilitare/disabilitare
|
|
|
|
|
bool on) // @parm Indica l'operazione da effettuare sulla cella:
|
|
|
|
|
//
|
|
|
|
|
// @flag TRUE | La cella viene abilitata (default)
|
|
|
|
|
// @flag FALSE| La cella viene disabilitata
|
|
|
|
|
{
|
|
|
|
|
TBit_array* ba = (TBit_array*)_disabled.objptr(row);
|
|
|
|
|
if (ba == NULL)
|
|
|
|
|
{
|
|
|
|
|
if (on) return; // Don't waste time and memory
|
1996-01-03 12:12:03 +00:00
|
|
|
|
ba = new TBit_array(column);
|
1995-09-25 11:39:10 +00:00
|
|
|
|
_disabled.add(ba, row);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (column >= 0)
|
1995-12-23 09:43:52 +00:00
|
|
|
|
{
|
1995-09-25 11:39:10 +00:00
|
|
|
|
ba->set(column, !on);
|
1995-12-23 09:43:52 +00:00
|
|
|
|
}
|
1995-09-25 11:39:10 +00:00
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (on)
|
|
|
|
|
_disabled.destroy(row, FALSE); // Let's save some memory!
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
ba->set(_columns); // Force right array size
|
|
|
|
|
ba->set(); // Set all bits
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
1996-02-05 19:00:53 +00:00
|
|
|
|
// @doc INTERNAL
|
|
|
|
|
|
1995-09-25 11:39:10 +00:00
|
|
|
|
// @mfunc Permette di abilitare/disabiltare una colonna
|
|
|
|
|
void TSpreadsheet::enable_column(
|
|
|
|
|
int col, // @parm Numero della colonna da abilitare/disabilitare
|
|
|
|
|
bool on) // @parm Indica l'operazione da effettuare sulla colonna:
|
|
|
|
|
//
|
|
|
|
|
// @flag TRUE | Abilita la colonna (default)
|
|
|
|
|
// @flag FALSE| Disabilita la colonna
|
|
|
|
|
{
|
1995-12-23 09:43:52 +00:00
|
|
|
|
if (col >= FIRST_FIELD)
|
|
|
|
|
col = cid2col(col);
|
1995-09-25 11:39:10 +00:00
|
|
|
|
const bool change = _column_disabled[col] == on;
|
|
|
|
|
_column_disabled.set(col, !on);
|
1996-05-08 11:09:13 +00:00
|
|
|
|
|
1995-09-25 11:39:10 +00:00
|
|
|
|
if (change)
|
|
|
|
|
{
|
1995-12-23 09:43:52 +00:00
|
|
|
|
XI_OBJ* column = find_column(col);
|
|
|
|
|
dword attr = xi_get_attrib(column);
|
|
|
|
|
if (on) attr |= XI_ATR_ENABLED;
|
|
|
|
|
else attr &= ~XI_ATR_ENABLED;
|
1995-09-25 11:39:10 +00:00
|
|
|
|
|
1995-12-23 09:43:52 +00:00
|
|
|
|
xi_set_attrib(column, attr); // Set new attributes
|
|
|
|
|
update(-1);
|
1995-09-25 11:39:10 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
1995-11-09 08:07:36 +00:00
|
|
|
|
|
|
|
|
|
void TSpreadsheet::delete_column( const int col ) const
|
|
|
|
|
{
|
|
|
|
|
XI_OBJ* column = find_column(col);
|
1995-09-25 11:39:10 +00:00
|
|
|
|
xi_delete( column );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void TSpreadsheet::move_column( const int fromindex, const int toindex) const
|
|
|
|
|
{
|
|
|
|
|
int num;
|
1996-05-08 11:09:13 +00:00
|
|
|
|
XI_OBJ** columns = xi_get_member_list(_obj, &num);
|
1995-09-25 11:39:10 +00:00
|
|
|
|
CHECKD(fromindex+1 < num, "Can't move column ", fromindex);
|
|
|
|
|
XI_OBJ* column = columns[fromindex+1];
|
|
|
|
|
|
|
|
|
|
xi_move_column( column, toindex );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TSpreadsheet::swap_columns(const int fromid, const int toid) const
|
|
|
|
|
{
|
|
|
|
|
int num;
|
1996-05-08 11:09:13 +00:00
|
|
|
|
XI_OBJ** columns = xi_get_member_list(_obj, &num);
|
1995-09-25 11:39:10 +00:00
|
|
|
|
|
|
|
|
|
XI_OBJ* from_column = XI_NULL_OBJ;
|
|
|
|
|
XI_OBJ* to_column = XI_NULL_OBJ;
|
|
|
|
|
int from_pos = 0;
|
|
|
|
|
int to_pos = 0;
|
|
|
|
|
|
1995-12-29 11:57:26 +00:00
|
|
|
|
for (int c = num-1; c > 0; c--)
|
1995-09-25 11:39:10 +00:00
|
|
|
|
{
|
|
|
|
|
XI_OBJ* column = columns[c];
|
|
|
|
|
if (column->cid == fromid)
|
|
|
|
|
{
|
|
|
|
|
from_column = column;
|
|
|
|
|
from_pos = c;
|
|
|
|
|
}
|
|
|
|
|
if (column->cid == toid)
|
|
|
|
|
{
|
|
|
|
|
to_column = column;
|
|
|
|
|
to_pos = c;
|
|
|
|
|
};
|
|
|
|
|
}
|
1995-12-29 11:57:26 +00:00
|
|
|
|
CHECKD(from_pos, "Can't swap column ", fromid);
|
|
|
|
|
CHECKD(to_pos, "Can't swap column ", toid);
|
1995-09-25 11:39:10 +00:00
|
|
|
|
xi_move_column(from_column, to_pos);
|
|
|
|
|
xi_move_column(to_column, from_pos);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TSpreadsheet::swap_rows( const int fromindex, const int toindex)
|
|
|
|
|
{
|
|
|
|
|
_str.swap(fromindex, toindex);
|
|
|
|
|
_disabled.swap(fromindex, toindex);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TSpreadsheet::set_column_width(const int col, const int width) const
|
|
|
|
|
{
|
1995-11-09 08:07:36 +00:00
|
|
|
|
XI_OBJ* column = find_column(col);
|
1995-09-25 11:39:10 +00:00
|
|
|
|
xi_set_column_width(column, width); // Force redraw
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TSpreadsheet::set_column_header(const int col, const TString& header) const
|
|
|
|
|
{
|
1995-11-09 08:07:36 +00:00
|
|
|
|
XI_OBJ* column = find_column(col);
|
1995-09-25 11:39:10 +00:00
|
|
|
|
xi_set_text(column, (char *)(const char *)header );
|
|
|
|
|
RCT r; xi_get_rect(column, &r);
|
|
|
|
|
xi_set_column_width(column, (r.right-r.left+1) / CHARX); // Force redraw
|
|
|
|
|
}
|
|
|
|
|
|
1995-11-09 08:07:36 +00:00
|
|
|
|
void TSpreadsheet::set_column_justify(int col, bool right)
|
|
|
|
|
{
|
|
|
|
|
XI_OBJ* column = find_column(col);
|
|
|
|
|
dword attr = xi_get_attrib(column);
|
|
|
|
|
if (right)
|
|
|
|
|
attr |= XI_ATR_RJUST;
|
|
|
|
|
else
|
|
|
|
|
attr &= ~XI_ATR_RJUST;
|
|
|
|
|
xi_set_attrib(column, attr); // Set new attribute
|
|
|
|
|
update(-1);
|
|
|
|
|
}
|
1995-09-25 11:39:10 +00:00
|
|
|
|
|
|
|
|
|
// Certified 99%
|
1996-02-05 19:00:53 +00:00
|
|
|
|
// @doc INTERNAL
|
|
|
|
|
|
1995-10-06 13:26:53 +00:00
|
|
|
|
// @mfunc Controlla se una cella o un'intera riga e' disabilitata
|
|
|
|
|
//
|
|
|
|
|
// @rdesc Se column e' minore di zero si considera l'intera riga
|
|
|
|
|
// @rdesc Ritorna lo stato della cella indicata:
|
1995-09-25 11:39:10 +00:00
|
|
|
|
//
|
|
|
|
|
// @flag TRUE | Se la cella e' disabilitata
|
|
|
|
|
// @flag FALSE| Se la cella e' abilitata
|
|
|
|
|
bool TSpreadsheet::cell_disabled(int row, int column) const
|
|
|
|
|
{
|
|
|
|
|
TBit_array* ba = (TBit_array*)_disabled.objptr(row);
|
1995-10-06 13:26:53 +00:00
|
|
|
|
bool d;
|
|
|
|
|
if (column < 0)
|
1995-12-23 09:43:52 +00:00
|
|
|
|
d = (ba == NULL) ? FALSE : (ba->ones() >= columns()-1);
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
d = _column_disabled[column]; // Controlla la colonna
|
|
|
|
|
if (d == FALSE && ba != NULL) // Se la colonna e' disabilitata e' inutile proseguire
|
|
|
|
|
d = (*ba)[column]; // Controlla la cella
|
|
|
|
|
}
|
1995-10-06 13:26:53 +00:00
|
|
|
|
return d;
|
1995-09-25 11:39:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Certified 75%
|
|
|
|
|
void TSpreadsheet::str2mask(int riga)
|
|
|
|
|
{
|
|
|
|
|
if (riga == items())
|
|
|
|
|
{
|
|
|
|
|
sheet_mask().reset();
|
|
|
|
|
mask2str(riga);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TToken_string& r = row(riga);
|
|
|
|
|
|
1996-05-08 11:09:13 +00:00
|
|
|
|
owner().row2mask(riga, r);
|
1995-09-25 11:39:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Certified 100%
|
|
|
|
|
bool TSpreadsheet::notify(int rec, KEY k)
|
|
|
|
|
{
|
1996-05-08 11:09:13 +00:00
|
|
|
|
const bool ok = _notify ? _notify(owner(), rec, k) : TRUE;
|
1995-09-25 11:39:10 +00:00
|
|
|
|
if (k == K_ENTER)
|
|
|
|
|
set_dirty(ok ? TRUE : 3);
|
|
|
|
|
return ok;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Certified 99%
|
1996-05-08 11:09:13 +00:00
|
|
|
|
KEY TSpreadsheet::edit(int n)
|
1995-09-25 11:39:10 +00:00
|
|
|
|
{
|
|
|
|
|
str2mask(n);
|
1996-05-08 11:09:13 +00:00
|
|
|
|
KEY k = owner().run_editmask(n);
|
1995-09-25 11:39:10 +00:00
|
|
|
|
|
1996-01-23 15:39:27 +00:00
|
|
|
|
if (active)
|
1995-09-25 11:39:10 +00:00
|
|
|
|
{
|
1996-01-23 15:39:27 +00:00
|
|
|
|
if (k == K_ENTER)
|
1995-09-25 11:39:10 +00:00
|
|
|
|
{
|
1996-01-23 15:39:27 +00:00
|
|
|
|
mask2str(n);
|
1995-09-25 11:39:10 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
1996-01-23 15:39:27 +00:00
|
|
|
|
{
|
|
|
|
|
if (k == K_DEL)
|
|
|
|
|
{
|
|
|
|
|
const bool ok = notify(n, K_DEL); // Notifica intenzione di cancellare
|
|
|
|
|
if (ok)
|
|
|
|
|
{
|
|
|
|
|
destroy(n);
|
|
|
|
|
if (n < items())
|
|
|
|
|
str2mask(n);
|
|
|
|
|
notify(n, K_CTRL+K_DEL); // Notifica l'avvenuta cancellazione
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
if (k == K_ESC)
|
|
|
|
|
{
|
|
|
|
|
str2mask(n); // Ripristina valori precedenti
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
1995-09-25 11:39:10 +00:00
|
|
|
|
return k;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////
|
|
|
|
|
// TSheet_field
|
|
|
|
|
///////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
// Certified 100%
|
|
|
|
|
TSheet_field::TSheet_field(TMask* m)
|
1996-05-08 11:09:13 +00:00
|
|
|
|
: TOperable_field(m), _append(TRUE)
|
|
|
|
|
{ }
|
1995-09-25 11:39:10 +00:00
|
|
|
|
|
|
|
|
|
// Certified 100%
|
|
|
|
|
word TSheet_field::class_id() const
|
|
|
|
|
{
|
|
|
|
|
return CLASS_SHEET_FIELD;
|
|
|
|
|
}
|
|
|
|
|
|
1996-05-08 11:09:13 +00:00
|
|
|
|
bool TSheet_field::is_kind_of(word cid) const
|
|
|
|
|
{ return cid == CLASS_SHEET_FIELD || TOperable_field::is_kind_of(cid); }
|
|
|
|
|
|
1995-09-25 11:39:10 +00:00
|
|
|
|
// Certified 100%
|
|
|
|
|
TSheet_field::~TSheet_field()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Certified 100%
|
|
|
|
|
void TSheet_field::reset()
|
|
|
|
|
{
|
1996-05-08 11:09:13 +00:00
|
|
|
|
TSpreadsheet* s = (TSpreadsheet*)_ctl;
|
|
|
|
|
s->destroy();
|
|
|
|
|
s->sheet_mask().reset();
|
1996-01-05 15:19:23 +00:00
|
|
|
|
set_dirty(); // Reset any error (dirty = 3)
|
|
|
|
|
set_dirty(mask().is_running()); // Set dirty state based on mask status
|
1995-11-21 08:27:37 +00:00
|
|
|
|
force_update();
|
1995-09-25 11:39:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Certified 100%
|
1996-01-11 11:42:57 +00:00
|
|
|
|
void TSheet_field::destroy(int r, bool update_sheet)
|
1995-09-25 11:39:10 +00:00
|
|
|
|
{
|
1996-05-08 11:09:13 +00:00
|
|
|
|
((TSpreadsheet*)_ctl)->destroy(r, update_sheet);
|
1995-09-25 11:39:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TSheet_field::parse_head(TScanner& scanner)
|
|
|
|
|
{
|
1996-05-08 11:09:13 +00:00
|
|
|
|
_ctl_data._width = scanner.integer();
|
|
|
|
|
_ctl_data._height = scanner.integer();
|
|
|
|
|
if (_ctl_data._height == 0)
|
|
|
|
|
_ctl_data._height = -1;
|
1995-09-25 11:39:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Certified 100%
|
|
|
|
|
bool TSheet_field::parse_item(TScanner& scanner)
|
|
|
|
|
{
|
|
|
|
|
if (scanner.key() == "IT")
|
|
|
|
|
{
|
1996-05-08 11:09:13 +00:00
|
|
|
|
_ctl_data._park.add(scanner.string());
|
1995-09-25 11:39:10 +00:00
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
return TMask_field::parse_item(scanner);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Certified 100%
|
|
|
|
|
void TSheet_field::create(WINDOW parent)
|
1996-05-08 11:09:13 +00:00
|
|
|
|
{
|
1995-09-25 11:39:10 +00:00
|
|
|
|
const TMask& m = mask();
|
1996-05-08 11:09:13 +00:00
|
|
|
|
const TString head(_ctl_data._park);
|
|
|
|
|
_ctl = new TSpreadsheet(parent, dlg(), _ctl_data._x, _ctl_data._y, _ctl_data._width, _ctl_data._height,
|
|
|
|
|
m.source_file(), m.sheets(), head, this);
|
1995-09-25 11:39:10 +00:00
|
|
|
|
|
1996-05-08 11:09:13 +00:00
|
|
|
|
_ctl->show(shown());
|
1995-10-11 11:42:19 +00:00
|
|
|
|
if (!_flags.enable_default)
|
|
|
|
|
{
|
|
|
|
|
_flags.enabled = TRUE; // Lo sheet e' sempre operabile anche se non editabile
|
|
|
|
|
disable();
|
|
|
|
|
}
|
1995-09-25 11:39:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Certified 100%
|
|
|
|
|
TString_array& TSheet_field::rows_array() const
|
|
|
|
|
{
|
1996-05-08 11:09:13 +00:00
|
|
|
|
return ((TSpreadsheet*)_ctl)->rows_array();
|
1995-09-25 11:39:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Certified 100%
|
|
|
|
|
// Ritorna l'indice della prima riga vuota dello sheet
|
|
|
|
|
int TSheet_field::first_empty() const
|
1996-05-08 11:09:13 +00:00
|
|
|
|
{
|
|
|
|
|
TSpreadsheet* s = (TSpreadsheet*)_ctl;
|
|
|
|
|
const int max = (int)s->items();
|
1995-09-25 11:39:10 +00:00
|
|
|
|
for (int n = 0; n < max; n++)
|
1996-05-08 11:09:13 +00:00
|
|
|
|
if (s->row(n).empty_items())
|
1995-09-25 11:39:10 +00:00
|
|
|
|
break;
|
|
|
|
|
return n;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
1996-02-05 19:00:53 +00:00
|
|
|
|
// @doc EXTERNAL
|
|
|
|
|
|
1995-09-25 11:39:10 +00:00
|
|
|
|
// @mfunc Ritorna nuova riga dello spreadshhet
|
|
|
|
|
//
|
|
|
|
|
// @rdesc Ritorna la stringa letta
|
|
|
|
|
TToken_string& TSheet_field::row(
|
|
|
|
|
int n) // @parm Numero della riga da leggere/creare
|
|
|
|
|
|
|
|
|
|
// @comm Se il parametro <p n> e maggiore del numero massimo di righe presenti
|
|
|
|
|
// o minore di 0 viene aggiunta una riga vuota in fondo allo spreadsheet
|
|
|
|
|
// (viene chiamata la <mf TSpreadsheet::add>)
|
1996-05-08 11:09:13 +00:00
|
|
|
|
{
|
|
|
|
|
TSpreadsheet* s = (TSpreadsheet*)_ctl;
|
|
|
|
|
const int max = (int)s->items();
|
1995-09-25 11:39:10 +00:00
|
|
|
|
if (n < 0 || n >= max)
|
|
|
|
|
{
|
|
|
|
|
if (n < 0) n = first_empty();
|
|
|
|
|
if (n >= max)
|
1996-05-08 11:09:13 +00:00
|
|
|
|
n = (int)s->add(new TToken_string(80));
|
1995-09-25 11:39:10 +00:00
|
|
|
|
}
|
1996-05-08 11:09:13 +00:00
|
|
|
|
return s->row(n);
|
1995-09-25 11:39:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-05 19:00:53 +00:00
|
|
|
|
// @doc EXTERNAL
|
1995-09-25 11:39:10 +00:00
|
|
|
|
|
|
|
|
|
// @mfunc Forza l'aggiornamento dei dati della riga sullo schermo
|
|
|
|
|
void TSheet_field::force_update(
|
|
|
|
|
int r) // @parm Numero della riga da aggiornare
|
|
|
|
|
|
|
|
|
|
// @comm Se il parametro <p r> assume valore -1 vengono aggiornate tutte le righe presenti
|
|
|
|
|
// nello spreadsheet
|
|
|
|
|
|
|
|
|
|
{
|
1996-05-08 11:09:13 +00:00
|
|
|
|
TSpreadsheet* s = (TSpreadsheet*)_ctl;
|
|
|
|
|
s->update(r);
|
1995-09-25 11:39:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int TSheet_field::items() const
|
1996-05-08 11:09:13 +00:00
|
|
|
|
{
|
|
|
|
|
TSpreadsheet* s = (TSpreadsheet*)_ctl;
|
|
|
|
|
return (int)s->items();
|
1995-09-25 11:39:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int TSheet_field::selected() const
|
|
|
|
|
{
|
1996-05-08 11:09:13 +00:00
|
|
|
|
TSpreadsheet* s = (TSpreadsheet*)_ctl;
|
|
|
|
|
return (int)s->selected();
|
1995-09-25 11:39:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TSheet_field::set_notify(SPREADSHEET_NOTIFY n)
|
|
|
|
|
{
|
1996-05-08 11:09:13 +00:00
|
|
|
|
TSpreadsheet* s = (TSpreadsheet*)_ctl;
|
|
|
|
|
s->set_notify(n);
|
1995-09-25 11:39:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Certified 50%
|
|
|
|
|
void TSheet_field::highlight() const
|
|
|
|
|
{
|
1996-05-08 11:09:13 +00:00
|
|
|
|
// TEditable_field::highlight();
|
|
|
|
|
TSpreadsheet* s = (TSpreadsheet*)_ctl;
|
|
|
|
|
if (s->_check_enabled)
|
|
|
|
|
{
|
|
|
|
|
int rows; xi_get_list_info(s->_obj, &rows);
|
1995-10-31 11:37:59 +00:00
|
|
|
|
if (rows > 0)
|
1995-10-31 14:01:20 +00:00
|
|
|
|
{
|
1996-05-08 11:09:13 +00:00
|
|
|
|
if (s->notify(s->_cur_rec, K_TAB))
|
1995-12-07 11:14:10 +00:00
|
|
|
|
{
|
1996-05-08 11:09:13 +00:00
|
|
|
|
s->set_focus_cell(s->_cur_row, s->_cur_col);
|
|
|
|
|
s->str2mask(selected());
|
1995-12-07 11:14:10 +00:00
|
|
|
|
}
|
1995-10-31 11:37:59 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
1995-09-25 11:39:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TSheet_field::enable(bool on)
|
|
|
|
|
{
|
1996-05-08 11:09:13 +00:00
|
|
|
|
TSpreadsheet* s = (TSpreadsheet*)_ctl;
|
|
|
|
|
s->activate(on);
|
1995-09-25 11:39:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
1995-10-30 10:19:44 +00:00
|
|
|
|
bool TSheet_field::enabled() const
|
|
|
|
|
{
|
|
|
|
|
return items() > 0;
|
|
|
|
|
}
|
|
|
|
|
|
1995-09-25 11:39:10 +00:00
|
|
|
|
void TSheet_field::enable_column(int column, bool on)
|
|
|
|
|
{
|
1996-05-08 11:09:13 +00:00
|
|
|
|
TSpreadsheet* s = (TSpreadsheet*)_ctl;
|
|
|
|
|
s->enable_column(column, on);
|
1995-09-25 11:39:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void TSheet_field::enable_cell(int row, int column, bool on)
|
|
|
|
|
{
|
1996-05-08 11:09:13 +00:00
|
|
|
|
TSpreadsheet* s = (TSpreadsheet*)_ctl;
|
|
|
|
|
s->enable_cell(row, column, on);
|
1995-09-25 11:39:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool TSheet_field::cell_disabled(int row, int column) const
|
|
|
|
|
{
|
1996-05-08 11:09:13 +00:00
|
|
|
|
TSpreadsheet* s = (TSpreadsheet*)_ctl;
|
|
|
|
|
return s->cell_disabled(row, column);
|
1995-09-25 11:39:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Matteo
|
|
|
|
|
void TSheet_field::delete_column( const int col ) const
|
|
|
|
|
{
|
1996-05-08 11:09:13 +00:00
|
|
|
|
TSpreadsheet* s = (TSpreadsheet*)_ctl;
|
|
|
|
|
s->delete_column( col );
|
1995-09-25 11:39:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TSheet_field::move_column( const int fromindex, const int toindex ) const
|
|
|
|
|
{
|
1996-05-08 11:09:13 +00:00
|
|
|
|
TSpreadsheet* s = (TSpreadsheet*)_ctl;
|
|
|
|
|
s->move_column(fromindex, toindex);
|
1995-09-25 11:39:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TSheet_field::swap_columns(const int fromid, const int toid) const
|
|
|
|
|
{
|
1996-05-08 11:09:13 +00:00
|
|
|
|
TSpreadsheet* s = (TSpreadsheet*)_ctl;
|
|
|
|
|
s->swap_columns(fromid, toid);
|
1995-09-25 11:39:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TSheet_field::swap_rows( const int fromindex, const int toindex)
|
|
|
|
|
{
|
1996-05-08 11:09:13 +00:00
|
|
|
|
TSpreadsheet* s = (TSpreadsheet*)_ctl;
|
|
|
|
|
s->swap_rows(fromindex, toindex);
|
1995-09-25 11:39:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TSheet_field::set_column_width( const int col, const int width ) const
|
|
|
|
|
{
|
1996-05-08 11:09:13 +00:00
|
|
|
|
TSpreadsheet* s = (TSpreadsheet*)_ctl;
|
|
|
|
|
s->set_column_width(col, width);
|
1995-09-25 11:39:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TSheet_field::set_column_header( const int col, const TString& header ) const
|
|
|
|
|
{
|
1996-05-08 11:09:13 +00:00
|
|
|
|
TSpreadsheet* s = (TSpreadsheet*)_ctl;
|
|
|
|
|
s->set_column_header(col, header);
|
1995-09-25 11:39:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
1995-11-09 08:07:36 +00:00
|
|
|
|
void TSheet_field::set_column_justify(int col, bool right)
|
|
|
|
|
{
|
|
|
|
|
if (col < FIRST_FIELD)
|
|
|
|
|
col += FIRST_FIELD;
|
|
|
|
|
sheet_mask().field(col).set_justify(right);
|
1996-05-08 11:09:13 +00:00
|
|
|
|
|
|
|
|
|
TSpreadsheet* s = (TSpreadsheet*)_ctl;
|
|
|
|
|
s->set_column_justify(col, right);
|
1995-11-09 08:07:36 +00:00
|
|
|
|
}
|
|
|
|
|
|
1995-09-25 11:39:10 +00:00
|
|
|
|
TMask& TSheet_field::sheet_mask() const
|
|
|
|
|
{
|
1996-05-08 11:09:13 +00:00
|
|
|
|
TSpreadsheet* s = (TSpreadsheet*)_ctl;
|
|
|
|
|
return s->sheet_mask();
|
1995-09-25 11:39:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool TSheet_field::on_hit()
|
|
|
|
|
{
|
|
|
|
|
if (!mask().is_running())
|
|
|
|
|
{
|
1996-01-22 10:02:16 +00:00
|
|
|
|
force_update();
|
1995-09-25 11:39:10 +00:00
|
|
|
|
set_dirty(FALSE);
|
|
|
|
|
}
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
1996-01-11 15:51:56 +00:00
|
|
|
|
void TSheet_field::select(int r, bool scrollto)
|
1995-09-25 11:39:10 +00:00
|
|
|
|
{
|
1996-05-08 11:09:13 +00:00
|
|
|
|
TSpreadsheet* s = (TSpreadsheet*)_ctl;
|
|
|
|
|
s->select(r, scrollto);
|
1995-09-25 11:39:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool TSheet_field::on_key(KEY k)
|
|
|
|
|
{
|
1995-10-31 14:01:20 +00:00
|
|
|
|
if (k == K_TAB && !focusdirty() && items() > 0)
|
|
|
|
|
{
|
|
|
|
|
select(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (k == K_ROWEDIT && items() > 0)
|
1995-09-25 11:39:10 +00:00
|
|
|
|
{
|
1995-10-31 14:01:20 +00:00
|
|
|
|
select(items()-1);
|
|
|
|
|
XI_EVENT xie;
|
|
|
|
|
xie.type = XIE_DBL_CELL;
|
|
|
|
|
xie.v.xi_obj = NULL;
|
1996-05-08 11:09:13 +00:00
|
|
|
|
_ctl->event_handler(NULL, &xie);
|
1995-10-31 14:01:20 +00:00
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
1995-12-07 11:14:10 +00:00
|
|
|
|
|
1996-05-08 11:09:13 +00:00
|
|
|
|
return TOperable_field::on_key(k);
|
1995-09-25 11:39:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TSheet_field::on_idle()
|
|
|
|
|
{
|
1996-05-08 11:09:13 +00:00
|
|
|
|
((TSpreadsheet*)_ctl)->on_idle();
|
1995-09-25 11:39:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TSheet_field::exchange(bool show_value, const real& nuo)
|
|
|
|
|
{
|
|
|
|
|
TMask& m = sheet_mask();
|
|
|
|
|
|
|
|
|
|
const real& vec = mask().exchange();
|
|
|
|
|
|
|
|
|
|
if (vec != nuo)
|
|
|
|
|
{
|
|
|
|
|
TBit_array valuta(32);
|
|
|
|
|
int i = 0;
|
|
|
|
|
for (int f = FIRST_FIELD; ;f++, i++)
|
|
|
|
|
{
|
|
|
|
|
const int pos = m.id2pos(f);
|
|
|
|
|
if (pos < 0) break;
|
|
|
|
|
if (m.fld(pos).class_id() == CLASS_REAL_FIELD)
|
|
|
|
|
{
|
|
|
|
|
if (m.fld(pos).exchangeable())
|
|
|
|
|
valuta.set(i);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (int riga = 0; riga < items(); riga++)
|
|
|
|
|
{
|
|
|
|
|
TToken_string& r = row(riga);
|
|
|
|
|
for (const char* s = r.get(i = 0); s; s = r.get(++i))
|
|
|
|
|
if (*s > ' ' && valuta[i])
|
|
|
|
|
{
|
|
|
|
|
real v(s);
|
|
|
|
|
v *= nuo;
|
|
|
|
|
v /= vec;
|
|
|
|
|
v.round();
|
|
|
|
|
r.add(v.string(), i);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m.set_exchange(show_value, nuo);
|
|
|
|
|
|
|
|
|
|
if (mask().is_running())
|
|
|
|
|
force_update();
|
1996-05-08 11:09:13 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Ricopia i campi della maschera nel record dato
|
|
|
|
|
void TSheet_field::mask2row(int n, TToken_string & rec)
|
|
|
|
|
{
|
|
|
|
|
const TMask& m = TSheet_field::sheet_mask();
|
|
|
|
|
|
|
|
|
|
rec.cut(0);
|
|
|
|
|
TSpreadsheet* s = (TSpreadsheet*)_ctl;
|
|
|
|
|
|
|
|
|
|
for (short id = FIRST_FIELD; ; id++)
|
|
|
|
|
{
|
|
|
|
|
int pos = m.id2pos(id);
|
|
|
|
|
if (pos < 0) break;
|
|
|
|
|
|
|
|
|
|
for(int dlg = id; pos >= 0; pos = m.id2pos(dlg += 100))
|
|
|
|
|
{
|
|
|
|
|
const TMask_field& f = m.fld(pos);
|
|
|
|
|
if (f.shown() || f.ghost())
|
|
|
|
|
{
|
|
|
|
|
rec.add(f.get());
|
|
|
|
|
if (active())
|
|
|
|
|
{
|
|
|
|
|
const int col = id-FIRST_FIELD;
|
|
|
|
|
|
|
|
|
|
if (!s->column_disabled(col))
|
|
|
|
|
{
|
|
|
|
|
const bool on = f.enabled();
|
|
|
|
|
enable_cell(n, col, on);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (pos < 0)
|
|
|
|
|
{
|
|
|
|
|
#ifdef DBG
|
|
|
|
|
if (s->cid2col(id) > 0)
|
|
|
|
|
yesnofatal_box("Mask2str: Non e' visibile il campo %d", dlg);
|
|
|
|
|
#endif
|
|
|
|
|
rec.add(" ");
|
|
|
|
|
}
|
|
|
|
|
}
|
1995-09-25 11:39:10 +00:00
|
|
|
|
}
|
1996-05-08 11:09:13 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Ricopia i campi del record dato nella maschera
|
|
|
|
|
void TSheet_field::row2mask(int n, TToken_string & r)
|
|
|
|
|
{
|
|
|
|
|
TString val(80);
|
|
|
|
|
|
|
|
|
|
TMask& m = TSheet_field::sheet_mask();
|
|
|
|
|
const int campi = m.fields();
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < campi; i++)
|
|
|
|
|
{
|
|
|
|
|
TMask_field& f = m.fld(i);
|
|
|
|
|
const short id = f.dlg();
|
|
|
|
|
if (id >= FIRST_FIELD)
|
|
|
|
|
{
|
|
|
|
|
const int index = (id % 100)-1;
|
|
|
|
|
val = r.get(index);
|
|
|
|
|
f.set(val);
|
|
|
|
|
const bool on = active() && !cell_disabled(n, index);
|
|
|
|
|
if (f.enabled() != on)
|
|
|
|
|
f.enable(on);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < campi; i++)
|
|
|
|
|
{
|
|
|
|
|
TMask_field& f = m.fld(i);
|
|
|
|
|
const short id = f.dlg();
|
|
|
|
|
if (id >= FIRST_FIELD &&
|
|
|
|
|
!f.is_kind_of(CLASS_BUTTON_FIELD) &&
|
|
|
|
|
(f.active() || f.ghost()))
|
|
|
|
|
{
|
|
|
|
|
if (f.has_check())
|
|
|
|
|
f.check(STARTING_CHECK);
|
|
|
|
|
f.set_dirty(FALSE);
|
|
|
|
|
f.on_hit();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < campi; i++)
|
|
|
|
|
{
|
|
|
|
|
TMask_field& f = m.fld(i);
|
|
|
|
|
const short id = f.dlg();
|
|
|
|
|
if (id > FIRST_FIELD)
|
|
|
|
|
{
|
|
|
|
|
if (f.dirty() == TRUE)
|
|
|
|
|
f.set_dirty(FALSE);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
val.format("Riga %d", n+1);
|
|
|
|
|
m.set_caption(val);
|
|
|
|
|
}
|
|
|
|
|
|