#include #include #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::declare_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"); TString16 codtab = tipo == 'L' ? _codlin : _codimp; codtab << key; cal.put("CODTAB", codtab); TString* s1 = new TString(62); if (cal.read() == NOERR) *s1 = cal.get("S1"); const int l1 = s1->len(); if (l1 < s1->size()) { const TString spc(s1->size()-l1, ' '); *s1 << spc; } if (tipo == 'L') _exc_lin.add(key, s1); else _exc_imp.add(key, s1); } int TMRP_calendar::write_cal(char tipo) const { int err = NOERR; TTable cal((tipo == 'L') ? "CAL" : "CAI"); TAssoc_array& ass = tipo == 'L' ? ((TMRP_calendar*)this)->_exc_lin : ((TMRP_calendar*)this)->_exc_imp; TString codtab, s0; FOR_EACH_ASSOC_STRING(ass, hash, key, str) { codtab = tipo == 'L' ? _codlin : _codimp; codtab.left_just(5); codtab << key; cal.zero(); cal.put("CODTAB", codtab); const TFixed_string s1(str); if (!s1.blank()) { const int anno = atoi(codtab.mid(5, 4)); const int mese = atoi(codtab.mid(9, 2)); if (tipo == 'L') { s0 = "Linea "; s0 << _codlin; } else { s0 = "Impianto "; s0 << _codimp; } s0 << ' ' << anno << ' ' << itom(mese); cal.put("S0", s0); cal.put("S1", s1); err = cal.write(); if (err != NOERR) err = cal.rewrite(); if (err != NOERR) { error_box("Errore %d nell'aggiornamento del calendario %s", err, (const char*)codtab); break; } } else err = cal.remove(); } return err; } int TMRP_calendar::remove_cal(const TString& code, char tipo) const { TTable cal(tipo == 'L' ? "CAL" : "CAI"); TString16 codtab = code; codtab.left_just(5); cal.put("CODTAB", codtab); for (int err = cal.read(_isgteq); err == NOERR; err = cal.next()) { if (codtab == cal.get("CODTAB").left(5)) cal.remove(); else break; } return NOERR; } int TMRP_calendar::turni(const TDate& data, int& mini, int& maxi, bool as_is) { 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("%04d%02d", year, month); if (_exc_lin.objptr(str) == NULL) read_cal(str, 'L'); const TString& turn = (const TString&)_exc_lin[str]; mini = turn[day-1] - '0'; maxi = turn[day+30] - '0'; if (as_is || (mini >= 0 && maxi >= 0)) return 3; } if (_codimp.not_empty()) { str.format("%04d%02d", year, month); if (_exc_imp.objptr(str) == NULL) read_cal(str, 'I'); const TString& turn = (const TString&)_exc_imp[str]; mini = turn[day-1] - '0'; maxi = turn[day+30] - '0'; if (as_is || (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[15] - '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("%04d%02d", 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-1] = '0' + mini; else turn[day-1] = ' '; if (maxi >= 0 && maxi <= 9) turn[day+30] = '0' + maxi; else turn[day+30] = ' '; return 3; } if (_codimp.not_empty()) { str.format("%04d%02d", 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-1] = '0' + mini; else turn[day-1] = ' '; if (maxi >= 0 && maxi <= 9) turn[day+30] = '0' + maxi; else turn[day+30] = ' '; 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() const { if (!_codlin.blank()) return write_cal('L'); if (!_codimp.blank()) return write_cal('I'); TConfig cfg(CONFIG_DITTA, "mr"); cfg.set("Turni", _days); cfg.set("Feste", _holidays); return NOERR; } int TMRP_calendar::remove() const { if (_codlin.not_empty()) return remove_cal(_codlin, 'L'); if (_codimp.not_empty()) return remove_cal(_codimp, 'I'); return NOERR; } 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 (impianto == NULL) _codimp = lnp.get("S6"); } else _codlin = ""; } if (_codimp.not_empty()) { TTable imp("IMP"); imp.put("CODTAB", _codimp); if (imp.read() != NOERR) _codimp = ""; } } char TMRP_calendar::tipo() const { if (!_codlin.blank()) return 'L'; if (!_codimp.blank()) return 'I'; return 'S'; } 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); TMRP_calendar* get_calendar() { return _calendario; } 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_number(106, 0, "= ", 31, 3, 1, "D"); m.add_number(107, 0, "= ", 31, 4, 1, "D"); 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, TRUE); m.set(104, mini); m.set(105, maxi); _calendario->turni(d, mini, maxi, FALSE); m.set(106, mini); m.set(107, 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->declare_holiday(d.day(), d.month()); else _calendario->suppress_holiday(d.day(), d.month()); } owner().set_dirty(); 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); set_handlers(); }