campo-sirio/mr/mrplib.cpp

497 lines
12 KiB
C++
Raw Normal View History

#include <config.h>
#include <tabutil.h>
#include "mrplib.h"
TString16 TMRP_calendar::_days;
TToken_string TMRP_calendar::_holidays;
void TMRP_calendar::init_default()
{
TConfig cfg(CONFIG_DITTA, "mr");
// Inizializza i turni dei 5 giorni feriali a 1
// Inizializza i turni di sabato e domenica a 0
// Inizializza i turni dei giorni festivi a 0
_days = cfg.get("Turni", NULL, -1, "1111100011111000");
// Inizializza la lista delle feste comandate tranne la Pasqua
_holidays = cfg.get("Feste", NULL, -1,
"01-01|06-01|25-04|01-05|15-08|01-11|08-12|25-12|26-12");
}
bool TMRP_calendar::is_holiday(int g, int m) const
{
if (_days.empty())
((TMRP_calendar*)this)->init_default();
TString16 str; str.format("%02d-%02d", g, m);
return _holidays.find(str) >= 0;
}
bool TMRP_calendar::is_holiday(const TDate& date) const
{
return is_holiday(date.day(), date.month());
}
bool TMRP_calendar::is_red(const TDate& date) const
{
if (date.wday() == 7)
return TRUE;
return is_holiday(date);
}
void TMRP_calendar::add_holiday(int g, int m)
{
if (!is_holiday(g, m))
{
TString16 str; str.format("%02d-%02d", g, m);
_holidays.add(str);
}
}
void TMRP_calendar::suppress_holiday(int g, int m)
{
if (is_holiday(g, m))
{
TString16 str; str.format("%02d-%02d", g, m);
const int pos = _holidays.find(str);
const TString tail = _holidays.mid(pos+6, -1);
_holidays.cut(pos);
_holidays << tail;
}
}
void TMRP_calendar::read_cal(const TString& key, char tipo)
{
TTable cal(tipo == 'L' ? "CAL" : "CAI");
cal.put("CODTAB", key);
TString80 s1;
if (cal.read() == NOERR)
s1 = cal.get("S1");
s1.left_just(62);
if (tipo == 'L')
_exc_lin.add(key, s1);
else
_exc_imp.add(key, s1);
}
int TMRP_calendar::turni(const TDate& data, int& mini, int& maxi)
{
const int year = data.year();
const int month = data.month();
const int day = data.day();
TString16 str;
mini = maxi = -1;
if (_codlin.not_empty())
{
str.format("%5s%4d%02d", _codlin, year, month);
if (_exc_lin.objptr(str) == NULL)
read_cal(str, 'L');
const TString& turn = (const TString&)_exc_lin[str];
mini = turn[day] - '0';
maxi = turn[day+31] - '0';
}
if (mini >= 0 && maxi >= 0)
return 3;
if (_codimp.not_empty())
{
str.format("%5s%4d%02d", _codimp, year, month);
if (_exc_imp.objptr(str) == NULL)
read_cal(str, 'I');
const TString& turn = (const TString&)_exc_imp[str];
mini = turn[day] - '0';
maxi = turn[day+31] - '0';
}
if (mini >= 0 && maxi >= 0)
return 2;
if (_days.empty())
init_default();
// Controlla se e' festa
for (str = _holidays.get(0); str.not_empty(); str = _holidays.get())
{
int g,m,a;
str << '-' << year;
if (sscanf(str, "%d-%d-%d", &g, &m, &a) == 3)
{
const TDate festa(g, m, a);
if (data == festa)
{
if (mini < 0) mini = _days[7] - '0';
if (maxi < 0) maxi = _days[7] - '0';
break;
}
}
}
if (mini >= 0 && maxi >= 0)
return 1;
// Usa giorni default
const int giorno = data.wday() - 1;
if (mini < 0) mini = _days[giorno] - '0';
if (maxi < 0) maxi = _days[giorno+8] - '0';
return 0;
}
int TMRP_calendar::set_turni(const TDate& data, int mini, int maxi)
{
const int year = data.year();
const int month = data.month();
const int day = data.day();
TString16 str;
if (_codlin.not_empty())
{
str.format("%5s%4d%02d", _codlin, year, month);
if (_exc_lin.objptr(str) == NULL)
read_cal(str, 'L');
TString& turn = (TString&)_exc_lin[str];
if (mini >= 0 && mini <= 9)
turn[day] = '0' + mini;
else
turn[day] = ' ';
if (maxi >= 0 && maxi <= 9)
turn[day+31] = '0' + maxi;
else
turn[day+31] = ' ';
return 3;
}
if (_codimp.not_empty())
{
str.format("%5s%4d%02d", _codimp, year, month);
if (_exc_imp.objptr(str) == NULL)
read_cal(str, 'I');
TString& turn = (TString&)_exc_imp[str];
if (mini >= 0 && mini <= 9)
turn[day] = '0' + mini;
else
turn[day] = ' ';
if (maxi >= 0 && maxi <= 9)
turn[day+31] = '0' + maxi;
else
turn[day+31] = ' ';
return 2;
}
// Controlla se e' festa
for (str = _holidays.get(0); str.not_empty(); str = _holidays.get())
{
int g,m,a;
str << '-' << year;
if (sscanf(str, "%d-%d-%d", &g, &m, &a) == 3)
{
const TDate festa(g, m, a);
if (data == festa)
{
if (mini >= 0 && mini <= 9)
_days[7] = '0' + mini;
else
_days[7] = ' ';
if (maxi >= 0 && maxi <= 9)
_days[15] = '0' + maxi;
else
_days[15] = ' ';
return 1;
}
}
}
const int giorno = data.wday() - 1;
if (mini >= 0 && mini <= 9)
_days[giorno] = '0' + mini;
else
_days[giorno] = '0';
if (maxi >= 0 && maxi <= 9)
_days[giorno+8] = '0' + maxi;
else
_days[giorno+8] = '0';
return 0;
}
int TMRP_calendar::write()
{
int err = NOERR;
if (_codlin.not_empty())
{
TTable cal("CAL");
FOR_EACH_ASSOC_STRING(_exc_lin, hash, key, str)
{
cal.put("CODTAB", key);
cal.put("S1", str);
err = cal.rewrite();
if (err != NOERR)
err = cal.write();
if (err != NOERR)
{
error_box("Errore %d nell'aggiornamento del calendario.", err);
break;
}
}
return err;
}
if (_codimp.not_empty())
{
TTable cal("CAI");
FOR_EACH_ASSOC_STRING(_exc_imp, hash, key, str)
{
cal.put("CODTAB", key);
cal.put("S1", (const TString&)_exc_imp[key]);
err = cal.rewrite();
if (err != NOERR)
err = cal.write();
if (err != NOERR)
{
error_box("Errore %d nell'aggiornamento del calendario.", err);
break;
}
}
return err;
}
TConfig cfg(CONFIG_DITTA, "mr");
cfg.set("Turni", _days);
cfg.set("Feste", _holidays);
return err;
}
void TMRP_calendar::set(const char* linea, const char* impianto)
{
_exc_lin.destroy();
_exc_imp.destroy();
_codlin = linea;
_codimp = impianto;
if (_codlin.not_empty())
{
TTable lnp("LNP");
lnp.put("CODTAB", _codlin);
if (lnp.read() == NOERR)
{
if (_codimp.empty())
_codimp = lnp.get("S6");
}
else
_codlin = "";
}
if (_codimp.not_empty())
{
TTable imp("IMP");
imp.put("CODTAB", _codimp);
if (imp.read() != NOERR)
_codimp = "";
}
}
TMRP_calendar::TMRP_calendar(const char* linea, const char* impianto)
{
set(linea, impianto);
}
///////////////////////////////////////////////////////////
// TCalendar_win
///////////////////////////////////////////////////////////
class TCalendar_win : public TField_window
{
int _anno;
TMRP_calendar* _calendario;
protected:
virtual void handler(WINDOW win, EVENT* ep);
virtual void update();
public:
void set_calendar(TMRP_calendar* cal, int year = 0);
TCalendar_win(int x, int y, int dx, int dy,
WINDOW parent, TWindowed_field* owner);
virtual ~TCalendar_win() { }
};
void TCalendar_win::handler(WINDOW win, EVENT* ep)
{
switch (ep->type)
{
case E_MOUSE_DOWN:
if (_calendario)
{
const PNT& where = ep->v.mouse.where;
RCT rct; xvt_vobj_get_client_rect(win, &rct);
const int month = where.v * 13 / rct.bottom;
if (month >= 1 && month <= 12)
{
const int day = where.h * 33 / rct.right - 1;
const int last = TDate::last_day(month, _anno);
if (day >= 1 && day <= last)
{
TMask m("Turni del giorno", 1, 40, 7);
m.add_date(101, 0, "Data ", 1, 1, "D");
m.add_string(102, 0, "", 19, 1, 9, "D");
m.add_boolean(103, 0, "Festa", 31, 1);
m.add_list(104, 0, "Turni minimi ", 1, 3, 8, "", " |0|1|2|3|4|5|6", "Standard|Nessuno|1 turno|2 turni|3 turni|4 turni|5 turni|6 turni");
m.add_list(105, 0, "Turni massimi ", 1, 4, 8, "", " |0|1|2|3|4|5|6", "Standard|Nessuno|1 turno|2 turni|3 turni|4 turni|5 turni|6 turni");
m.add_button(DLG_OK, 0, "", -12, -1, 10, 2);
m.add_button(DLG_CANCEL, 0, "", -22, -1, 10, 2);
const TDate d(day, month, _anno);
const bool festa = _calendario->is_holiday(d);
m.set(101, d.string());
m.set(102, itow(d.wday()));
m.set(103, festa ? "X" : "");
int mini, maxi; _calendario->turni(d, mini, maxi);
m.set(104, mini);
m.set(105, maxi);
if (m.run() == K_ENTER && m.dirty())
{
const char mi = m.get(104)[0];
mini = (mi == ' ') ? -1 : mi-'0';
const char ma = m.get(105)[0];
maxi = (ma == ' ') ? -1 : ma-'0';
_calendario->set_turni(d, mini, maxi);
const bool fe = m.get_bool(103);
if (fe != festa)
{
if (fe)
_calendario->add_holiday(d.day(), d.month());
else
_calendario->suppress_holiday(d.day(), d.month());
}
force_update();
}
}
}
}
break;
default:
break;
}
TField_window::handler(win, ep);
}
void TCalendar_win::update()
{
TField_window::update();
_pixmap = TRUE;
TString16 str;
str << _anno;
set_color(COLOR_BLACK, COLOR_WHITE);
printat(1, 1, str);
RCT rct; xvt_vobj_get_client_rect(win(), &rct);
int i, j;
for (i = 1; i <= 31; i++)
{
const int x = rct.right * (i+1) / 33;
line(x, 0, x, rct.bottom);
str.format("%2d", i);
printat(x+2, 0, str);
}
for (j = 1; j <= 12; j++)
{
const int y = rct.bottom * j / 13;
line(0, y, rct.right, y);
str = itom(j); str.cut(3);
printat(1, y, str);
}
TMRP_calendar* defcal = NULL;
TMRP_calendar* cal = _calendario;
if (cal == NULL)
{
defcal = new TMRP_calendar();
cal = defcal;
}
for (j = 1; j <= 12; j++)
{
const int y = rct.bottom * j / 13;
const last = TDate::last_day(j, _anno);
for (i = 1; i <= last; i++)
{
const int x = rct.right * (i+1) / 33;
const TDate data(i, j, _anno);
set_color(cal->is_red(data) ? COLOR_RED : COLOR_BLACK, COLOR_WHITE);
int tmin, tmax;
cal->turni(data, tmin, tmax);
str.format("%d", tmin);
printat(x+2, y, str);
str.format("%2d", tmax);
printat(x+2, y+CHARY-3, str);
}
}
if (defcal != NULL)
delete defcal;
_pixmap = FALSE;
}
void TCalendar_win::set_calendar(TMRP_calendar* cal, int year)
{
_calendario = cal;
if (year > 0)
_anno = year;
else
_anno = TDate(TODAY).year();
}
TCalendar_win::TCalendar_win(int x, int y, int dx, int dy,
WINDOW parent, TWindowed_field* owner)
: TField_window(x, y, dx, dy, parent, owner)
{
xvt_sbar_set_range(win(), HSCROLL, 0, 0);
xvt_sbar_set_range(win(), VSCROLL, 0, 0);
set_calendar(NULL);
}
///////////////////////////////////////////////////////////
// TCalendar_field
///////////////////////////////////////////////////////////
TField_window* TCalendar_field::create_window(int x, int y, int dx, int dy, WINDOW parent)
{
return new TCalendar_win(x, y, dx, dy, parent, this);
}
void TCalendar_field::set_calendar(TMRP_calendar* cal, int year)
{
TCalendar_win& cw = (TCalendar_win&)win();
cw.set_calendar(cal, year);
}
///////////////////////////////////////////////////////////
// TCalendar_mask
///////////////////////////////////////////////////////////
TMask_field* TCalendar_mask::parse_field(TScanner& scanner)
{
const TString& k = scanner.key();
if (k == "CA")
return new TCalendar_field(this);
return TAutomask::parse_field(scanner);
}
TCalendar_mask::TCalendar_mask(const char* name, int num)
{
read_mask(name, num, 0);
}