cglib.h Aggiunti vari const agli esercizi cglib02.cpp Aggiunti vari const agli esercizi cg3600a.* Aggiunta maschera mastrini a video git-svn-id: svn://10.65.10.50/trunk@3902 c028cbd2-c16b-5b4b-a496-9718f37d4682
871 lines
21 KiB
C++
Executable File
871 lines
21 KiB
C++
Executable File
#include <stdlib.h>
|
|
|
|
#include <applicat.h>
|
|
#include <colors.h>
|
|
#include <controls.h>
|
|
#include <mask.h>
|
|
#include <urldefid.h>
|
|
#include <utility.h>
|
|
|
|
#include "cg3.h"
|
|
#include "cglib.h"
|
|
|
|
#include "cg3600a.h"
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// TList
|
|
///////////////////////////////////////////////////////////
|
|
|
|
class TList : public TContainer
|
|
{
|
|
enum { MAX_SKIP = 8192 };
|
|
|
|
struct TList_object : public TObject
|
|
{
|
|
TObject* _obj;
|
|
TList_object* _next;
|
|
TList_object* _prev;
|
|
};
|
|
|
|
TList_object** _skip;
|
|
long _items, _current;
|
|
long _step, _last_skip;
|
|
|
|
protected:
|
|
// @cmember Ritorna un puntatore al primo oggetto del contenitore
|
|
virtual TObject* first_item( );
|
|
// @cmember Ritorna un puntatore all'ultimo oggetto del contenitore
|
|
virtual TObject* last_item( );
|
|
// @cmember Ritorna un puntatore all'oggetto successivo all'oggetto corrente
|
|
virtual TObject* succ_item( );
|
|
// @cmember Ritorna un puntatore all'oggetto che precede l'oggetto corrente
|
|
virtual TObject* pred_item( );
|
|
// @cmember Ritorna il numero di oggetti nel contenitore
|
|
virtual long objects( );
|
|
|
|
protected:
|
|
TList_object* detach_lstobj(long index);
|
|
TList_object* lstobjptr(long index);
|
|
void change_step(long step);
|
|
|
|
public:
|
|
|
|
TObject* TList::objptr(long index);
|
|
|
|
void destroy();
|
|
long insert(TObject* obj, long pos);
|
|
long add(TObject* obj, long pos = -1);
|
|
|
|
TObject* detach(long pos);
|
|
bool remove(long pos);
|
|
|
|
void choose_step(long expected_size); // Sceglie il passo per gli elemnti
|
|
|
|
TList(long expected_size);
|
|
virtual ~TList();
|
|
};
|
|
|
|
TList::TList(long expected_size)
|
|
: _items(0), _current(0)
|
|
{
|
|
_skip = new TList_object*[MAX_SKIP];
|
|
_skip[0] = NULL;
|
|
choose_step(expected_size);
|
|
}
|
|
|
|
TList::~TList()
|
|
{
|
|
destroy();
|
|
delete [] _skip;
|
|
}
|
|
|
|
long TList::objects( )
|
|
{
|
|
return _items;
|
|
}
|
|
|
|
TObject* TList::first_item()
|
|
{
|
|
return objptr(_current = 0);
|
|
}
|
|
|
|
TObject* TList::succ_item()
|
|
{
|
|
return objptr(++_current);
|
|
}
|
|
|
|
TObject* TList::pred_item()
|
|
{
|
|
return objptr(_current++);
|
|
}
|
|
|
|
TObject* TList::last_item()
|
|
{
|
|
return objptr(_current = _items-1);
|
|
}
|
|
|
|
void TList::destroy()
|
|
{
|
|
TList_object* head = _skip[0];
|
|
while (head)
|
|
{
|
|
TList_object* next = head->_next;
|
|
if (head->_obj)
|
|
delete head->_obj;
|
|
delete head;
|
|
head = next;
|
|
}
|
|
_items = _current = _last_skip = 0;
|
|
_skip[0] = NULL;
|
|
}
|
|
|
|
TList::TList_object* TList::lstobjptr(long index)
|
|
{
|
|
TList_object* lstobj = NULL;
|
|
const ldiv_t p = ldiv(index, _step);
|
|
if (p.quot >= 0 && p.quot < _last_skip)
|
|
{
|
|
TList_object* lo = _skip[p.quot];
|
|
for (long s = p.rem; lo && s > 0; s--)
|
|
lo = lo->_next;
|
|
|
|
lstobj = lo;
|
|
}
|
|
return lstobj;
|
|
}
|
|
|
|
TObject* TList::objptr(long index)
|
|
{
|
|
TList_object* lo = lstobjptr(index);
|
|
return lo ? lo->_obj : NULL;
|
|
}
|
|
|
|
void TList::change_step(long step)
|
|
{
|
|
CHECKD(step > 0 && step <= 16384, "Bad list step ", step);
|
|
_step = step;
|
|
_last_skip = 0;
|
|
|
|
step = 0;
|
|
for (TList_object* lo = _skip[0]; lo; lo = lo->_next, step--)
|
|
{
|
|
if (step == 0)
|
|
{
|
|
CHECK(_last_skip < MAX_SKIP, "Too many items");
|
|
_skip[_last_skip++] = lo;
|
|
step = _step;
|
|
}
|
|
}
|
|
}
|
|
|
|
void TList::choose_step(long expected_size)
|
|
{
|
|
long step = expected_size / MAX_SKIP + 1;
|
|
change_step(step);
|
|
}
|
|
|
|
long TList::insert(TObject* obj, long index)
|
|
{
|
|
if (index < 0)
|
|
index = 0;
|
|
else
|
|
{
|
|
if (index > _items)
|
|
index = _items;
|
|
}
|
|
const long pred = index-1;
|
|
|
|
TList_object* newobj = new TList_object;
|
|
newobj->_obj = obj;
|
|
|
|
if (pred < 0)
|
|
{
|
|
newobj->_prev = NULL;
|
|
newobj->_next = _skip[0];
|
|
if (_skip[0])
|
|
_skip[0]->_prev = newobj;
|
|
}
|
|
else
|
|
{
|
|
TList_object* lo = lstobjptr(pred);
|
|
CHECK(lo, "NULL insertion point");
|
|
newobj->_next = lo->_next;
|
|
newobj->_prev = lo;
|
|
if (lo->_next)
|
|
lo->_next->_prev = newobj;
|
|
lo->_next = newobj;
|
|
}
|
|
_items++;
|
|
|
|
ldiv_t p = ldiv(index, _step);
|
|
if (p.rem == 0 && p.quot < MAX_SKIP) // Cambia il capolista
|
|
_skip[p.quot] = newobj;
|
|
|
|
for (long i = p.quot + 1; i < _last_skip; i++)
|
|
_skip[i] = _skip[i]->_prev; // Aggiorna capilista successivi
|
|
|
|
// Siamo andati oltre l'ultimo skip
|
|
const long s = (_items - 1) / _step + 1;
|
|
if (s > _last_skip)
|
|
{
|
|
if (s > MAX_SKIP)
|
|
change_step(_step+1);
|
|
else
|
|
_last_skip++;
|
|
}
|
|
|
|
return index;
|
|
}
|
|
|
|
long TList::add(TObject* obj, long index)
|
|
{
|
|
if (index < 0 || index >= _items)
|
|
{
|
|
index = insert(obj, _items);
|
|
}
|
|
else
|
|
{
|
|
TList_object* lo = lstobjptr(index);
|
|
CHECK(lo, "NULL list object");
|
|
delete lo->_obj;
|
|
lo->_obj = obj;
|
|
}
|
|
return index;
|
|
}
|
|
|
|
TList::TList_object* TList::detach_lstobj(long index)
|
|
{
|
|
TList_object* lo = lstobjptr(index);
|
|
if (lo)
|
|
{
|
|
if (lo->_prev)
|
|
lo->_prev->_next = lo->_next;
|
|
if (lo->_next)
|
|
lo->_next->_prev = lo->_prev;
|
|
ldiv_t res = ldiv(index, _step);
|
|
if (res.rem == 0)
|
|
_skip[res.quot] = lo->_next;
|
|
long p;
|
|
for (p = res.quot + 1; p < _last_skip; p++)
|
|
_skip[p] = _skip[p]->_next;
|
|
|
|
_items--;
|
|
|
|
p = (_items - 1) / _step + 1;
|
|
if (p < _last_skip)
|
|
{
|
|
_last_skip--;
|
|
_skip[_last_skip] = NULL;
|
|
}
|
|
}
|
|
|
|
return lo;
|
|
}
|
|
|
|
TObject* TList::detach(long index)
|
|
{
|
|
TList_object* lo = detach_lstobj(index);
|
|
TObject* obj;
|
|
if (lo)
|
|
{
|
|
obj = lo->_obj;
|
|
delete lo;
|
|
}
|
|
else
|
|
obj = NULL;
|
|
return obj;
|
|
}
|
|
|
|
bool TList::remove(long index)
|
|
{
|
|
TObject* o = detach(index);
|
|
if (o)
|
|
delete o;
|
|
return o != NULL;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// TGrid_control
|
|
///////////////////////////////////////////////////////////
|
|
|
|
class TGrid_control;
|
|
|
|
class TGrid_field : public TOperable_field
|
|
{
|
|
long _to_select;
|
|
|
|
protected: // TMask_field
|
|
virtual void create(WINDOW parent);
|
|
virtual void parse_head(TScanner& scanner);
|
|
virtual bool parse_item(TScanner& scanner);
|
|
|
|
public:
|
|
virtual long items() const;
|
|
virtual bool handler(XI_EVENT* ep);
|
|
|
|
TGrid_control* grid() const { return (TGrid_control*)_ctl; }
|
|
|
|
TGrid_field(TMask* m) : TOperable_field(m) { }
|
|
virtual ~TGrid_field() { }
|
|
};
|
|
|
|
class TGrid_control : public TControl
|
|
{
|
|
enum { FIRST_FIELD = 101, MAX_COL = 128 };
|
|
|
|
long _cur_rec;
|
|
|
|
// @cmember:(INTERNAL) Tipo di ogni colonna
|
|
byte _type[MAX_COL];
|
|
|
|
TGrid_field* _grid;
|
|
|
|
protected: // TControl
|
|
//@cmember Gestisce gli eventi delle celle
|
|
virtual bool event_handler(XI_OBJ* itf, XI_EVENT* xiev);
|
|
|
|
protected:
|
|
long items() const { return _grid->items(); }
|
|
|
|
int rec2row(long rec) const;
|
|
long row2rec(int row) const;
|
|
|
|
XI_OBJ* find_column(int col) const;
|
|
|
|
public:
|
|
long selected() const { return _cur_rec; }
|
|
void select(long n);
|
|
void set_focus_rec(long rec);
|
|
|
|
int visible_rows() const;
|
|
|
|
byte& column_type(int c) { CHECKD(c >= 0 && c < MAX_COL, "Bad column ", c); return _type[c]; }
|
|
|
|
void update(long n = -1);
|
|
|
|
TGrid_control(WINDOW parent, short cid,
|
|
short x, short y, short dx, short dy,
|
|
const char* flags, const char* head,
|
|
TGrid_field* owner);
|
|
virtual ~TGrid_control() {}
|
|
};
|
|
|
|
|
|
TGrid_control::TGrid_control(
|
|
WINDOW parent, // @parm Finestra alla quale appartiene lo spreadsheet
|
|
short cid, // @parm Identificatore
|
|
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* flags, // @parm Flags di abilitazione
|
|
const char* head, // @parm Titolo delle colonne
|
|
TGrid_field* owner)
|
|
: _grid(owner), _cur_rec(0)
|
|
{
|
|
const int NUMBER_WIDTH = strchr(flags, 'A') ? 7 : 1;
|
|
short v_width[MAX_COL];
|
|
short m_width[MAX_COL];
|
|
int fixed_columns = 1; // Number of fixed columns
|
|
int lines_in_header = 1; // Number of header lines
|
|
const bool multiline = strchr(flags, 'M') != NULL;
|
|
const int lines_in_cell = multiline ? (int)xi_get_pref(XI_PREF_DEFAULT_MAX_LINES_IN_CELL) : 1;
|
|
|
|
// Calcolo larghezza massima tabella
|
|
TToken_string header(head);
|
|
TToken_string new_header(256);
|
|
int i = 0;
|
|
int f_width = NUMBER_WIDTH; // 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);
|
|
_type[i] = ' ';
|
|
|
|
TFixed_string testa(esc(h));
|
|
const bool multiple = testa.find('\n') > 0;
|
|
if (multiple)
|
|
lines_in_header = 2;
|
|
|
|
const int at = testa.find('@');
|
|
int v = testa.len(); // Video width
|
|
if (at >= 0)
|
|
{
|
|
const TString& wi = testa.mid(at+1);
|
|
const int video = atoi(wi);
|
|
if (video > 0) v = video;
|
|
if (wi.find('F') >= 0)
|
|
{
|
|
fixed_columns = i+2;
|
|
f_width += v+1;
|
|
}
|
|
if (wi.find('R') >= 0)
|
|
_type[i] = 'R';
|
|
|
|
testa.cut(at);
|
|
}
|
|
|
|
v++;
|
|
// memory width of column
|
|
m_width[i] = v * lines_in_cell;
|
|
if (v > 64) v = 64;
|
|
v_width[i] = v;
|
|
if (v_width[i] > max_width) max_width = v_width[i];
|
|
|
|
new_header.add(testa);
|
|
}
|
|
|
|
// Calcola rettangolo massimo per lo sheet
|
|
XI_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)
|
|
fixed_columns = 1;
|
|
|
|
XI_OBJ* itf = get_interface(parent);
|
|
|
|
XI_OBJ_DEF* listdef = xi_add_list_def(NULL, cid,
|
|
rct.top, rct.left, rct.bottom-rct.top,
|
|
XI_ATR_ENABLED | XI_ATR_VISIBLE,
|
|
NORMAL_COLOR, NORMAL_BACK_COLOR, // normal
|
|
DISABLED_COLOR, DISABLED_BACK_COLOR, // disabled
|
|
FOCUS_COLOR, // active
|
|
0);
|
|
|
|
listdef->app_data = (long)this;
|
|
|
|
XI_LIST_DEF* l = listdef->v.list;
|
|
l->min_heading_height = xi_button_calc_height_font_id(xvt_default_font()) * lines_in_header;
|
|
l->sizable_columns = TRUE;
|
|
l->movable_columns = TRUE;
|
|
l->fixed_columns = fixed_columns;
|
|
l->scroll_bar = TRUE;
|
|
l->scroll_bar_button = TRUE;
|
|
l->white_space_color = MASK_DARK_COLOR;
|
|
l->rule_color = MASK_DARK_COLOR;
|
|
|
|
// Definizione della prima colonna (numero di riga)
|
|
const long attr = XI_ATR_VISIBLE | XI_ATR_RJUST | XI_ATR_SELECTABLE;
|
|
XI_OBJ_DEF* coldef = xi_add_column_def(listdef, FIRST_FIELD+1000-1, attr, 0,
|
|
NUMBER_WIDTH * XI_FU_MULTIPLE, NUMBER_WIDTH , "");
|
|
|
|
coldef->app_data = (long)this;
|
|
XI_COLUMN_DEF* cd = coldef->v.column;
|
|
cd->heading_platform = TRUE;
|
|
cd->column_platform = TRUE;
|
|
cd->size_rows = multiline;
|
|
|
|
for (h = new_header.get(0), i = 0; h; h = new_header.get(), i++)
|
|
{
|
|
long attr = XI_ATR_VISIBLE | XI_ATR_ENABLED | XI_ATR_AUTOSCROLL | XI_ATR_READONLY;
|
|
if (_type[i] == 'C')
|
|
attr |= XI_ATR_SELECTABLE;
|
|
if (_type[i] == 'R')
|
|
attr |= XI_ATR_RJUST;
|
|
coldef = xi_add_column_def(listdef, FIRST_FIELD+i+1000, attr, i+1,
|
|
v_width[i] * XI_FU_MULTIPLE, m_width[i], (char*)h);
|
|
|
|
coldef->app_data = (long)this;
|
|
cd = coldef->v.column;
|
|
cd->heading_platform = TRUE;
|
|
cd->center_heading = strchr(h, '\n') == NULL;
|
|
if (multiline)
|
|
{
|
|
cd->size_rows = TRUE;
|
|
cd->wrap_text = TRUE;
|
|
}
|
|
}
|
|
|
|
RCT rd; xi_get_def_rect(listdef, &rd);
|
|
if ((rd.right - rd.left) > (rct.right - rct.left))
|
|
l->width = rct.right - rct.left;
|
|
|
|
_obj = xi_create(itf, listdef); // Create the whole thing!
|
|
xi_dequeue(); // Flush events in XOL
|
|
xi_tree_free(listdef); // Free definitions
|
|
|
|
CHECKD(_obj, "Can't create list control ", cid);
|
|
update_tab_cid();
|
|
}
|
|
|
|
// Converts a row number in the correspondig record number
|
|
int TGrid_control::rec2row(long record) const
|
|
{
|
|
int rows;
|
|
const long* rec = xi_get_list_info(_obj, &rows);
|
|
int r = int(record - rec[0]);
|
|
if (r < 0 || r >= rows)
|
|
r = -1;
|
|
return r;
|
|
}
|
|
|
|
// Converts a row number in the correspondig record number
|
|
long TGrid_control::row2rec(int row) const
|
|
{
|
|
int rows;
|
|
const long* handle = xi_get_list_info(_obj, &rows);
|
|
|
|
if (row < 0)
|
|
row = 0;
|
|
else
|
|
{
|
|
if (row >= rows)
|
|
row = rows-1;
|
|
}
|
|
const long r = handle[row];
|
|
CHECKD(r >= 0 && r < items(), "Sheet line out of range: ", row);
|
|
|
|
return r;
|
|
}
|
|
|
|
int TGrid_control::visible_rows() const
|
|
{
|
|
return xi_get_visible_rows(_obj, NULL, NULL);
|
|
}
|
|
|
|
void TGrid_control::update(long n)
|
|
{
|
|
if (n >= 0)
|
|
{
|
|
const int riga = rec2row(n);
|
|
if (riga >= 0)
|
|
{
|
|
XI_OBJ row;
|
|
XI_MAKE_ROW(&row, _obj, riga);
|
|
xi_cell_request(&row);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
int num = 0;
|
|
const long* handle = xi_get_list_info(_obj, &num);
|
|
|
|
bool scroll_first = items() == 0;
|
|
if (!scroll_first)
|
|
{
|
|
int first = 0, last = 0;
|
|
xi_get_visible_rows(_obj, &first, &last);
|
|
n = handle[first];
|
|
scroll_first = n > items();
|
|
}
|
|
|
|
if (scroll_first)
|
|
xi_scroll(_obj, XI_SCROLL_FIRST);
|
|
else
|
|
xi_scroll_rec(_obj, n, NORMAL_COLOR, XI_ATR_ENABLED, 0);
|
|
}
|
|
}
|
|
|
|
void TGrid_control::select(long rec)
|
|
{
|
|
if (rec >= 0 && rec < items())
|
|
{
|
|
int rows;
|
|
const long* handle = xi_get_list_info(_obj, &rows);
|
|
|
|
int first = 0, last = 0;
|
|
xi_get_visible_rows(_obj, &first, &last);
|
|
|
|
if (rec < handle[first] || rec > handle[last])
|
|
xi_scroll_rec(_obj, rec, NORMAL_COLOR, XI_ATR_ENABLED, 0);
|
|
}
|
|
}
|
|
|
|
void TGrid_control::set_focus_rec(long rec)
|
|
{
|
|
if (rec < 0)
|
|
rec = selected();
|
|
int r = rec2row(rec);
|
|
if (r < 0)
|
|
{
|
|
select(rec);
|
|
r = rec2row(rec);
|
|
}
|
|
|
|
const int c = _type[0] == 'C' ? 2 : 1;
|
|
XI_OBJ cell; XI_MAKE_CELL(&cell, _obj, r, c);
|
|
xi_set_focus(&cell);
|
|
}
|
|
|
|
XI_OBJ* TGrid_control::find_column(
|
|
int col) const // @parm Indice o identificatore colonna
|
|
{
|
|
CHECKD(col >= 0, "Bad column ", col);
|
|
if (col < FIRST_FIELD) // Se e' un indice trasformalo in identificatore
|
|
col += FIRST_FIELD + 1000;
|
|
|
|
int num;
|
|
XI_OBJ** columns = xi_get_member_list(_obj, &num);
|
|
for (int c = num-1; c >= 0; c--)
|
|
{
|
|
if (columns[c]->cid == col)
|
|
break;
|
|
}
|
|
return c >= 0 ? columns[c] : NULL;
|
|
}
|
|
|
|
// Certified 75%
|
|
bool TGrid_control::event_handler(XI_OBJ* itf, XI_EVENT *xiev)
|
|
{
|
|
BOOLEAN& refused = xiev->refused;
|
|
|
|
const bool handled = _grid->handler(xiev);
|
|
if (handled)
|
|
return !refused;
|
|
|
|
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
|
|
refused = TRUE;
|
|
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())
|
|
refused = TRUE;
|
|
else
|
|
xiev->v.rec_request.data_rec = n;
|
|
}
|
|
break;
|
|
case XIE_GET_PERCENT:
|
|
{
|
|
const long rec = xiev->v.get_percent.record;
|
|
long n = items(); if (n <= 0) n = 1;
|
|
xiev->v.get_percent.percent = int(rec * 100L / n);
|
|
}
|
|
break;
|
|
case XIE_COL_MOVE:
|
|
if (xiev->v.column.in_fixed ||
|
|
xiev->v.column.col_nbr < xi_get_fixed_columns(xiev->v.column.list))
|
|
refused = TRUE;
|
|
break;
|
|
case XIE_COL_SIZE:
|
|
break;
|
|
case XIE_SELECT:
|
|
xiev->refused = TRUE;
|
|
break;
|
|
case XIE_CELL_REQUEST:
|
|
if (xiev->v.cell_request.col_nbr == 0)
|
|
{
|
|
if (xiev->v.cell_request.len > 1)
|
|
{
|
|
sprintf(xiev->v.cell_request.s, "%ld", xiev->v.cell_request.rec);
|
|
xiev->v.cell_request.color = NORMAL_COLOR;
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return !refused;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// TGrid_field
|
|
///////////////////////////////////////////////////////////
|
|
|
|
void TGrid_field::create(WINDOW parent)
|
|
{
|
|
_ctl = new TGrid_control(parent, dlg(),
|
|
_ctl_data._x, _ctl_data._y,
|
|
_ctl_data._width, _ctl_data._size,
|
|
_ctl_data._flags, _ctl_data._park,
|
|
this);
|
|
}
|
|
|
|
void TGrid_field::parse_head(TScanner& scanner)
|
|
{
|
|
_ctl_data._width = scanner.integer();
|
|
_ctl_data._height = scanner.integer();
|
|
if (_ctl_data._height == 0)
|
|
_ctl_data._height = -1;
|
|
}
|
|
|
|
bool TGrid_field::parse_item(TScanner& scanner)
|
|
{
|
|
if (scanner.key() == "IT")
|
|
{
|
|
_ctl_data._park.add(scanner.string());
|
|
return TRUE;
|
|
}
|
|
return TMask_field::parse_item(scanner);
|
|
}
|
|
|
|
|
|
bool TGrid_field::handler(XI_EVENT* xiev)
|
|
{
|
|
if (xiev->type == XIE_CELL_REQUEST)
|
|
{
|
|
const long& rec = xiev->v.cell_request.rec;
|
|
const short& col = xiev->v.cell_request.col_nbr;
|
|
|
|
if (col == 3)
|
|
{
|
|
strcpy(xiev->v.cell_request.s,
|
|
"Questa e' una descrizioncina sgarsolina sgarsolina,"
|
|
" che non doverebbe stare in una sola righina");
|
|
|
|
xiev->v.cell_request.back_color = rec % 7 ? COLOR_YELLOW : COLOR_CYAN;
|
|
return TRUE;
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
long TGrid_field::items() const
|
|
{
|
|
return 30000L;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// TGrid_mask
|
|
///////////////////////////////////////////////////////////
|
|
|
|
class TGrid_mask : public TMask
|
|
{
|
|
TEsercizi_contabili _esercizi;
|
|
|
|
protected: // TMask
|
|
virtual TMask_field* parse_field(TScanner& sc);
|
|
|
|
static bool data_handler(TMask_field& f, KEY k);
|
|
|
|
public:
|
|
const TEsercizi_contabili& esercizi() const { return _esercizi; }
|
|
TEsercizi_contabili& esercizi() { return _esercizi; }
|
|
|
|
TGrid_mask(const char* name);
|
|
virtual ~TGrid_mask() { }
|
|
};
|
|
|
|
TGrid_mask::TGrid_mask(const char* name)
|
|
{
|
|
read_mask(name, 0, 0);
|
|
|
|
set_handler(F_DADATA, data_handler);
|
|
set_handler(F_ADATA, data_handler);
|
|
}
|
|
|
|
TMask_field* TGrid_mask::parse_field(TScanner& sc)
|
|
{
|
|
TMask_field* f;
|
|
if (sc.key() == "SP")
|
|
f = new TGrid_field(this);
|
|
else
|
|
f = TMask::parse_field(sc);
|
|
return f;
|
|
}
|
|
|
|
bool TGrid_mask::data_handler(TMask_field& f, KEY k)
|
|
{
|
|
bool ok = TRUE;
|
|
if (f.to_check(k) && !f.empty())
|
|
{
|
|
const TGrid_mask& gm = (const TGrid_mask&)f.mask();
|
|
int codice_esercizio = gm.get_int(F_ESERCIZIO);
|
|
if (codice_esercizio == 0)
|
|
{
|
|
const short id_altra_data = f.dlg() == F_DADATA ? F_ADATA : F_DADATA;
|
|
const TDate d = gm.get(id_altra_data);
|
|
if (d.ok())
|
|
codice_esercizio = gm.esercizi().date2esc(d);
|
|
}
|
|
const TDate d = f.get();
|
|
const int esercizio = gm.esercizi().date2esc(d);
|
|
if (codice_esercizio != 0)
|
|
{
|
|
if (esercizio != codice_esercizio)
|
|
ok = error_box("La data deve appartenere all'esercizio %d", codice_esercizio);
|
|
}
|
|
else
|
|
{
|
|
if (esercizio == 0)
|
|
ok = error_box("La data deve appartenere ad un esercizio contabile");
|
|
}
|
|
}
|
|
return ok;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// TMastrini_video
|
|
///////////////////////////////////////////////////////////
|
|
|
|
class TMastrini_video : public TApplication
|
|
{
|
|
TGrid_mask* _gm;
|
|
|
|
protected:
|
|
virtual bool create();
|
|
virtual bool menu(MENU_TAG);
|
|
virtual void on_firm_change();
|
|
};
|
|
|
|
bool TMastrini_video::create()
|
|
{
|
|
_gm = NULL;
|
|
dispatch_e_menu(BAR_ITEM(1));
|
|
return TRUE;
|
|
}
|
|
|
|
void TMastrini_video::on_firm_change()
|
|
{
|
|
if (_gm)
|
|
_gm->esercizi().update();
|
|
}
|
|
|
|
bool TMastrini_video::menu(MENU_TAG)
|
|
{
|
|
_gm = new TGrid_mask("cg3600a");
|
|
KEY key = 0;
|
|
while (key != K_QUIT)
|
|
{
|
|
if (key == 0)
|
|
{
|
|
const TEsercizi_contabili& esercizi = _gm->esercizi();
|
|
const int codice_ultimo_esercizio = esercizi.last();
|
|
if (codice_ultimo_esercizio > 0)
|
|
{
|
|
const TEsercizio& esercizio = esercizi.esercizio(codice_ultimo_esercizio);
|
|
_gm->set(F_ESERCIZIO, codice_ultimo_esercizio);
|
|
_gm->set(F_DADATA, esercizio.inizio());
|
|
_gm->set(F_ADATA, esercizio.fine());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
_gm->reset(F_SOTTOCONTO); // Azzera sottoconto
|
|
_gm->reset(F_CLIENTE); // Azzera cliente
|
|
_gm->reset(F_FORNITORE); // Azzera fornitore
|
|
_gm->reset(F_DACAUSALE); // Azzera causali
|
|
_gm->reset(F_ACAUSALE);
|
|
}
|
|
key = _gm->run();
|
|
}
|
|
delete _gm;
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
int cg3600(int argc, char* argv[])
|
|
{
|
|
TMastrini_video mv;
|
|
mv.run(argc, argv, "Mastrini");
|
|
return 0;
|
|
}
|
|
|
|
|