1995-08-23 14:33:51 +00:00
|
|
|
|
#ifndef __MSKSHEET_H
|
|
|
|
|
#define __MSKSHEET_H
|
|
|
|
|
|
1997-06-25 07:04:37 +00:00
|
|
|
|
#ifndef __ISAM_H
|
|
|
|
|
class TLocalisamfile;
|
|
|
|
|
class TRectype;
|
1995-08-23 14:33:51 +00:00
|
|
|
|
#endif
|
|
|
|
|
|
1997-06-25 07:04:37 +00:00
|
|
|
|
#ifndef __MASK_H
|
|
|
|
|
#include <mask.h>
|
1997-05-23 14:06:32 +00:00
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifndef __RECARRAY_H
|
1997-06-25 07:04:37 +00:00
|
|
|
|
class TRecord_array;
|
1997-05-23 14:06:32 +00:00
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifndef __RELATION_H
|
1997-06-25 07:04:37 +00:00
|
|
|
|
class TRelation;
|
1997-05-23 14:06:32 +00:00
|
|
|
|
#endif
|
|
|
|
|
|
1996-05-08 11:09:13 +00:00
|
|
|
|
#define FIRST_FIELD 101
|
1995-08-31 17:30:48 +00:00
|
|
|
|
#define K_ROWEDIT ( K_CTRL + 'I' )
|
|
|
|
|
|
1996-02-05 19:00:53 +00:00
|
|
|
|
|
1995-12-07 11:14:10 +00:00
|
|
|
|
class TSheet_field;
|
1995-09-05 10:45:24 +00:00
|
|
|
|
|
1996-02-05 19:00:53 +00:00
|
|
|
|
// @doc EXTERNAL
|
|
|
|
|
|
1999-04-06 15:34:39 +00:00
|
|
|
|
//typedef (*ROWS_COMPARE_FUNCTION)(const TToken_string&, const TToken_string&);
|
|
|
|
|
typedef (*ROWS_COMPARE_FUNCTION)(TSheet_field & s, int r1, int r2);
|
|
|
|
|
|
1996-02-05 19:00:53 +00:00
|
|
|
|
// @type SPREADSHEET_NOTIFY | Prototipo funzione che gestisce l'ingresso, l'uscita e la modifica da una riga dello sheet
|
1995-08-23 14:33:51 +00:00
|
|
|
|
typedef bool (*SPREADSHEET_NOTIFY)(TSheet_field& s, int r, KEY k);
|
1996-02-05 19:00:53 +00:00
|
|
|
|
|
1997-05-23 14:06:32 +00:00
|
|
|
|
// @type SHEET_USERGETPUT| Prototipo funzione utente che gestisce il caricamento/salvataggio dei dati dello sheet
|
|
|
|
|
typedef void (*SHEET_USERGETPUT)(TSheet_field &fld_righe, int item);
|
|
|
|
|
|
1996-02-05 19:00:53 +00:00
|
|
|
|
// @doc EXTERNAL
|
|
|
|
|
|
1995-09-05 10:45:24 +00:00
|
|
|
|
// @class TSheet_field | Classe per la gestione dei campi di uno spreadsheet
|
|
|
|
|
//
|
|
|
|
|
// @base public | TMask_field
|
1997-05-23 14:06:32 +00:00
|
|
|
|
class TSheet_field : public TLoadable_field
|
1995-08-23 14:33:51 +00:00
|
|
|
|
{
|
1995-09-05 10:45:24 +00:00
|
|
|
|
// @author:(INTERNAL) Guido
|
|
|
|
|
|
1996-02-05 19:00:53 +00:00
|
|
|
|
// @cfriend TSpreadsheet
|
1995-12-07 11:14:10 +00:00
|
|
|
|
friend class TSpreadsheet;
|
|
|
|
|
|
1996-02-05 19:00:53 +00:00
|
|
|
|
// @access:(INTERNAL) Private Member
|
1995-09-05 10:45:24 +00:00
|
|
|
|
|
1996-02-05 19:00:53 +00:00
|
|
|
|
// @cmember:(INTERNAL) Indica se aggiungere a fondo dello spreadsheet o nella riga in cui ti trovi
|
1997-05-23 14:06:32 +00:00
|
|
|
|
bool _append;
|
|
|
|
|
|
1998-12-10 16:25:48 +00:00
|
|
|
|
// @cmember:(INTERNAL) Separatore delle TToken_string
|
|
|
|
|
char _separator;
|
|
|
|
|
|
1997-05-23 14:06:32 +00:00
|
|
|
|
// @cmember:(INTERNAL) Flag di autoload
|
|
|
|
|
bool _enable_autoload;
|
|
|
|
|
// @cmember:(INTERNAL) Campi di input sulla maschera (key field names)
|
|
|
|
|
TToken_string _file_k_names;
|
|
|
|
|
// @cmember:(INTERNAL) Campi di input sulla maschera (key field ids)
|
|
|
|
|
TToken_string _file_k_ids;
|
|
|
|
|
// @cmember:(INTERNAL) file delle righe
|
1997-06-25 07:04:37 +00:00
|
|
|
|
TLocalisamfile * _sheetfile;
|
1997-05-23 14:06:32 +00:00
|
|
|
|
// @cmember:(INTERNAL) record array delle righe
|
1997-06-25 07:04:37 +00:00
|
|
|
|
TRecord_array* _linee_rec;
|
1997-05-23 14:06:32 +00:00
|
|
|
|
// @cmember:(INTERNAL) indicatore di record array gestito esternamente
|
1997-06-25 07:04:37 +00:00
|
|
|
|
bool _external_record;
|
1997-05-23 14:06:32 +00:00
|
|
|
|
// @cmember:(INTERNAL) funzioni utente per get tra record (array) e array righe
|
1997-06-25 07:04:37 +00:00
|
|
|
|
SHEET_USERGETPUT _userput;
|
1997-05-23 14:06:32 +00:00
|
|
|
|
// @cmember:(INTERNAL) funzioni utente per put tra righe e record (array)
|
1997-06-25 07:04:37 +00:00
|
|
|
|
SHEET_USERGETPUT _userget;
|
1995-08-23 14:33:51 +00:00
|
|
|
|
|
1995-09-05 10:45:24 +00:00
|
|
|
|
// @access Protected Member
|
1995-08-23 14:33:51 +00:00
|
|
|
|
protected:
|
1996-09-26 15:34:37 +00:00
|
|
|
|
// @cmember:(INTERNAL) Identificatore dell' ultima colonna dello sheet
|
|
|
|
|
short _last_column_id;
|
|
|
|
|
|
1995-09-05 10:45:24 +00:00
|
|
|
|
// @cmember Ritorna l'identificatore della classe
|
1995-08-23 14:33:51 +00:00
|
|
|
|
virtual word class_id() const;
|
1996-05-08 11:09:13 +00:00
|
|
|
|
|
|
|
|
|
virtual bool is_kind_of(word cid) const;
|
|
|
|
|
|
1995-09-05 10:45:24 +00:00
|
|
|
|
// @cmember Gestisce la chiamata all'handler del campo
|
1995-08-23 14:33:51 +00:00
|
|
|
|
virtual bool on_hit();
|
|
|
|
|
|
1995-09-05 10:45:24 +00:00
|
|
|
|
// @cmember Legge la testata dello spreadsheet da <p scanner>
|
1995-08-23 14:33:51 +00:00
|
|
|
|
virtual void parse_head(TScanner& scanner);
|
1995-09-05 10:45:24 +00:00
|
|
|
|
// @cmember Legge gli item dello spreadsheet da <p scanner>
|
1995-08-23 14:33:51 +00:00
|
|
|
|
virtual bool parse_item(TScanner& scanner);
|
1997-05-23 14:06:32 +00:00
|
|
|
|
// @cmember Legge gli input (campi chiave) dello spreadsheet da <p scanner>
|
1997-06-25 07:04:37 +00:00
|
|
|
|
void parse_input(TScanner& scanner);
|
|
|
|
|
// @cmember Crea lo spreadsheet
|
1995-08-23 14:33:51 +00:00
|
|
|
|
virtual void create(WINDOW parent);
|
|
|
|
|
|
1995-09-05 10:45:24 +00:00
|
|
|
|
// @cmember Setta il focus sul campo
|
1995-08-23 14:33:51 +00:00
|
|
|
|
virtual void highlight() const;
|
1996-05-08 11:09:13 +00:00
|
|
|
|
// @cmember Ricopia i campi della maschera nel record <p n>-esimo
|
|
|
|
|
virtual void mask2row(int n, TToken_string & rec);
|
|
|
|
|
// @cmember Ricopia i campi del record <p n>-esimo nella maschera
|
1998-08-10 10:20:31 +00:00
|
|
|
|
virtual void row2mask(int n, TToken_string & rec, int mode = 0x3);
|
1995-08-23 14:33:51 +00:00
|
|
|
|
|
1999-03-22 15:55:50 +00:00
|
|
|
|
// @access Public Member
|
|
|
|
|
public:
|
1997-08-05 12:54:08 +00:00
|
|
|
|
// @cmember Permette di mettere il focus su una cella
|
|
|
|
|
void set_focus_cell(int riga, int colonna);
|
|
|
|
|
|
1996-11-12 14:53:09 +00:00
|
|
|
|
// @cmember Gestisce la pressione del tasto (TRUE se la gestione ha avuto successo)
|
|
|
|
|
virtual bool on_key(KEY k);
|
|
|
|
|
|
1997-12-24 14:26:25 +00:00
|
|
|
|
// @cmember Si, sono uno spreadsheet
|
1997-05-23 14:06:32 +00:00
|
|
|
|
virtual bool is_sheet() const { return TRUE; }
|
|
|
|
|
|
1997-06-25 07:04:37 +00:00
|
|
|
|
// @cmember Legge automaticamente la linea dal record array assegnato
|
1997-05-23 14:06:32 +00:00
|
|
|
|
virtual bool autoload_line(int i,TRectype & rec);
|
1997-06-25 07:04:37 +00:00
|
|
|
|
// @cmember Salva automaticamente la linea nel record array assegnato
|
1997-05-23 14:06:32 +00:00
|
|
|
|
virtual bool autosave_line(int i,TRectype & rec);
|
|
|
|
|
|
1997-06-25 07:04:37 +00:00
|
|
|
|
// @cmember Legge automaticamente lo sheet dal record array assegnato
|
1997-05-23 14:06:32 +00:00
|
|
|
|
virtual bool autoload(const TRelation& r);
|
1997-06-25 07:04:37 +00:00
|
|
|
|
// @cmember Salva automaticamente lo sheet nel record array assegnato
|
|
|
|
|
virtual bool autosave(TRelation& r) ;
|
|
|
|
|
// @cmember setta la funzione utente che Legge i campi dello sheet
|
|
|
|
|
void set_userget(SHEET_USERGETPUT handler);
|
|
|
|
|
// @cmember setta la funzione utente che scrive i campi dello sheet
|
|
|
|
|
void set_userput(SHEET_USERGETPUT handler);
|
|
|
|
|
// @cmember carica le chiavi del record array dello sheet
|
|
|
|
|
TRectype * putkey(const TRelation& r);
|
|
|
|
|
// @cmember restituisce il record array assegnato allo sheet
|
|
|
|
|
TRecord_array * record() const {return _linee_rec;}
|
1997-05-23 14:06:32 +00:00
|
|
|
|
// @cmember Imposta un record array esterno che contiene le righe dello sheet
|
|
|
|
|
void set_lines_record(TRecord_array &);
|
1997-06-25 07:04:37 +00:00
|
|
|
|
// @cmember Ritorna se il record assegnato <20> gestito esternamente (read/write/remove)
|
|
|
|
|
bool external_record() const {return _external_record;}
|
1999-10-22 10:00:18 +00:00
|
|
|
|
// @cmember Gestisce i campi della chiave
|
|
|
|
|
void restart_key();
|
|
|
|
|
TMask_field *get_key(TString & dbfieldname);
|
1997-05-23 14:06:32 +00:00
|
|
|
|
|
1997-06-25 07:04:37 +00:00
|
|
|
|
// @cmember Ritorna una riga dello spreadsheet
|
1995-09-05 10:45:24 +00:00
|
|
|
|
TToken_string& row(int n);
|
|
|
|
|
// @cmember Ritorna un array con tutte le righe dello spreadsheet
|
|
|
|
|
TString_array& rows_array() const;
|
1997-05-23 14:06:32 +00:00
|
|
|
|
// @cmember Ritorna l'elemento <p c>-esimo della riga <p r>
|
1995-09-05 10:45:24 +00:00
|
|
|
|
const char* cell(int r, int c)
|
1997-06-16 09:33:08 +00:00
|
|
|
|
{ const char*v=row(r).get(c); return v ? v: " "; }
|
1995-09-05 10:45:24 +00:00
|
|
|
|
|
1998-12-10 16:25:48 +00:00
|
|
|
|
char separator() const { return _separator; }
|
|
|
|
|
|
1995-09-05 10:45:24 +00:00
|
|
|
|
// @cmember Ritorna la prima riga vuota nello spreadsheet
|
|
|
|
|
int first_empty() const;
|
|
|
|
|
// @cmember Ritorna il numero di righe presenti nello spreadsheet
|
|
|
|
|
int items() const;
|
|
|
|
|
// @cmember Ritorna il numero della riga corrente
|
|
|
|
|
int selected() const;
|
|
|
|
|
// @cmember Seleziona la riga <p r> come quella corrente
|
1996-01-11 15:51:56 +00:00
|
|
|
|
void select(int r, bool scrollto = FALSE);
|
1999-07-16 14:59:11 +00:00
|
|
|
|
// @cmember Seleziona la riga <p r> e la colonna <p c> come quella corrente
|
|
|
|
|
void select(int r, int c, bool scrollto = FALSE);
|
1995-09-05 10:45:24 +00:00
|
|
|
|
|
|
|
|
|
// @cmember Vuota tutto lo spreadsheet
|
1995-08-23 14:33:51 +00:00
|
|
|
|
virtual void reset();
|
1995-09-05 10:45:24 +00:00
|
|
|
|
// @cmember Abilita/disabilita tutto lo spreadsheet (vedi <mf TMask_field::enable>)
|
1995-08-23 14:33:51 +00:00
|
|
|
|
virtual void enable(bool on);
|
1995-10-30 10:19:44 +00:00
|
|
|
|
// @cmember Ritorna lo stato di abilitazione dello spreadsheet (vedi <mf TMask_field::enabled>)
|
|
|
|
|
virtual bool enabled() const;
|
1995-08-23 14:33:51 +00:00
|
|
|
|
|
1995-09-05 10:45:24 +00:00
|
|
|
|
// @cmember Aggiorna le righe dello spreadsheet con i valori salvati una volta che non ci sono
|
|
|
|
|
// piu' processi attivi
|
1995-08-23 14:33:51 +00:00
|
|
|
|
void on_idle();
|
|
|
|
|
|
1997-04-16 13:37:57 +00:00
|
|
|
|
// @cmember Elimina una o tutte le righe
|
1996-01-11 11:42:57 +00:00
|
|
|
|
void destroy(int r = -1, bool update_sheet = TRUE);
|
1997-01-10 16:02:13 +00:00
|
|
|
|
// @cmember Inserisce una riga
|
1997-04-16 13:37:57 +00:00
|
|
|
|
int insert(int r = -1, bool update_sheet = TRUE, bool call_notify = FALSE);
|
1995-09-05 10:45:24 +00:00
|
|
|
|
// @cmember Forza l'aggiornamento dei dati della riga sullo schermo
|
|
|
|
|
void force_update(int r = -1);
|
1995-08-23 14:33:51 +00:00
|
|
|
|
|
1995-09-05 10:45:24 +00:00
|
|
|
|
// @cmember Ritorna la maschera corrispondente ad una riga dello spreadsheet
|
1996-05-08 11:09:13 +00:00
|
|
|
|
virtual TMask& sheet_mask() const;
|
|
|
|
|
// @cmember esegue la maschera di edit dello speadsheet;
|
|
|
|
|
virtual KEY run_editmask(int ) { return sheet_mask().run();}
|
1995-09-05 10:45:24 +00:00
|
|
|
|
// @cmember Setta il membro <p _notify> della classe <c TSpreadsheet>
|
1995-08-23 14:33:51 +00:00
|
|
|
|
void set_notify(SPREADSHEET_NOTIFY n);
|
|
|
|
|
|
1996-09-26 15:34:37 +00:00
|
|
|
|
// @cmember Trasforma l'identificatore di un campo <p cid> in un numero di colonna logica
|
|
|
|
|
int cid2index(short cid) const;
|
1995-09-05 10:45:24 +00:00
|
|
|
|
// @cmember Abilita/disabilita una colonna dello spreadsheet (vedi <mf TSpreadsheet::enable_column>)
|
1995-08-23 14:33:51 +00:00
|
|
|
|
void enable_column(int col, bool on = TRUE);
|
|
|
|
|
|
1995-09-05 10:45:24 +00:00
|
|
|
|
// @cmember Abilita/disabilita una cella dello spreadsheet (vedi <mf TSpreadsheet::enable_cell>)
|
1995-08-23 14:33:51 +00:00
|
|
|
|
void enable_cell(int row, int column, bool on = TRUE);
|
1995-09-05 10:45:24 +00:00
|
|
|
|
// @cmember Disabilta una cella dello spreadsheet (chiama <mf TSheet_field::enable>)
|
|
|
|
|
void disable_cell(int row, int column)
|
|
|
|
|
{ enable_cell(row, column, FALSE); }
|
|
|
|
|
// @cmember Controlla se una cella e' disabilitata (vedi <mf TSpreadsheet::cell_disabled>)
|
1995-08-23 14:33:51 +00:00
|
|
|
|
bool cell_disabled(int row, int column) const;
|
1999-04-06 15:34:39 +00:00
|
|
|
|
// @cmember Controlla se una cella e' disabilitata (vedi <mf TSpreadsheet::cell_disabled>)
|
|
|
|
|
bool cell_enabled(int row, int column) const;
|
|
|
|
|
|
1996-09-26 15:34:37 +00:00
|
|
|
|
// @cmember Controlla se una colonna e' abilitata (vedi <mf TSpreadsheet::column_enabled>)
|
|
|
|
|
bool column_enabled(int column) const;
|
|
|
|
|
// @cmember Controlla se una colonna e' disabilitata (vedi <mf TSpreadsheet::column_disabled>)
|
|
|
|
|
bool column_disabled(int column) const;
|
1998-11-03 10:27:35 +00:00
|
|
|
|
// @cmember Permette di visualizzare una colonna dello spreadsheet
|
|
|
|
|
void show_column(int col, bool on) const;
|
1995-09-05 10:45:24 +00:00
|
|
|
|
// @cmember Permette di eliminare una colonna dallo spreadsheet
|
1995-08-23 14:33:51 +00:00
|
|
|
|
void delete_column( const int col ) const;
|
1999-03-22 15:55:50 +00:00
|
|
|
|
bool exist_column(const int col) const;
|
1995-09-05 10:45:24 +00:00
|
|
|
|
// @cmember Sposta la colonna dalla posizione <p fromindex> alla posizione
|
|
|
|
|
// <p toindex>
|
1995-08-23 14:33:51 +00:00
|
|
|
|
void move_column( const int fromindex, const int toindex ) const;
|
1995-09-05 10:45:24 +00:00
|
|
|
|
// @cmember Permette di invertire la posizione di due colonne
|
1995-08-23 14:33:51 +00:00
|
|
|
|
void swap_columns(const int fromid, const int toid) const;
|
1999-04-06 15:34:39 +00:00
|
|
|
|
|
|
|
|
|
// @cmember Abilita/disabilita una riga dello spreadsheet (vedi <mf TSpreadsheet::enable_cell>)
|
|
|
|
|
void enable_row(int row, bool on = TRUE);
|
|
|
|
|
// @cmember Disabilta una riga dello spreadsheet (chiama <mf TSheet_field::enable>)
|
|
|
|
|
void disable_row(int row)
|
|
|
|
|
{ enable_row(row, FALSE); }
|
|
|
|
|
// @cmember Controlla se una riga e' disabilitata (tutte le sue celle sono disabilitate)
|
|
|
|
|
bool row_enabled(int row);
|
1995-09-05 10:45:24 +00:00
|
|
|
|
// @cmember Permette di invertire la posizione di due righe
|
|
|
|
|
void swap_rows( const int fromindex, const int toindex ) ;
|
1995-08-23 14:33:51 +00:00
|
|
|
|
|
1999-04-06 15:34:39 +00:00
|
|
|
|
// @cmember Permette di ordinare le righe dello sheet
|
|
|
|
|
void sort(ROWS_COMPARE_FUNCTION = NULL);
|
|
|
|
|
|
1998-12-10 16:25:48 +00:00
|
|
|
|
// @cmember Controlla se l'utente ha salvato la disposizione delle colonne
|
|
|
|
|
bool user_saved_columns_order() const;
|
|
|
|
|
|
1995-09-05 10:45:24 +00:00
|
|
|
|
// @cmember Setta la larghezza della colonna
|
1995-08-23 14:33:51 +00:00
|
|
|
|
void set_column_width( const int col, const int width ) const;
|
1995-09-05 10:45:24 +00:00
|
|
|
|
// @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'allineamento della colonna
|
|
|
|
|
void set_column_justify(int col, bool right);
|
1996-11-12 14:53:09 +00:00
|
|
|
|
// @cmember Setta il colore dello sfondo e del testo di una o tutte le righe
|
|
|
|
|
void set_back_and_fore_color(COLOR back, COLOR fore, int row);
|
|
|
|
|
// @cmember Memorizza la disposizione delle colonne
|
1999-04-06 15:34:39 +00:00
|
|
|
|
void save_columns_order();
|
|
|
|
|
// @cmember Imposta la disposizione delle colonne
|
|
|
|
|
void set_columns_order(TToken_string* order);
|
1996-11-12 14:53:09 +00:00
|
|
|
|
// @cmember Dispone le colonne come all'atto del caricamento
|
|
|
|
|
void reset_columns_order();
|
1995-09-05 10:45:24 +00:00
|
|
|
|
// @cmember Setta il member <p _append> con il valore di <p on>
|
|
|
|
|
void set_append(bool on = TRUE)
|
|
|
|
|
{ _append = on;}
|
1997-05-23 14:06:32 +00:00
|
|
|
|
// @cmember Ritorna il valore del membro <p _append>
|
1995-09-05 10:45:24 +00:00
|
|
|
|
bool append() const
|
|
|
|
|
{ return _append;}
|
1996-09-26 15:34:37 +00:00
|
|
|
|
// @cmember Funzione eseguita dopo ogni insert
|
|
|
|
|
virtual void post_insert(int) { }
|
1995-09-05 10:45:24 +00:00
|
|
|
|
|
1997-08-29 16:35:22 +00:00
|
|
|
|
// @cmember Esegue tutti i check iniziali sulla riga <p n>
|
1998-08-10 10:20:31 +00:00
|
|
|
|
void check_row(int n, int mode = 0x3);
|
1997-01-10 16:02:13 +00:00
|
|
|
|
|
1997-08-29 16:35:22 +00:00
|
|
|
|
// @cmember Trasferisce i valori dalla maschera alla riga <p n>
|
|
|
|
|
void update_row(int n) { mask2row(n, row(n)); }
|
1999-10-22 10:00:18 +00:00
|
|
|
|
// @cmember Trasferisce i valori dalla riga alla maschera <p n>
|
|
|
|
|
void update_mask(int n) { row2mask(n, row(n)); }
|
1997-08-29 16:35:22 +00:00
|
|
|
|
|
1995-09-05 10:45:24 +00:00
|
|
|
|
// @cmember Costruttore
|
1995-08-23 14:33:51 +00:00
|
|
|
|
TSheet_field(TMask* m);
|
1995-09-05 10:45:24 +00:00
|
|
|
|
// @cmember Distruttore
|
1995-08-23 14:33:51 +00:00
|
|
|
|
virtual ~TSheet_field();
|
|
|
|
|
};
|
|
|
|
|
|
1997-11-17 10:28:04 +00:00
|
|
|
|
#define FOR_EACH_SHEET_ROW(__sheet, __r, __riga) \
|
|
|
|
|
FOR_EACH_ARRAY_ROW(__sheet.rows_array(), __r, __riga)
|
|
|
|
|
|
|
|
|
|
#define FOR_EACH_SHEET_ROW_BACK(__sheet, __r, __riga) \
|
|
|
|
|
FOR_EACH_ARRAY_ROW_BACK(__sheet.rows_array(), __r, __riga)
|
|
|
|
|
|
1995-08-23 14:33:51 +00:00
|
|
|
|
#endif
|