diff --git a/include/msksheet.cpp b/include/msksheet.cpp index 74a323976..a804c2382 100755 --- a/include/msksheet.cpp +++ b/include/msksheet.cpp @@ -77,595 +77,601 @@ class TSpreadsheet:public TWindow { return _mask; } + int items () const { return _str.items (); } + int columns () const { return _columns; } + bool dirty () const { return _dirty; } + void set_notify (SPREADSHEET_NOTIFY n) { _notify = n; } void set_dirty (bool spork = TRUE) - {_dirty = spork; - } + { + _dirty = spork; + } - TSpreadsheet (short x, short y, short dx, short dy, const char *maskname, int maskno, - const char *head, WINDOW parent); - }; + TSpreadsheet (short x, short y, short dx, short dy, const char *maskname, int maskno, + const char *head, WINDOW parent); + }; // Certified 99% void TSpreadsheet ::init () - { - static bool first = TRUE; + { + static bool first = TRUE; - if (!first) return; + if (!first) return; - xvt_set_font (TASK_WIN, FF_FIXED, 0); - DRAW_CTOOLS ct; - win_get_draw_ctools (TASK_WIN, &ct); - xi_set_font (&ct.font); + xvt_set_font (TASK_WIN, FF_FIXED, 0); + DRAW_CTOOLS ct; + win_get_draw_ctools (TASK_WIN, &ct); + xi_set_font (&ct.font); - xi_init (); - xi_set_pref (XI_PREF_3D_LOOK, TRUE); + xi_init (); + xi_set_pref (XI_PREF_3D_LOOK, TRUE); // xi_set_pref(XI_PREF_COLOR_LIGHT, COLOR_CYAN); // xi_set_pref(XI_PREF_COLOR_CTRL, MASK_BACK_COLOR); // xi_set_pref(XI_PREF_COLOR_DARK, COLOR_GRAY); - first = FALSE; - } + first = FALSE; + } TSpreadsheet ::TSpreadsheet (short x, short y, short dx, short dy, - const char *maskname, int maskno, - const char *head, WINDOW parent) -: _mask (maskname, NO_MODE, maskno), _notify (NULL) + const char *maskname, int maskno, + const char *head, WINDOW parent) +: _mask (maskname, NO_MODE, maskno), _notify (NULL) - { - const int NUMBER_WIDTH = 3; - const int MAX_COL = 32; - int width[MAX_COL]; + { + const int NUMBER_WIDTH = 3; + const int MAX_COL = 32; + int width[MAX_COL]; - init (); + init (); // Calcolo larghezza massima tabella - TToken_string header (head); - TToken_string new_header (256); - int i = 0, tot_width = NUMBER_WIDTH + 1; - for (const char *h = header.get (); h; h = header.get (), i++) - { - CHECKD (i < MAX_COL, "Tu meni calumns in scit: ", i); - int w; - char *at = strchr (h, '@'); - if (at) - { - w = atoi (at + 1); - *at = '\0'; - } - else - w = strlen (h); + TToken_string header (head); + TToken_string new_header (256); + int i = 0, tot_width = NUMBER_WIDTH + 1; + for (const char *h = header.get (); h; h = header.get (), i++) + { + CHECKD (i < MAX_COL, "Tu meni calumns in scit: ", i); + int w; + char *at = strchr (h, '@'); + if (at) + { + w = atoi (at + 1); + *at = '\0'; + } + else + w = strlen (h); - width[i] = w + 1; + width[i] = w + 1; - const int cid = FIRST_FIELD + i; // Column & Field ID - const TMask_field * f = field (cid); // Field on mask - CHECKD (f, "The spreadsheet mask needs ALSO field ", cid); - if (f->has_query ())w += 2; + const int cid = FIRST_FIELD + i; // Column & Field ID + const TMask_field * f = field (cid); // Field on mask + CHECKD (f, "The spreadsheet mask needs ALSO field ", cid); + if (f->has_query ())w += 2; - tot_width += w; - new_header.add (h); - } - _columns = i; + tot_width += w; + new_header.add (h); + } + _columns = i; - if (x < 0) x = 0; - if (y < 0) y = 0; - if (dx == 0) - { - dx = tot_width; - if (dx > 76) dx = -x; - } + if (x < 0) x = 0; + if (y < 0) y = 0; + if (dx == 0) + { + dx = tot_width; + if (dx > 76) dx = -x; + } - RCT rct = resize_rect (x, y, dx, dy, WO_TE, parent); - rct.right -= 20; - rct.bottom -= 8; + RCT rct = resize_rect (x, y, dx, dy, WO_TE, parent); + rct.right -= 20; + rct.bottom -= 8; - XI_OBJ_DEF * itfdef = xi_create_itf_def (ITF_CID, + XI_OBJ_DEF * itfdef = xi_create_itf_def (ITF_CID, (XI_EVENT_HANDLER) xiev_handler, &rct, (char *) maskname, - PTR_LONG (this)); - itfdef->v.itf->automatic_back_color = FALSE; - itfdef->v.itf->back_color = MASK_BACK_COLOR; + PTR_LONG (this)); + itfdef->v.itf->automatic_back_color = FALSE; + itfdef->v.itf->back_color = MASK_BACK_COLOR; - XI_OBJ_DEF * listdef = xi_add_list_def (itfdef, LIST_CID, - 0, 0, rct.bottom - rct.top, - XI_ATR_ENABLED | XI_ATR_VISIBLE, - NORMAL_COLOR, NORMAL_BACK_COLOR, + XI_OBJ_DEF * listdef = xi_add_list_def (itfdef, LIST_CID, + 0, 0, rct.bottom - rct.top, + XI_ATR_ENABLED | XI_ATR_VISIBLE, + NORMAL_COLOR, NORMAL_BACK_COLOR, NORMAL_COLOR, DISABLED_BACK_COLOR, NORMAL_COLOR, - LIST_CID); - listdef->v.list->scroll_bar = TRUE; - listdef->v.list->sizable_columns = TRUE; - listdef->v.list->movable_columns = TRUE; - listdef->v.list->scroll_bar_button = TRUE; - listdef->v.list->fixed_columns = 1; - listdef->v.list->width = rct.right - rct.left; - listdef->v.list->min_cell_height = CHARY; - listdef->v.list->min_heading_height = CHARY; - listdef->v.list->white_space_color = COLOR_GRAY; + LIST_CID); + listdef->v.list->scroll_bar = TRUE; + listdef->v.list->sizable_columns = TRUE; + listdef->v.list->movable_columns = TRUE; + listdef->v.list->scroll_bar_button = TRUE; + listdef->v.list->fixed_columns = 1; + listdef->v.list->width = rct.right - rct.left; + listdef->v.list->min_cell_height = CHARY; + listdef->v.list->min_heading_height = CHARY; + listdef->v.list->white_space_color = COLOR_GRAY; - XI_OBJ_DEF * coldef = xi_add_column_def (listdef, 0, + XI_OBJ_DEF * coldef = xi_add_column_def (listdef, 0, XI_ATR_RJUST, 0, NUMBER_WIDTH, NUMBER_WIDTH, ""); - coldef->v.column->heading_platform = TRUE; - coldef->v.column->column_platform = TRUE; - coldef->v.column->center_heading = TRUE; + coldef->v.column->heading_platform = TRUE; + coldef->v.column->column_platform = TRUE; + coldef->v.column->center_heading = TRUE; - for (h = new_header.get (0), i = 0; h; h = new_header.get (), i++) - { - const int cid = FIRST_FIELD + i; // Column & Field ID - const TMask_field * f = field (cid); // Field on mask - const int w = width[i] + (f->has_query ()? 2 : 0); // Column width + for (h = new_header.get (0), i = 0; h; h = new_header.get (), i++) + { + const int cid = FIRST_FIELD + i; // Column & Field ID + const TMask_field * f = field (cid); // Field on mask + const int w = width[i] + (f->has_query ()? 2 : 0); // Column + // width - long flags = XI_ATR_EDITMENU | XI_ATR_AUTOSCROLL; - if (f->class_id () == CLASS_REAL_FIELD) flags |= XI_ATR_RJUST; - if (f->active ())flags |= XI_ATR_ENABLED; - else - _column_disabled.set (i); + long flags = XI_ATR_EDITMENU | XI_ATR_AUTOSCROLL; + if (f->class_id () == CLASS_REAL_FIELD) flags |= XI_ATR_RJUST; + if (f->active ())flags |= XI_ATR_ENABLED; + else + _column_disabled.set (i); - coldef = xi_add_column_def (listdef, cid, - flags, cid, w, width[i], (char *) h); - coldef->v.column->heading_platform = TRUE; - coldef->v.column->center_heading = TRUE; - } + coldef = xi_add_column_def (listdef, cid, + flags, cid, w, width[i], (char *) h); + coldef->v.column->heading_platform = TRUE; + coldef->v.column->center_heading = TRUE; + } - RCT itfrct; - xi_get_def_rect (itfdef, &itfrct); - offset_rect (&itfrct, rct.left, rct.top); - itfrct.bottom++; + RCT itfrct; + xi_get_def_rect (itfdef, &itfrct); + offset_rect (&itfrct, rct.left, rct.top); + itfrct.bottom++; - WINDOW win = create_window (W_NO_BORDER, &itfrct, "", 0, parent, - 0, EM_ALL, (EVENT_HANDLER) xi_event, 0L); - CHECK (win, "Can't create a window for the spreadsheet"); + WINDOW win = create_window (W_NO_BORDER, &itfrct, "", 0, parent, + 0, EM_ALL, (EVENT_HANDLER) xi_event, 0L); + CHECK (win, "Can't create a window for the spreadsheet"); - set_win (win); // Set TWindow::_win - itfdef->v.itf->win = win; + set_win (win); // Set TWindow::_win + itfdef->v.itf->win = win; - xi_create (NULL, itfdef); - xi_tree_free (itfdef); + xi_create (NULL, itfdef); + xi_tree_free (itfdef); - XI_OBJ * itf = xi_get_itf (win); - _list = xi_get_obj (itf, LIST_CID); - } + XI_OBJ * itf = xi_get_itf (win); + _list = xi_get_obj (itf, LIST_CID); + } // Converts a row number in the correspondig record number int TSpreadsheet ::row2rec (int row) - { - int rows; - const long *rec = xi_get_list_info (_list, &rows); + { + int rows; + const long *rec = xi_get_list_info (_list, &rows); #ifdef DBG - if (row < 0 || row >= rows) - { - error_box ("Line %d is not visible", row); - return 0L; - } + if (row < 0 || row >= rows) + { + error_box ("Line %d is not visible", row); + return 0L; + } #endif - return (int) rec[row]; - } + return (int) rec[row]; + } // Converts a row number in the correspondig record number int TSpreadsheet ::rec2row (int record) - { - int rows; - const long *rec = xi_get_list_info (_list, &rows); - int r = int (record - rec[0]); - if (r < 0 || r >= rows) - r = -1; + { + int rows; + const long *rec = xi_get_list_info (_list, &rows); + int r = int (record - rec[0]); + if (r < 0 || r >= rows) + r = -1; - return r; - } + return r; + } // Retrieves the corresponding field of the mask from a spredsheet cell TMask_field * TSpreadsheet ::cell2field (const XI_OBJ * cell) const - { - const int pos = cell->v.cell.column; + { + const int pos = cell->v.cell.column; - int num; - XI_OBJ ** column = xi_get_member_list (_list, &num); + int num; + XI_OBJ ** column = xi_get_member_list (_list, &num); - TMask_field * good = NULL; - for (short id = column[pos]->cid;; id += 100) - { - TMask_field * f = field (id); - if (f == NULL) break; - good = f; - if (f->active ())break; - } + TMask_field * good = NULL; + for (short id = column[pos]->cid;; id += 100) + { + TMask_field * f = field (id); + if (f == NULL) break; + good = f; + if (f->active ())break; + } - return good; - } + return good; + } void TSpreadsheet ::update_rec (int rec) - { - const int riga = rec2row (rec); - if (riga >= 0) - { - XI_OBJ row; - XI_MAKE_ROW (&row, _list, riga); - xi_cell_request (&row); // Update internal values - xi_set_row_height (&row, CHARY + 1); // Force row updating - } - } + { + const int riga = rec2row (rec); + if (riga >= 0) + { + XI_OBJ row; + XI_MAKE_ROW (&row, _list, riga); + xi_cell_request (&row); // Update internal values + xi_set_row_height (&row, CHARY + 1); // Force row updating + } + } void TSpreadsheet ::set_focus_cell (int riga, int colonna) - { - set_front_window (win ()); - XI_OBJ cell; - XI_MAKE_CELL (&cell, _list, rec2row (riga), colonna); - xi_set_focus (&cell); - } + { + set_front_window (win ()); + XI_OBJ cell; + XI_MAKE_CELL (&cell, _list, rec2row (riga), colonna); + xi_set_focus (&cell); + } int TSpreadsheet ::insert (int rec) - { - const bool ok = notify (rec, K_INS); - if (!ok) return -1; + { + const bool ok = notify (rec, K_INS); + if (!ok) return -1; - TToken_string s; // Empty row - const int r = _str.insert (s, rec); - _disabled.insert (NULL, rec); + TToken_string s; // Empty row + const int r = _str.insert (s, rec); + _disabled.insert (NULL, rec); - xi_insert_row (_list, INT_MAX); - xi_cell_request (_list); + xi_insert_row (_list, INT_MAX); + xi_cell_request (_list); - return r; - } + return r; + } bool TSpreadsheet ::destroy (int rec) - { - bool ok = TRUE; + { + bool ok = TRUE; - if (rec < 0) - { - _disabled.destroy (); - _str.destroy (); - } - else - { - _disabled.destroy (rec, TRUE); // Destroy enable info - ok = _str.destroy (rec, TRUE); // Destroy line - enable_cell (_str.items (), -1); // Enable last line - } + if (rec < 0) + { + _disabled.destroy (); + _str.destroy (); + } + else + { + _disabled.destroy (rec, TRUE); // Destroy enable info + ok = _str.destroy (rec, TRUE); // Destroy line + enable_cell (_str.items (), -1); // Enable last line + } - if (ok) xi_cell_request (_list); + if (ok) xi_cell_request (_list); - return ok; - } + return ok; + } void TSpreadsheet ::update (int row) - { - if (row < 0) - { - xi_cell_request (_list); - xi_scroll (_list, XI_SCROLL_FIRST); - set_front_window (win ()); - } - else - update_rec (row); - } + { + if (row < 0) + { + xi_cell_request (_list); + xi_scroll (_list, XI_SCROLL_FIRST); + set_front_window (win ()); + } + else + update_rec (row); + } void TSpreadsheet ::xiev_handler (XI_OBJ * itf, XI_EVENT * xiev) - { - TSpreadsheet * es = (TSpreadsheet *) xi_get_app_data (itf); - CHECK (es, "NULL Edit sheet in xi event"); - es->list_handler (xiev); - } + { + TSpreadsheet * es = (TSpreadsheet *) xi_get_app_data (itf); + CHECK (es, "NULL Edit sheet in xi event"); + es->list_handler (xiev); + } // Certified 75% void TSpreadsheet ::list_handler (XI_EVENT * xiev) - { - static TMask_field * edit_field = NULL; // Current edit field - static int cur_row = 0, cur_col = 0; // Current cell - static bool row_dirty = FALSE; // Current row changed - static bool check_enabled = TRUE; // Perform OFF_ROW checks + { + static TMask_field * edit_field = NULL; // Current edit field + static int cur_row = 0, cur_col = 0; // Current cell + static bool row_dirty = FALSE; // Current row changed + static bool check_enabled = TRUE; // Perform OFF_ROW checks - switch (xiev->type) - { + switch (xiev->type) + { case XIE_GET_FIRST: - { - const long max = items (); - if (max <= 0L) - { - xiev->refused = TRUE; - break; - } - long n = max * (long)xiev->v.rec_request.percent / 100L; - if (n < 0L) n = 0L; - xiev->v.rec_request.data_rec = n; - } - break; + { + const long max = items (); + if (max <= 0L) + { + xiev->refused = TRUE; + break; + } + long n = max * (long)xiev->v.rec_request.percent / 100L; + if (n < 0L) n = 0L; + xiev->v.rec_request.data_rec = n; + } + break; case XIE_GET_LAST: - xiev->v.rec_request.data_rec = items () - 1; - break; + 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 ()) - xiev->refused = TRUE; - 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; - TMask_field * f = field (cid); - src = row (rec).get (col); // Set value for cell - if (src && *src && f->class_id () == CLASS_REAL_FIELD) - { - src = f->picture_data (src, FALSE); // Get formatted string - } - if (field (cid)->has_query ()) - { - xiev->v.cell_request.button = - xiev->v.cell_request.button_on_focus = TRUE; - } - if (cell_disabled (rec, col)) - xiev->v.cell_request.back_color = MASK_BACK_COLOR; - } - } - else - src = format ("%d", rec + 1); - - const int len = xiev->v.cell_request.len; - char *dst = xiev->v.cell_request.s; - if (src) - { - strncpy (dst, src, len); - if (isspace (*dst)) - { - TFixed_string d (dst); - d.ltrim (); - } - } - else - *dst = '\0'; - } - break; -case XIE_BUTTON: - if (xiev->v.xi_obj->type == XIT_CELL) - { - if (edit_field) - { - const char *val = xi_get_text (xiev->v.xi_obj, NULL, -1); - edit_field->set (val); // Update current cell - check_enabled = FALSE; // Disable checks - if (!row_dirty) notify (cur_row, K_SPACE); - if (edit_field->on_key (K_F9)) // Show search sheet { - mask2str (cur_row); // Update row - row_dirty = TRUE; - } - check_enabled = TRUE; // Enable checks - xi_set_focus (xiev->v.xi_obj); // Restore focus to cell - } - } - else - if (xiev->v.xi_obj->type == XIT_LIST) - insert (-1); - break; -case XIE_DBL_CELL: - { - check_enabled = FALSE; - cur_row = row2rec (xiev->v.xi_obj->v.cell.row); - cur_col = xiev->v.xi_obj->v.cell.column; - const KEY k = edit (cur_row); - if (k == K_ENTER) - { - update_rec (cur_row); - row_dirty = TRUE; - } - xi_set_focus (xiev->v.xi_obj); - check_enabled = TRUE; - } - break; -case XIE_ON_ROW: - { - const int rec = row2rec (xiev->v.xi_obj->v.row); - if (rec < items ()) - { - cur_row = rec; - str2mask (rec); - row_dirty = FALSE; - } - else - xiev->refused = TRUE; - } - break; -case XIE_OFF_ROW: - if (row_dirty && check_enabled) - { - check_enabled = FALSE; // Avoid recursion! - set_dirty (); - str2mask (cur_row); // It shouldn't have to be necessary - bool ok = _mask.check_fields (); - if (ok) - { - mask2str (cur_row); - ok = notify (cur_row, K_ENTER); // Notify edit - } - else - { - xiev->refused = TRUE; - set_dirty (2); // Set error status - set_focus_cell (cur_row, cur_col); - } - check_enabled = TRUE; - } - break; -case XIE_ON_CELL: - { - TMask_field * f = cell2field (xiev->v.xi_obj); - const int col = (f->dlg () - FIRST_FIELD) % 100; - if (!cell_disabled (cur_row, col)) - { - edit_field = f; - cur_col = xiev->v.xi_obj->v.cell.column; - xi_set_color (xiev->v.xi_obj, XIC_BACK, FOCUS_BACK_COLOR); - } - else - { - xiev->refused = TRUE; // Refuse focus on disabled cells - } - } - break; -case XIE_OFF_CELL: - if (edit_field && check_enabled) - { - TMask_field * c = edit_field; // Save field, it could turn out to - // be NULL on error - const TString80 old (c->get ()); // Save old value on mask - const TString80 nuo (c->picture_data (xi_get_text (xiev->v.xi_obj, NULL, -1), TRUE)); - if (old != nuo) - { - check_enabled = FALSE; - if (!row_dirty) - { - notify (cur_row, K_SPACE); - row_dirty = TRUE; - } - c->set (nuo); // Set new mask value - c->set_dirty (); // Get it dirty! - if (c->on_key (K_TAB) == FALSE) // Test it - { - c->set (old); - xi_set_focus (xiev->v.xi_obj); - } - else - { - mask2str (cur_row); // Update sheet row - edit_field = NULL; // Reset current field - } - check_enabled = TRUE; - } - xi_set_color (xiev->v.xi_obj, XIC_BACK, NORMAL_BACK_COLOR); - } - break; -case XIE_GET_PERCENT: - { - const long rec = xiev->v.get_percent.record; - long n = items (); if (n < 1) n = 1; - xiev->v.get_percent.percent = int (rec * 100L / n); - } - break; -case XIE_CLEANUP: - set_win (NULL_WIN); - break; -case XIE_XVT_EVENT: - { - EVENT * ep = &xiev->v.xvte; - switch (ep->type) - { -case E_FOCUS: - if (ep->v.active == FALSE) - { - XI_OBJ * itf = xi_get_itf (win ()); - const bool ok = (bool) xi_move_focus (itf); - if (!ok) - xiev->refused = TRUE; - } - break; -case E_CHAR: - if (edit_field) - { - const KEY k = e_char_to_key (ep); - switch (k) - { -case K_F1: - check_enabled = FALSE; // Disable checks - edit_field->on_key (K_F1); - set_focus_cell (cur_row, cur_col); - check_enabled = TRUE; // Enable checks - // xiev->refused = TRUE; + const long n = xiev->v.rec_request.spec_rec + + (xiev->type == XIE_GET_NEXT ? +1 : -1); + if (n < 0 || n >= items ()) + xiev->refused = TRUE; + 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; + TMask_field * f = field (cid); + src = row (rec).get (col); // Set value for cell + if (src && *src && f->class_id () == CLASS_REAL_FIELD) + { + src = f->picture_data (src, FALSE); // Get formatted string + } + if (field (cid)->has_query ()) + { + xiev->v.cell_request.button = + xiev->v.cell_request.button_on_focus = TRUE; + } + if (cell_disabled (rec, col)) + xiev->v.cell_request.back_color = MASK_BACK_COLOR; + } + } + else + src = format ("%d", rec + 1); + + const int len = xiev->v.cell_request.len; + char *dst = xiev->v.cell_request.s; + if (src) + { + strncpy (dst, src, len); + if (isspace (*dst)) + { + TFixed_string d (dst); + d.ltrim (); + } + } + else + *dst = '\0'; + } + break; +case XIE_BUTTON: + if (xiev->v.xi_obj->type == XIT_CELL) + { + if (edit_field) + { + const char *val = xi_get_text (xiev->v.xi_obj, NULL, -1); + edit_field->set (val); // Update current cell + check_enabled = FALSE; // Disable checks + if (!row_dirty) notify (cur_row, K_SPACE); + if (edit_field->on_key (K_F9)) // Show search sheet + { + mask2str (cur_row); // Update row + row_dirty = TRUE; + } + check_enabled = TRUE; // Enable checks + xi_set_focus (xiev->v.xi_obj); // Restore focus to cell + } + } + else + if (xiev->v.xi_obj->type == XIT_LIST) + insert (-1); + break; +case XIE_DBL_CELL: + { + check_enabled = FALSE; + cur_row = row2rec (xiev->v.xi_obj->v.cell.row); + cur_col = xiev->v.xi_obj->v.cell.column; + const KEY k = edit (cur_row); + if (k == K_ENTER) + { + update_rec (cur_row); + row_dirty = TRUE; + } + xi_set_focus (xiev->v.xi_obj); + check_enabled = TRUE; + } + break; +case XIE_ON_ROW: + { + const int rec = row2rec (xiev->v.xi_obj->v.row); + if (rec < items ()) + { + cur_row = rec; + str2mask (rec); + row_dirty = FALSE; + } + else + xiev->refused = TRUE; + } + break; +case XIE_OFF_ROW: + if (row_dirty && check_enabled) + { + check_enabled = FALSE; // Avoid recursion! + set_dirty (); + str2mask (cur_row); // It shouldn't have to be necessary + bool ok = _mask.check_fields (); + if (ok) + { + mask2str (cur_row); + ok = notify (cur_row, K_ENTER); // Notify edit + } + else + { + xiev->refused = TRUE; + set_dirty (2); // Set error status + set_focus_cell (cur_row, cur_col); + } + check_enabled = TRUE; + } + break; +case XIE_ON_CELL: + { + TMask_field * f = cell2field (xiev->v.xi_obj); + const int col = (f->dlg () - FIRST_FIELD) % 100; + if (!cell_disabled (cur_row, col)) + { + edit_field = f; + cur_col = xiev->v.xi_obj->v.cell.column; + xi_set_color (xiev->v.xi_obj, XIC_BACK, FOCUS_BACK_COLOR); + } + else + { + xiev->refused = TRUE; // Refuse focus on disabled cells + } + } + break; +case XIE_OFF_CELL: + if (edit_field && check_enabled) + { + TMask_field * c = edit_field; // Save field, it could turn out to + // be NULL on error + const TString80 old (c->get ()); // Save old value on mask + const TString80 nuo (c->picture_data (xi_get_text (xiev->v.xi_obj, NULL, -1), TRUE)); + if (old != nuo) + { + check_enabled = FALSE; + if (!row_dirty) + { + notify (cur_row, K_SPACE); + row_dirty = TRUE; + } + c->set (nuo); // Set new mask value + c->set_dirty (); // Get it dirty! + if (c->on_key (K_TAB) == FALSE) // Test it + { + c->set (old); + xi_set_focus (xiev->v.xi_obj); + } + else + { + mask2str (cur_row); // Update sheet row + edit_field = NULL; // Reset current field + } + check_enabled = TRUE; + } + xi_set_color (xiev->v.xi_obj, XIC_BACK, NORMAL_BACK_COLOR); + } + break; +case XIE_GET_PERCENT: + { + const long rec = xiev->v.get_percent.record; + long n = items (); if (n < 1) n = 1; + xiev->v.get_percent.percent = int (rec * 100L / n); + } + break; +case XIE_CLEANUP: + set_win (NULL_WIN); + break; +case XIE_XVT_EVENT: + { + EVENT * ep = &xiev->v.xvte; + switch (ep->type) + { +case E_FOCUS: + if (ep->v.active == FALSE) + { + XI_OBJ * itf = xi_get_itf (win ()); + const bool ok = (bool) xi_move_focus (itf); + if (!ok) + xiev->refused = TRUE; + } + break; +case E_CHAR: + if (edit_field) + { + const KEY k = e_char_to_key (ep); + switch (k) + { +case K_F1: + check_enabled = FALSE; // Disable checks + edit_field->on_key (K_F1); + set_focus_cell (cur_row, cur_col); + check_enabled = TRUE; // Enable checks + // xiev->refused = TRUE; + break; case K_F2: case K_F3: case K_F8: case K_F9: - { - check_enabled = FALSE; // Disable checks - if (!row_dirty) notify (cur_row, K_SPACE); - if (edit_field->on_key (k)) - { - mask2str (cur_row); - row_dirty = TRUE; - } - set_focus_cell (cur_row, cur_col); - check_enabled = TRUE; // Enable checks - } - break; + { + check_enabled = FALSE; // Disable checks + if (!row_dirty) notify (cur_row, K_SPACE); + if (edit_field->on_key (k)) + { + mask2str (cur_row); + row_dirty = TRUE; + } + set_focus_cell (cur_row, cur_col); + check_enabled = TRUE; // Enable checks + } + break; case K_PLUS: - insert (cur_row); - xiev->refused = TRUE; - break; + insert (cur_row); + xiev->refused = TRUE; + break; case K_PREV: - xi_scroll (_list, XI_SCROLL_PGUP); + xi_scroll (_list, XI_SCROLL_PGUP); // xiev->refused = TRUE; - break; + break; case K_NEXT: - xi_scroll (_list, XI_SCROLL_PGDOWN); + xi_scroll (_list, XI_SCROLL_PGDOWN); // xiev->refused = TRUE; - break; + break; case K_HOME: - xi_scroll (_list, XI_SCROLL_FIRST); + xi_scroll (_list, XI_SCROLL_FIRST); // xiev->refused = TRUE; - break; + break; case K_END: - xi_scroll (_list, XI_SCROLL_LAST); + xi_scroll (_list, XI_SCROLL_LAST); // xiev->refused = TRUE; - break; + break; default: - break; - } - } - break; + break; + } + } + break; default: - break; - } - } - break; + break; + } + } + break; default: - break; - } - } + break; + } + } int TSpreadsheet ::add (TToken_string & t) - { - return _str.add (t); - } + { + return _str.add (t); + } TToken_string & TSpreadsheet ::row (int n) - { - return (TToken_string &) _str[n]; - } + { + return (TToken_string &) _str[n]; + } #else diff --git a/include/printer.cpp b/include/printer.cpp index 47986c2c4..9ec961d9a 100755 --- a/include/printer.cpp +++ b/include/printer.cpp @@ -1,2875 +1,3061 @@ -#include -#include - -#if XVT_OS==XVT_OS_SCOUNIX -#include -#include -#include -#else -#include -#endif - -#define STYLE_NUM 4 - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -struct PrDesc - { - TTextfile *_txt; - PRINT_RCD *_prcd; - bool _graphics; - int _formlen; - int _charsize; - int _lines_per_inch; - } -PrintWhat; - -#define LINES_PER_INCH (6.0) - -#if XVT_OS == XVT_OS_WIN - -#include - -void TPrinter :: -_get_windows_printer_names (TToken_string & t) -{ - char *buf = new char[4096]; // ammazzao' - - GetProfileString ("devices", NULL, "", buf, 4096); - - for (int i = 0; i < 4095; i++) - { - if (buf[i] == '\0' && buf[i + 1] == '\0') - break; - if (buf[i] == '\0' && buf[i + 1] != '\0') - buf[i] = '|'; - } - t = buf; - delete buf; -} - -BOOLEAN TPrinter :: -start_winprint (long data) -{ - PrDesc *pd = (PrDesc *) data; - TTextfile & txt = *(pd->_txt); - TPrintwin pw (pd->_prcd, txt, pd->_charsize); - pw.print_background (pd->_graphics); - pw.do_print (); - return pw.aborted (); -} -#endif - -// utils del caz -HIDDEN void -read_int (const char *s, int &n, int &cnt) -{ - static char nbuf[10]; - int j = 0; - while (!isdigit (s[cnt])) - cnt++; - while (isdigit (s[cnt])) - nbuf[j++] = s[cnt++]; - nbuf[j] = '\0'; - n = atoi (nbuf); -} - -#if XVT_OS == XVT_OS_WIN -void TPrinter :: -set_win_formlen () -{ - long pw, ph, phr, pvr; - xvt_escape (XVT_ESC_GET_PRINTER_INFO, _print_rcd, &ph, &pw, &pvr, &phr); - if (pvr != 0) - { - _formlen = (int) ((ph / pvr) * _lines_per_inch); - _dots_per_line = (int) (pvr / _lines_per_inch); - _vert_offset = (int) (ph % (long) (_formlen * _dots_per_line)); - _horz_offset = 0; // not implemented (font dependent) - - } - else - warning_box ("Il driver di stampante non e' valido. Non stampare prima di averlo" - " reinstallato"); -} -#endif - -void TPrinter :: -_parse_background () -{ - char op; - int x1, x2, y1, y2; - TToken_string tt (20); - TString txt (80); - TArray pix; - char ch; - int cnt = 0; - - while ((ch = _bg_desc[cnt++]) != '\0') - { - op = ch; - tt = ""; - char bf[2]; - bf[1] = '\0'; - switch (op) - { - case ' ': // ignore whitespace - - case '\t': - case '\n': - continue; - break; - case 'l': // line - - case 'b': // box - - case 'r': // round box - - cnt++; - read_int (_bg_desc, x1, cnt); - read_int (_bg_desc, y1, cnt); - read_int (_bg_desc, x2, cnt); - read_int (_bg_desc, y2, cnt); - cnt++; - tt << op; - tt.add (x1 - 1); - tt.add (y1 - 1); - tt.add (x2 - 1); - tt.add (y2 - 1); - break; - case 't': // text - - cnt++; - read_int (_bg_desc, x1, cnt); - read_int (_bg_desc, y1, cnt); - cnt++; - txt = ""; - while ((ch = _bg_desc[cnt++]) != '}') - txt << ch; - tt << op; - tt.add (x1 - 1); - tt.add (y1 - 1); - tt.add (txt); - break; - case 'P': // set pen style - - case 'B': // set brush - - case 'W': // set line width - - case 'C': // set pen color - - tt << op; - bf[0] = _bg_desc[cnt++]; - tt.add (bf); - break; - default: - yesnofatal_box ("Unknown background opcode: %c", op); - break; - } - pix.add (tt); - } - - // now build row descriptions - - // colors are listed in printapp: - - char curcol = 'n'; - char curpen = 'n'; - char curpat = 'n'; - char curwid = '1'; - - for (int l = 0; l < _formlen; l++) - { - - TString *rwd = (TString *) _background.objptr (l); - if (rwd == NULL) - { - _background.add (rwd = new TString, l); - if (curcol != 'n') - (*rwd) << 'C' << curcol; - if (curpat != 'n') - (*rwd) << 'B' << curpat; - if (curwid != '1') - (*rwd) << 'W' << curwid; - if (curpen != 'n') - (*rwd) << 'P' << curcol; - } - for (int j = 0; j < pix.items (); j++) - { - TToken_string & tt = (TToken_string &) pix[j]; - tt.restart (); - - // la stringa contiene l'opcode piu' i parametri in binario, - // incrementati di 1 per evitare lo 0 - - switch (*(tt.get (0))) - { - case 'b': - x1 = tt.get_int (1) + 1; - y1 = tt.get_int (2) + 1; - x2 = tt.get_int (3) + 1; - y2 = tt.get_int (4) + 1; - if (y1 == l + 1) // at ze biginnin - - { - (*rwd) << 'u' << char (x1); - (*rwd) << 'r' << char (x1) << char (x2); - (*rwd) << 'u' << char (x2); - } - else if (y2 == l + 1) // at ze end - - { - (*rwd) << 'o' << char (x1); - (*rwd) << 'r' << char (x1) << char (x2); - (*rwd) << 'o' << char (x2); - } - else if (y1 < l + 1 && y2 > l + 1) // in ze middol - - { - (*rwd) << 'v' << char (x1); - (*rwd) << 'v' << char (x2); - } - break; - case 'l': - x1 = tt.get_int (1) + 1; - y1 = tt.get_int (2) + 1; - x2 = tt.get_int (3) + 1; - y2 = tt.get_int (4) + 1; - if (y1 == y2 && y1 == l + 1) // orizzontale - - { - (*rwd) << 'h' << char (x1) << char (x2); - } - else if (y1 <= l + 1 && y2 >= l + 1) // verticale - - { - (*rwd) << 'v' << char (x1); - } - break; - case 't': - x1 = tt.get_int (1) + 1; - y1 = tt.get_int (2) + 1; // al gh'e' - - if (y1 == l + 1) - { - } - break; - case 'W': - curwid = *(tt.get (1)); - (*rwd) << 'W' << curwid; - break; - case 'P': - curpen = *(tt.get (1)); - (*rwd) << 'P' << curpen; - break; - case 'B': - curpat = *(tt.get (1)); - (*rwd) << 'B' << curpat; - break; - case 'C': - curcol = *(tt.get (1)); - (*rwd) << 'C' << curcol; - break; - } - } - } -} - -void TPrinter :: -setbackground (const char *b) -{ - _background.destroy (); - _bg_desc = b; - if (b != NULL) - _parse_background (); -} - -bool printers_on_key (TMask_field & f, KEY key); - -// fv support structs for config - -bool PrinterDef :: -read (const char *name, FILE * fd) -{ - _printername = name; - _printername.trim (); - - TToken_string tmp (64, '='); - TString l (48); - TString r (16); - - while (TRUE) - { - const long p = ftell (fd); // Memorizza inizio paragrafo - - if (fgets (__tmp_string, 256, fd) == NULL) - return FALSE; - tmp = __tmp_string; - tmp.trim (); - - if (tmp == "[End of File]") - return FALSE; - - if (tmp[0] == '[') - { - fseek (fd, p, SEEK_SET); // Ritorna ad inizio paragrafo - - break; - } - - l = tmp.get (); - l.trim (); - r = tmp.get (); - r.trim (); - - if (l == "Device name") - { - _devicename = r; - } - else if (l == "Filter name") - { - _filtername = r; - } - else if (l == "Printer type") - { - _printertype = r; - } - else if (l == "Normal") - { - strcpy (_atstr[normalstyle], r); - } - else if (l == "Bold") - { - strcpy (_atstr[boldstyle], r); - } - else if (l == "Italic") - { - strcpy (_atstr[italicstyle], r); - } - else if (l == "Underlined") - { - strcpy (_atstr[underlinedstyle], r); - } - else if (l == "Code") - { - TToken_string code (r); - _names.add (TString (code.get ())); - _codes.add (TString (code.get ())); - } - else if (l == "Form feed") - { - _ffcode = r; - } - else if (l == "Newline") - { - _nlcode = r; - } - else - return error_box ("Riga di configurazione stampante errata:\n%s", (const char *) l); - } - return TRUE; -} - -bool PrinterDef :: -isdefault () -{ - return strcmp (_printername, "Default") == 0; -} - -////////// TPRINTROW ////////// - -TPrintrow ::TPrintrow () -{ - reset (); -} - -TPrintrow ::TPrintrow (const TPrintrow & pr) -{ - _row = pr.row (); - memcpy (_attr, pr._attr, MAXSTR); - memcpy (_cols, pr._cols, MAXSTR); - _currentcolor = 'w'; - _currentcolor <<= 8; - _currentcolor += 'n'; - _currentstyle = pr._currentstyle; - for (int i = 0; i < MAXSTR; i++) - _cols[i] = _currentcolor; - _lastpos = pr._lastpos; -} - -TObject *TPrintrow :: -dup () - const - { - return new TPrintrow (*this); - } - - const char *TPrintrow ::class_name () - const - { - return "Printrow"; - } - - word TPrintrow ::class_id () - const - { - return CLASS_PRINTROW; - } - -TPrintrow & TPrintrow :: -reset () -{ - _row.spaces (sizeof (_attr)); - _currentcolor = 'w'; - _currentcolor <<= 8; - _currentcolor += 'n'; - memset (_attr, normalstyle, sizeof (_attr)); - for (int i = 0; i < MAXSTR; i++) - _cols[i] = _currentcolor; - _lastpos = 0; - _currentstyle = normalstyle; - return *this; -} - -const char *TPrintrow :: -row_codified () -{ - // returns the row with @-codes for font style and color - char last_attr = -1; - int last_color = -1; - int k = 0; - _row.rtrim (); - for (int i = 0; i < _row.len (); i++) - { - if (_attr[i] != last_attr) - { - __tmp_string[k++] = '@'; - switch (_attr[i]) - { - case normalstyle: - __tmp_string[k++] = 'r'; - break; - case boldstyle: - __tmp_string[k++] = 'b'; - break; - case italicstyle: - __tmp_string[k++] = 'i'; - break; - case underlinedstyle: - __tmp_string[k++] = 'u'; - break; - } - last_attr = _attr[i]; - } - if (_cols[i] != last_color) - { - __tmp_string[k++] = '$'; - __tmp_string[k++] = '['; - __tmp_string[k++] = (char) (_cols[i] & 0x00ff); - __tmp_string[k++] = ','; - __tmp_string[k++] = (char) (_cols[i] >> 8); - __tmp_string[k++] = ']'; - last_color = _cols[i]; - } - __tmp_string[k++] = _row[i]; - } - // k = k > 255 ? 255 : k; - __tmp_string[k] = '\0'; - return __tmp_string; -} - -TPrintrow & TPrintrow ::put (const char *str, int position, int len) -{ - if (len < 1) - len = strlen (str); - - if (position < 0) - position = _lastpos; - - char bg = 'w', fg = 'n'; - for (int i = 0; i < len; i++) - { - char c = str[i]; - if (c == '$' && str[i + 1] == '[') - { - ++i; - fg = str[++i]; - c = str[++i]; - if (c == ']') - bg = _currentcolor >> 8; - else if (c == ',') - { - bg = str[++i]; - i++; - } - else - { - CHECK (0, "Error in color specification"); - } - _currentcolor = (bg << 8) + fg; - } - else if (c == '@') - { - c = str[++i]; - switch (toupper (c)) - { - case '#': - case '<': - case '>': - // printer MUST handle them - { - const int n = (c == '#') ? 5 : ((c == '>') ? 10 : 8); - _row[position] = '@'; - _attr[position++] = _currentstyle; - for (int j = 1; j < n; j++) - { - _row[position] = c; - _attr[position++] = _currentstyle; - } - } - break; - case 'B': - _currentstyle = boldstyle; - break; - case 'I': - _currentstyle = italicstyle; - break; - case 'U': - _currentstyle = underlinedstyle; - break; - case 'R': - _currentstyle = normalstyle; - break; - default: - // should be number followed by skip or jump - if (isdigit (c)) - { - // read number - char digbuf[8]; - int cnt = 0; - digbuf[cnt++] = c; - while (isdigit (c = str[++i])) - digbuf[cnt++] = c; - digbuf[cnt] = '\0'; - int pp = atoi (digbuf); - if (toupper (c) == 'G') - { - if (pp >= MAXSTR) - fatal_box ("printrow reaches position %d", pp); - if (pp > position) - for (int k = position; k < pp; k++) - { - _attr[k] = _currentstyle; - _cols[k] = _currentcolor; - } - position = pp; - } - else if (toupper (c) == 'J') - { - if (pp + position >= MAXSTR) - fatal_box ("printrow reaches position %d", pp + position); - for (int k = 0; k < pp; k++) - { - _attr[k + position] = _currentstyle; - _cols[k + position] = _currentcolor; - } - position += pp; - } - } - else - { - _row[position] = c; - _attr[position++] = _currentstyle; - _cols[position++] = _currentcolor; - } - } // switch - - } - else - { - _row[position] = c; - _attr[position] = _currentstyle; - _cols[position++] = _currentcolor; - } - } // for - - _lastpos = position; - return *this; -} - -////////// TPRINTER ////////// - -bool -printers_on_key (TMask_field & f, KEY key) -{ - if (key == K_SPACE) - { - TToken_string pn1 (10), pn2 (20); - - const PrinterDef & def = MainApp ()->printer ().get_description (atoi (f.get ())); - const char *s; - int j = 0; - while ((s = def.get_codenames (j)) != NULL) - { - pn1.add (format ("%02d", j)); - pn2.add (s); - j++; - } - ((TList_field &) f.mask ().field (MSK_1_CODES)).replace_items (pn1, pn2); - } - return TRUE; -} - -#if XVT_OS == XVT_OS_WIN - -bool -set_windows_print_device (TMask_field & f, KEY key) -{ - static char szDevice[80]; - if (key == K_SPACE) - { - if (MainApp ()->printer ().get_printrcd () != NULL) - free_print_rcd (MainApp ()->printer ().get_printrcd ()); - TToken_string & pn = MainApp ()->printer ().getprinternames (); - TString pdev (pn.get (atoi (f.get ()))); - GetProfileString ("devices", pdev, "", szDevice, sizeof (szDevice)); - pdev << "," << szDevice; -// WriteProfileString("windows","device", pdev); - // madonna bona - MainApp ()->printer ().set_printrcd (get_print_rcd (&(MainApp ()->printer ().get_printrcdsize ()))); - MainApp ()->printer ().set_win_formlen (); - } - return TRUE; -} - -#endif - -TPrinter :: TPrinter ():_date (TODAY), _multiple_link (FALSE), _frozen (FALSE), _isgraphics (TRUE), -_lines_per_inch (6), _ch_size (12) - -{ - _footerhandler = _headerhandler = NULL; - _linkhandler = NULL; - _config = "printer.ini"; - _curprn = 0; // first in list if no default is specified - - _curcode = 0; // first in list if no default is specified - - _formlen = 66; - _frompage = 0; - _topage = 0xffff; - _hwformfeed = FALSE; - _currentpage = 1; - _currentrow = 1; - _fp = NULL; - _headersize = 0; - _footersize = 0; - _isopen = FALSE; - // read configuration file - read_configuration (_config); -#if XVT_OS == XVT_OS_WIN - print_begin (); - _print_rcd = get_print_rcd (&_print_rcd_size); - set_win_formlen (); -#else - _isgraphics = FALSE; -#endif -} - -TToken_string & TPrinter ::getprinternames () -{ -// per ora va solo in windows -#if XVT_OS == XVT_OS_WIN - _get_windows_printer_names (_printer_names); -#endif - return _printer_names; -} - -void TPrinter :: -read_configuration (const char *conf) -{ - - FILE *cnfp = fopen (conf, "r"); - if (cnfp == NULL) - fatal_box ("Impossibile aprire il file %s", (const char *) _config); - - for (int i = 0; !feof (cnfp); i++) - { - if (fgets (__tmp_string, 256, cnfp) == NULL) - return; - // else - if (strncmp (__tmp_string, "[Default]", 9) != 0) - // fgets(__tmp_string,256,cnfp); - // else - { - if (*__tmp_string == '[') - { - // fatal_box("[ expected in file of printer configuration"); - - char *u = strchr (__tmp_string, ']'); - if (u) - *u = '\0'; - u = __tmp_string + 1; - - PrinterDef *pp = new PrinterDef; - _printers.add (pp); - if (pp->read (u, cnfp) == FALSE) - break; - } - } - } - fclose (cnfp); - - TString s ("printer.def"); -#if XVT_OS == XVT_OS_SCOUNIX - s << format (".%d", getuid ()); -#endif - if (fexist (s)) - { - TScanner sc (s); - TToken_string t (sc.line ()); - int where_print = t.get_int (1); - t = sc.line (); - _curprn = t.get_int (1); - t = sc.line (); - _printerfile = t.get (1); - t = sc.line (); - _curcode = t.get_int (1); -#if XVT_OS != XVT_OS_WIN - PrinterDef & def = (PrinterDef &) get_description (_curprn); -#endif - switch (where_print) - { - case 0: // stampante -#if XVT_OS == XVT_OS_WIN - _printertype = winprinter; -#else - switch (atoi (def._printertype)) - { - case 0: - _printertype = normprinter; - break; - case 1: - _printertype = localprinter; - break; - case 2: - _printertype = spoolprinter; - break; - } -#endif - break; - case 1: // file - - _printertype = fileprinter; - break; - case 2: // video - - _printertype = screenvis; - _curcode = 0; - break; - } - } -} - -TPrinter ::~TPrinter () -{ -#if XVT_OS == XVT_OS_WIN - print_end (); -#endif -} - -const char *TPrinter :: -class_name () - const - { - return "Printer"; - } - - word TPrinter ::class_id () - const - { - return CLASS_PRINTER; - } - - TPrintrow *TPrinter ::getheaderline (int linetoget) -{ - return ((TPrintrow *) _header.objptr (linetoget)); -} - -TPrintrow *TPrinter :: -getfooterline (int linetoget) -{ - return ((TPrintrow *) _footer.objptr (linetoget)); -} - -void TPrinter :: -setheaderline (int linetoset, TPrintrow * line) -{ - _header.add (line, linetoset); - if (linetoset >= _headersize) - _headersize = linetoset + 1; -} - -void TPrinter :: -setheaderline (int linetoset, const TPrintrow & line) -{ - TPrintrow *p = new TPrintrow (line); - setheaderline (linetoset, p); -} - -void TPrinter :: -setfooterline (int linetoset, TPrintrow * line) -{ - _footer.add (line, linetoset); - // if (linetoset >= _footersize) _footersize = linetoset+1; -} - -void TPrinter :: -setfooterline (int linetoset, const TPrintrow & line) -{ - TPrintrow *p = new TPrintrow (line); - setfooterline (linetoset, p); -} - -void TPrinter :: -resetheader () -{ - _header.destroy (); - _headersize = 0; -} - -void TPrinter :: -resetfooter () -{ - _footer.destroy (); - // _footersize = 0; -} - -bool TPrinter :: -printrow (TPrintrow * rowtoprint) -{ - if (!isopen ()) - return FALSE; - - if (_currentpage < _frompage || _currentpage > _topage) - return TRUE; - - TString rw (rowtoprint == NULL ? "" : (_printertype == screenvis || _printertype == winprinter ? - rowtoprint->row_codified () : - rowtoprint->row ())); - rw.rtrim (); - - int lun = rw.len (); - int idx; - - for (idx = 0; idx < lun; idx++) - { - if (rw[idx] == '@') // gestione data e n. di pagina - - { - switch (rw[idx + 1]) - { - case '#': - rw.overwrite (format ("%-5u", _currentpage), idx++); - break; - case '>': - rw.overwrite (_date.string (4), idx++); - break; - case '<': - rw.overwrite (_date.string (2), idx++); - break; - default: - break; - } - } - } - - if (_printertype == screenvis) - { - if (!_vf->frozen ()) - _vf->add_line (rw); - else - _frozen = TRUE; - return TRUE; - } - - if (_printertype == winprinter) - { - // add line to txt - if (!_frozen) - _txt.append (rw); - return TRUE; - } - - const PrinterDef & pd = get_description (_curprn); - int prvstl = -1; - for (idx = 0; idx < lun; idx++) - { - int cst = rowtoprint->get_style (idx); - if (cst != prvstl) - { - fprintf (_fp, "%s", pd._atstr[normalstyle]); - if (cst != normalstyle) - fprintf (_fp, "%s", pd._atstr[cst]); - } - prvstl = cst; - putc (rw[idx], _fp); - } - if (newline ()) - putc (newline (), _fp); - - return TRUE; -} - -word TPrinter :: -rows_left () - const - { - word left = _formlen - _currentrow - _footersize + 1; - if (_currentrow < 2) - left -= _headersize; - return left; - } - - bool TPrinter ::print (TPrintrow & rowtoprint) -{ - bool ok = TRUE; - - if (_currentrow > _formlen - _footersize) - ok = printfooter (); - -// if (ok && _currentrow <= _headersize) - if (ok && _currentrow == 1) - ok = printheader (); - - if (ok) - { - ok = printrow (&rowtoprint); - _currentrow++; - } - - return ok; -} - -bool TPrinter :: -printheader () -{ - if (_headerhandler) - _headerhandler (*this); - - bool ok = TRUE; - for (int i = 0; i < _headersize && ok; i++) - ok = printrow (getheaderline (i)); - - _currentrow = _headersize + 1; - return ok; -} - -bool TPrinter :: -printfooter () -{ - if (_footerhandler) - _footerhandler (*this); - - bool ok = TRUE; - for (int i = 0; i < _footersize && ok; i++) - ok = printrow (getfooterline (i)); - -#if XVT_OS != XVT_OS_WIN - if (ok) - printformfeed (); -#endif - - _currentrow = 1; - _currentpage++; - - return ok; -} - -bool TPrinter :: -skip (int linestoskip) -{ - int jumpline; - - CHECK (linestoskip >= 0, "Linestoskip can't be negative"); - jumpline = _currentrow + linestoskip; - return jump (jumpline); -} - -bool TPrinter :: -jump (int jumpline) -{ - int i = 0; - bool ok = TRUE; - - CHECK (jumpline >= 0, "Jumpline can't be negative"); - if (jumpline > _formlen - _footersize) - ok = formfeed (); - else - for (i = _currentrow; i < jumpline; i++) - if (!printrow ()) - ok = FALSE; - if (jumpline > _formlen - _footersize) - ok = FALSE; - return ok; -} - -bool TPrinter :: -formfeed () -{ - const int lastrow = _formlen - _footersize; - for (; _currentrow <= lastrow; _currentrow++) - printrow (); - return printfooter (); -} - -void TPrinter :: -reset () -{ - resetheader (); - resetfooter (); - _currentpage = 1; - _currentrow = 1; -} - -bool TPrinter :: -printformfeed () -{ -#if XVT_OS != XVT_OS_WIN - const PrinterDef & pd = get_description (_curprn); - - if (_printertype != screenvis && _hwformfeed) - fprintf (_fp, "%s", (const char *) pd._ffcode); -#endif - return TRUE; -} - -bool TPrinter :: -open () -{ -// qui -#if XVT_OS==XVT_OS_SCOUNIX - if (_printertype == spoolprinter) - { - const PrinterDef & def = get_description (_curprn); - int pfd[2]; - - if (pipe (pfd) == -1) - return error_box ("Impossibile creare processo di stampa " "(pipe)"); - - int ret = fork (); - if (ret == -1) - return error_box ("Impossibile creare processo di stampa " "(fork)"); - - if (ret == 0) - { - if (( :: close (0) != -1) && ( ::dup (pfd[0]) == 0) && - ( :: close (pfd[0]) == 0) && ( ::close (pfd[1]) != -1)) - { - char s0[80]; - - sprintf (s0, "-d%s", (const char *) def._devicename); - if ((def._filtername).not_empty ()) - { - char s1[80]; - sprintf (s1, "-o %s", (const char *) def._filtername); - char *ws[5] = - {"lpr", "-s", s0, s1, NULL}; - execvp (ws[0], ws); - } - else - { - char *ws[4] = - {"lpr", "-s", s0, NULL}; - execvp (ws[0], ws); - } - exit (-1); - } - } - if (( ::close (pfd[0]) == -1) || ((_fp = fdopen (pfd[1], "w")) == NULL)) - return error_box ("Impossibile creare processo di stampa" "(close)"); - } - else -#endif - if (_printertype == screenvis) - { - _vf = new TViswin (NULL, "Anteprima di stampa", TRUE, TRUE, - _linksdescr.items () > 0); - _vf->open_modal (); - } - else if (_printertype == winprinter) - { - // prepare text object for new text - _txt.destroy (); - } - else - { - const PrinterDef & def = get_description (_curprn); - TFilename fname (_printerfile); - - if (_printertype == normprinter) - fname = def._devicename; - _fp = fopen (fname, "w"); - - if (_fp == NULL) - return error_box ("Errore di apertura file stampa: '%s'", - (const char *) fname); - - TString code (def.get_codes (_curcode)); - if (code.not_empty ()) - { - const char *s = code; - fputs (esc ((char *) s), _fp); - } - } - - _currentrow = 1; - _currentpage = 1; - - return _isopen = TRUE; -} - -void TPrinter :: -set () -{ - TMask mask ("bagn001a.msk"); - TToken_string pn1 (50), pn2 (100); - int i; - - MainApp ()->disable_menu_item (M_FILE_PG_SETUP); -#if XVT_OS != XVT_OS_WIN - for (i = 0; i < _printers.items (); i++) - { - pn1.add (i); - pn2.add (((PrinterDef &) _printers[i])._printername); - } - ((TList_field &) (mask.field (MSK_1_PRINTERS))).replace_items (pn1, pn2); - mask.hide (MSK_1_SETUP); - mask.hide (MSK_1_SIZE); - mask.hide (MSK_1_LINES); - pn1 = ""; - pn2 = ""; - for (i = 0; i < ((PrinterDef &) _printers[_curprn])._names.items (); i++) - { - pn1.add (format ("%d", i)); - pn2.add ((TString &) ((PrinterDef &) _printers[_curprn])._names[i]); - } - ((TList_field &) (mask.field (MSK_1_CODES))).replace_items (pn1, pn2); - mask.set_handler (MSK_1_PRINTERS, printers_on_key); - if (_printertype == fileprinter) - mask.set (MSK_1_TYPE, "1"); - else if (_printertype == screenvis) - mask.set (MSK_1_TYPE, "2"); - else - mask.set (MSK_1_TYPE, "0"); - - mask.set (MSK_1_PRINTERS, format ("%d", _curprn)); - mask.set (MSK_1_CODES, format ("%d", _curcode)); - mask.set (MSK_1_FILENAME, _printerfile); - mask.reset (MSK_1_SAVE); - - if (mask.run () == K_ESC) - return; - - if (mask.get (MSK_1_SAVE).not_empty ()) - { - TString s ("printer.def"); -#if XVT_OS == XVT_OS_SCOUNIX - s << format (".%d", getuid ()); -#endif - mask.set_workfile (s); - mask.save (); - } - - // get user choices - - _curprn = atoi (mask.get (MSK_1_PRINTERS)); - PrinterDef & def = (PrinterDef &) get_description (_curprn); - switch (atoi (mask.get (MSK_1_TYPE))) - { - case 0: // stampante - - _printertype = normprinter; - _curcode = atoi (mask.get (MSK_1_CODES)); - switch (atoi (def._printertype)) - { - case 0: - _printertype = normprinter; - break; - case 1: - _printertype = localprinter; - break; - case 2: - _printertype = spoolprinter; - break; - } - break; - case 1: // file - - _printertype = fileprinter; - _printerfile = mask.get (MSK_1_FILENAME); - _curcode = atoi (mask.get (MSK_1_CODES)); - break; - case 2: // video - - _printertype = screenvis; - _curcode = 0; - break; - } - -#else - - static char defPrinter[80]; - static char szDevice[50]; - int defIndex; - - // get default printer driver - GetProfileString ("windows", "device", ",,,", defPrinter, sizeof (defPrinter)); - TString pdev (defPrinter); - GetProfileString ("devices", pdev, "", szDevice, sizeof (szDevice)); - pdev << "," << szDevice; - TToken_string dio (pdev, ','); - - // get printer names - _get_windows_printer_names (pn2); - // determine index of current default printer - for (i = 0; i < pn2.items (); i++) - { - if (TString (dio.get (0)) == TString (pn2.get (i))) - { - defIndex = i; - break; - } - } - if (defIndex == pn2.items ()) - defIndex = 0; // should never happen - - for (i = 0; i < pn2.items (); i++) - pn1.add (i); - - ((TList_field &) (mask.field (MSK_1_PRINTERS))).replace_items (pn1, pn2); - mask.set (MSK_1_PRINTERS, pn1.get (defIndex)); - mask.hide (MSK_1_CODES); - mask.set (MSK_1_ISGRAPHICS, _isgraphics ? "X" : ""); - mask.set (MSK_1_SIZE, format ("%d", _ch_size)); - mask.set (MSK_1_LINES, format ("%d", _lines_per_inch)); - - if (_printertype == fileprinter) - mask.set (MSK_1_TYPE, "1"); - else if (_printertype == screenvis) - mask.set (MSK_1_TYPE, "2"); - else - mask.set (MSK_1_TYPE, "0"); - - mask.set_handler (MSK_1_PRINTERS, set_windows_print_device); - mask.reset (MSK_1_SAVE); - - KEY k; - while ((k = mask.run ()) != K_ESC && k != K_ENTER) - { - if (k == MSK_1_SETUP) - { - if (_print_rcd != NULL) - { - if (page_setup_dlg (_print_rcd)) - { - // see if user has changed printer - int dIndex; - // determine index of currently selected printer - // ACTHUNG! Deep hacking of XVT internals! NON PORTABLE! - for (i = 0; i < pn2.items (); i++) - if (strcmp ((const char *) (_print_rcd + 4), pn2.get (i)) == 0) - { - dIndex = i; - break; - } - mask.set (MSK_1_PRINTERS, pn1.get (dIndex)); - set_win_formlen (); - } - mask.set_focus (); - } - else - beep (); - } - } - if (k == K_ESC) - { - // rimetti come prima - // WriteProfileString("windows","device", pdev); - if (_print_rcd != NULL) - free_print_rcd (_print_rcd); - _print_rcd = get_print_rcd (&_print_rcd_size); - set_win_formlen (); - return; - } - - if (mask.get (MSK_1_SAVE).not_empty ()) - { - TString s ("printer.def"); - mask.set_workfile (s); - mask.save (); - } - - switch (atoi (mask.get (MSK_1_TYPE))) - { - case 0: // stampante - - _printertype = winprinter; - break; - case 1: // file - - _printertype = fileprinter; - _printerfile = mask.get (MSK_1_FILENAME); - _curcode = atoi (mask.get (MSK_1_CODES)); - break; - case 2: // video - - _printertype = screenvis; - _curcode = 0; - break; - } - - _isgraphics = mask.get_bool (MSK_1_ISGRAPHICS); - _ch_size = atoi (mask.get (MSK_1_SIZE)); - _lines_per_inch = atoi (mask.get (MSK_1_LINES)); - set_win_formlen (); - -#endif - - MainApp ()->enable_menu_item (M_FILE_PG_SETUP); -} - -void TPrinter :: -close () -{ - if (isopen () && _currentrow > 1 && - (_footersize || (_printertype != screenvis && _printertype != winprinter))) - formfeed (); - - if (_fp) - { - fclose (_fp); - _fp = NULL; - } - - if (_printertype == screenvis) - { - CHECK (_vf, "VF!"); - _vf->close_print (); - _vf->run (); - if (_vf->is_open ()) - _vf->close_modal (); - delete _vf; - freeze (FALSE); - _vf = NULL; - } -#if XVT_OS == XVT_OS_WIN - else if (_printertype == winprinter) - { - PrintWhat._prcd = _print_rcd; - PrintWhat._txt = &_txt; - PrintWhat._graphics = _isgraphics; - PrintWhat._charsize = _ch_size; - start_print_thread (start_winprint, (long) (&PrintWhat)); - } -#endif - else if (_printertype == localprinter) - { -#if XVT_OS == XVT_OS_SCOUNIX - TFilename s1 = tmpnam (NULL); - switch (fork ()) - { - case -1: - break; - case 0: - execlp ("localprint", "localprint", (const char *) s1, NULL); - default: - wait ((int *) NULL); - } - remove (s1); -#endif - } - _isopen = FALSE; -} - -// -// TFile_printer -// - -#include - -#if XVT_OS == XVT_OS_DOS -#define FORMAT_COMMAND "FORMAT" -#else -#define FORMAT_COMMAND "dosformat -fq" -#endif - -const long disk_sizes[] = -{360000, 1200000, 720000, 1400000, 2880000}; - -TFile_printer ::TFile_printer (const char *ffile, const char *label, int len_rec, int num_rec_inizio, int num_rec_fine, int tipo_disco) -{ - set_printtype (fileprinter); - - _num_rec_testa_coda = num_rec_inizio + num_rec_fine; - _file = ffile; - _label = label; - _len_rec = len_rec; - _volume = 1; - _size = disk_sizes[tipo_disco]; - _num_rec_volume = int ((_size / len_rec) - _num_rec_testa_coda); - _nome_file_fissato = TRUE; - _formatta = FALSE; - _label_fissata = TRUE; - -} - -void TFile_printer :: -open () -{ -} - -void TFile_printer :: -close () -{ -} - -bool TFile_printer :: -genera_dischetti () -{ - int r; - - warning_box ("Questa procedura richiede %2d dischetti", - _volume); - - for (int i = 0; i < _tmp_files.items (); i++) - { - // Avvisa l'utente di inserire un dischetto - r = yesno_box ("Inserire il dischetto n. %2d di %2d nel drive %2s", - i + 1, _volume, _drive); - if (!r) - return error_box ("Procedura interrotta!"); - - // e eventualmente lo formatta - if (_formatta) - { - TString dep (30); - if (_label != NULL) - dep << FORMAT_COMMAND << " " << "/v:" << _label << " " << _drive; - else - dep << FORMAT_COMMAND << " " << _drive; - - TExternal_app sys (dep); - sys.run (); - } - - // copia il file sul dischetto - fcopy ((const char *) &_tmp_files[i], (const char *) _drive); - - } - return TRUE; -} - -TFile_printer ::~TFile_printer () -{ -} - -void TFile_printer :: -set () -{ - TMask m ("tfilepr"); - KEY tasto; - int f; - -// - // - // -------------------------------------------------------------------- - // Qui bisogna inserire la lista dei drive disponibili nella maschera - // Per ora tale lista e' fissa e contiene solo A: e B: - // -------------------------------------------------------------------- - // - // - - m.set (F_FILE_DESTINAZIONE, _file); - m.set (F_LABEL, _label); - - if (_nome_file_fissato) - m.disable (F_FILE_DESTINAZIONE); - - if (_label_fissata) - m.disable (F_LABEL); - - tasto = m.run (); - - if (tasto == K_ENTER) - { - f = atoi (m.get (F_FORMATO_DISCO)); - _drive = m.get (F_DRIVE); - _file = m.get (F_FILE_DESTINAZIONE); - _label = m.get (F_LABEL); - _formatta = (bool) (m.get (F_FORMATTA) == "X"); - _size = disk_sizes[f]; - _num_rec_volume = int ((_size / _len_rec) - _num_rec_testa_coda); - } -} - -// -// TFile printer fine -// -#include -#include - -#if XVT_OS==XVT_OS_SCOUNIX -#include -#include -#include -#else -#include -#endif - -#define STYLE_NUM 4 - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -struct PrDesc { - TTextfile* _txt; - PRINT_RCD* _prcd; - bool _graphics; - int _formlen; - int _charsize; - int _lines_per_inch; -} PrintWhat; - - -#define LINES_PER_INCH (6.0) - - -#if XVT_OS == XVT_OS_WIN - -#include - -void TPrinter::_get_windows_printer_names(TToken_string& t) -{ - char* buf = new char[4096]; // ammazzao' - GetProfileString("devices", NULL, "", buf, 4096); - - for(int i = 0; i < 4095; i++) - { - if (buf[i] == '\0' && buf[i+1] == '\0') - break; - if (buf[i] == '\0' && buf[i+1] != '\0') - buf[i] = '|'; - } - t = buf; - delete buf; -} - - -BOOLEAN TPrinter::start_winprint(long data) -{ - PrDesc* pd = (PrDesc*)data; - TTextfile& txt = *(pd->_txt); - TPrintwin pw(pd->_prcd, txt, pd->_charsize); - pw.print_background(pd->_graphics); - pw.do_print(); - return pw.aborted(); -} -#endif - - -// utils del caz -HIDDEN void read_int(const char* s, int& n, int& cnt) -{ - static char nbuf[10]; int j = 0; - while (!isdigit(s[cnt])) cnt++; - while (isdigit(s[cnt])) nbuf[j++] = s[cnt++]; - nbuf[j] = '\0'; n = atoi(nbuf); -} - - -#if XVT_OS == XVT_OS_WIN -void TPrinter::set_win_formlen() -{ - long pw, ph, phr, pvr; - xvt_escape(XVT_ESC_GET_PRINTER_INFO, _print_rcd, &ph, &pw, &pvr, &phr); - if (pvr != 0) - { - _formlen = (int)((ph/pvr)*_lines_per_inch); - _dots_per_line = (int)(pvr/_lines_per_inch); - _vert_offset = (int)(ph % (long)(_formlen * _dots_per_line)); - _horz_offset = 0; // not implemented (font dependent) - } - else warning_box("Il driver di stampante non e' valido. Non stampare prima di averlo" - " reinstallato"); -} -#endif - - -void TPrinter::_parse_background() -{ - char op; int x1, x2, y1, y2; - TToken_string tt(20); - TString txt(80); - TArray pix; char ch; int cnt = 0; - - while ((ch = _bg_desc[cnt++]) != '\0') - { - op = ch; tt = ""; char bf[2]; bf[1] = '\0'; - switch (op) - { - case ' ': // ignore whitespace - case '\t': - case '\n': - continue; - break; - case 'l': // line - case 'b': // box - case 'r': // round box - cnt++; read_int(_bg_desc,x1,cnt); read_int(_bg_desc,y1,cnt); - read_int(_bg_desc,x2,cnt); read_int(_bg_desc,y2,cnt); cnt++; - tt << op; tt.add(x1-1); tt.add(y1-1); tt.add(x2-1); tt.add(y2-1); - break; - case 't': // text - cnt++; - read_int(_bg_desc,x1,cnt); read_int(_bg_desc,y1,cnt); - cnt++; txt = ""; - while ((ch = _bg_desc[cnt++]) != '}') txt << ch; - tt << op; tt.add(x1-1); tt.add(y1-1); tt.add(txt); - break; - case 'P': // set pen style - case 'B': // set brush - case 'W': // set line width - case 'C': // set pen color - tt << op; bf[0] = _bg_desc[cnt++]; tt.add(bf); - break; - default: - yesnofatal_box("Unknown background opcode: %c", op); - break; - } - pix.add(tt); - } - - // now build row descriptions - - // colors are listed in printapp: - - char curcol = 'n'; - char curpen = 'n'; - char curpat = 'n'; - char curwid = '1'; - - for (int l = 0; l < _formlen; l++) - { - - TString* rwd = (TString*)_background.objptr(l); - if (rwd == NULL) - { - _background.add(rwd = new TString,l); - if (curcol != 'n') (*rwd) << 'C' << curcol; - if (curpat != 'n') (*rwd) << 'B' << curpat; - if (curwid != '1') (*rwd) << 'W' << curwid; - if (curpen != 'n') (*rwd) << 'P' << curcol; - } - for (int j = 0; j < pix.items(); j++) - { - TToken_string& tt = (TToken_string&)pix[j]; - tt.restart(); - - // la stringa contiene l'opcode piu' i parametri in binario, - // incrementati di 1 per evitare lo 0 - - switch(*(tt.get(0))) - { - case 'b': - x1 = tt.get_int(1)+1; y1 = tt.get_int(2)+1; - x2 = tt.get_int(3)+1; y2 = tt.get_int(4)+1; - if (y1 == l+1) // at ze biginnin - { - (*rwd) << 'u' << char(x1); - (*rwd) << 'r' << char(x1) << char(x2); - (*rwd) << 'u' << char(x2); - } - else if (y2 == l+1) // at ze end - { - (*rwd) << 'o' << char(x1); - (*rwd) << 'r' << char(x1) << char(x2); - (*rwd) << 'o' << char(x2); - } - else if (y1 < l+1 && y2 > l+1) // in ze middol - { - (*rwd) << 'v' << char(x1); - (*rwd) << 'v' << char(x2); - } - break; - case 'l': - x1 = tt.get_int(1)+1; y1 = tt.get_int(2)+1; - x2 = tt.get_int(3)+1; y2 = tt.get_int(4)+1; - if (y1 == y2 && y1 == l+1) // orizzontale - { - (*rwd) << 'h' << char(x1) << char(x2); - } - else if (y1 <= l+1 && y2 >= l+1) // verticale - { - (*rwd) << 'v' << char(x1); - } - break; - case 't': - x1 = tt.get_int(1)+1; y1 = tt.get_int(2)+1; // al gh'e' - if (y1 == l+1) - {} - break; - case 'W': - curwid = *(tt.get(1)); - (*rwd) << 'W' << curwid; - break; - case 'P': - curpen = *(tt.get(1)); - (*rwd) << 'P' << curpen; - break; - case 'B': - curpat = *(tt.get(1)); - (*rwd) << 'B' << curpat; - break; - case 'C': - curcol = *(tt.get(1)); - (*rwd) << 'C' << curcol; - break; - } - } - } -} - -void TPrinter::setbackground(const char* b) -{ - _background.destroy(); - _bg_desc = b; - if (b != NULL) _parse_background(); -} - - -bool printers_on_key (TMask_field& f, KEY key); - -// fv support structs for config - -bool PrinterDef::read(const char* name, FILE* fd) -{ - _printername = name; - _printername.trim(); - - TToken_string tmp(64, '='); - TString l(48); - TString r(16); - - while(TRUE) - { - const long p = ftell(fd); // Memorizza inizio paragrafo - - if (fgets(__tmp_string,256,fd) == NULL) - return FALSE; - tmp = __tmp_string; tmp.trim(); - - if (tmp == "[End of File]") - return FALSE; - - if (tmp[0] == '[') - { - fseek(fd,p,SEEK_SET); // Ritorna ad inizio paragrafo - break; - } - - l = tmp.get(); l.trim(); - r = tmp.get(); r.trim(); - - if (l == "Device name") { _devicename = r; } else - if (l == "Filter name") { _filtername = r; } else - if (l == "Printer type"){ _printertype = r; } else - if (l == "Normal") { strcpy(_atstr[normalstyle], r); } else - if (l == "Bold") { strcpy(_atstr[boldstyle], r); } else - if (l == "Italic") { strcpy(_atstr[italicstyle], r); } else - if (l == "Underlined") { strcpy(_atstr[underlinedstyle], r); } else - if (l == "Code") { TToken_string code(r); _names.add(TString( code.get())); - _codes.add(TString(code.get())); } else - if (l == "Form feed") { _ffcode = r; } else - if (l == "Newline") { _nlcode = r; } else - return error_box("Riga di configurazione stampante errata:\n%s", (const char*)l); - } - return TRUE; -} - -bool PrinterDef::isdefault() -{ - return strcmp(_printername,"Default") == 0; -} - -////////// TPRINTROW ////////// - -TPrintrow::TPrintrow () -{ - reset(); -} - -TPrintrow::TPrintrow(const TPrintrow& pr) -{ - _row = pr.row(); - memcpy(_attr, pr._attr,MAXSTR); - memcpy(_cols, pr._cols,MAXSTR); - _currentcolor = 'w'; _currentcolor <<= 8; _currentcolor += 'n'; - _currentstyle = pr._currentstyle; - for (int i = 0; i < MAXSTR; i++) _cols[i] = _currentcolor; - _lastpos = pr._lastpos; -} - -TObject* TPrintrow::dup() const -{ - return new TPrintrow(*this); -} - -const char* TPrintrow::class_name() const -{ - return "Printrow"; -} - -word TPrintrow::class_id() const -{ - return CLASS_PRINTROW; -} - - -TPrintrow& TPrintrow::reset() -{ - _row.spaces(sizeof(_attr)); - _currentcolor = 'w'; _currentcolor <<= 8; _currentcolor += 'n'; - memset(_attr, normalstyle, sizeof(_attr)); - for (int i = 0; i < MAXSTR; i++) _cols[i] = _currentcolor; - _lastpos = 0; - _currentstyle = normalstyle; - return *this; -} - -const char* TPrintrow::row_codified() -{ - // returns the row with @-codes for font style and color - char last_attr = -1; int last_color = -1; - int k = 0; - _row.rtrim(); - for(int i = 0; i < _row.len(); i++) - { - if (_attr[i] != last_attr) - { - __tmp_string[k++] = '@'; - switch(_attr[i]) - { - case normalstyle: __tmp_string[k++] = 'r'; break; - case boldstyle: __tmp_string[k++] = 'b'; break; - case italicstyle: __tmp_string[k++] = 'i'; break; - case underlinedstyle: __tmp_string[k++] = 'u'; break; - } - last_attr = _attr[i]; - } - if (_cols[i] != last_color) - { - __tmp_string[k++] = '$'; - __tmp_string[k++] = '['; - __tmp_string[k++] = (char)(_cols[i] & 0x00ff); - __tmp_string[k++] = ','; - __tmp_string[k++] = (char)(_cols[i] >> 8); - __tmp_string[k++] = ']'; - last_color = _cols[i]; - } - __tmp_string[k++] = _row[i]; - } - // k = k > 255 ? 255 : k; - __tmp_string[k] = '\0'; - return __tmp_string; -} - - -TPrintrow& TPrintrow::put (const char* str, int position, int len) -{ - if (len < 1) - len = strlen(str); - - if (position < 0) - position = _lastpos; - - char bg = 'w', fg = 'n'; - for (int i = 0; i < len; i++) - { - char c = str[i]; - if (c == '$' && str[i+1] == '[') - { - ++i; - fg = str[++i]; - c = str[++i]; - if (c == ']') - bg = _currentcolor >> 8; - else if (c == ',') - { bg = str[++i]; i++; } - else { CHECK(0,"Error in color specification"); } - _currentcolor = (bg << 8) + fg; - } - else if (c == '@') - { - c = str[++i]; - switch (toupper(c)) - { - case '#': - case '<': - case '>': - // printer MUST handle them - { - const int n = (c == '#') ? 5 : ((c == '>') ? 10 : 8); - _row[position] = '@'; _attr[position++] = _currentstyle; - for (int j = 1; j < n; j++) - { - _row[position] = c; - _attr[position++] = _currentstyle; - } - } - break; - case 'B': - _currentstyle = boldstyle; - break; - case 'I': - _currentstyle = italicstyle; - break; - case 'U': - _currentstyle = underlinedstyle; - break; - case 'R': - _currentstyle = normalstyle; - break; - default: - // should be number followed by skip or jump - if (isdigit(c)) - { - // read number - char digbuf[8]; int cnt = 0; - digbuf[cnt++] = c; - while (isdigit(c = str[++i])) - digbuf[cnt++] = c; - digbuf[cnt] = '\0'; - int pp = atoi(digbuf); - if (toupper(c) == 'G') - { - if (pp >= MAXSTR) - fatal_box("printrow reaches position %d",pp); - if (pp > position) - for (int k = position; k < pp; k++) - { - _attr[k] = _currentstyle; - _cols[k] = _currentcolor; - } - position = pp; - } - else if (toupper(c) == 'J') - { - if (pp+position >= MAXSTR) - fatal_box("printrow reaches position %d", pp+position); - for (int k = 0; k < pp; k++) - { - _attr[k+position] = _currentstyle; - _cols[k+position] = _currentcolor; - } - position += pp; - } - } - else - { - _row[position] = c; - _attr[position++] = _currentstyle; - _cols[position++] = _currentcolor; - } - } // switch - } - else - { - _row[position] = c; - _attr[position] = _currentstyle; - _cols[position++] = _currentcolor; - } - } // for - - _lastpos = position; - return *this; -} - -////////// TPRINTER ////////// - -bool printers_on_key (TMask_field& f, KEY key) -{ - if (key==K_SPACE) - { - TToken_string pn1(10), pn2(20); - - const PrinterDef& def = MainApp()->printer().get_description(atoi(f.get())); - const char* s; - int j = 0; - while ((s = def.get_codenames(j)) != NULL) - { - pn1.add(format("%02d", j)); - pn2.add(s); - j++; - } - ((TList_field&) f.mask().field(MSK_1_CODES)).replace_items(pn1, pn2); - } - return TRUE; -} - - -#if XVT_OS == XVT_OS_WIN - -bool set_windows_print_device(TMask_field& f, KEY key) -{ - static char szDevice[80]; - if (key == K_SPACE) - { - if (MainApp()->printer().get_printrcd() != NULL) - free_print_rcd(MainApp()->printer().get_printrcd()); - TToken_string& pn = MainApp()->printer().getprinternames(); - TString pdev(pn.get(atoi(f.get()))); - GetProfileString("devices", pdev, "", szDevice, sizeof(szDevice)); - pdev << "," << szDevice; -// WriteProfileString("windows","device", pdev); - // madonna bona - MainApp()->printer().set_printrcd(get_print_rcd(&(MainApp()->printer().get_printrcdsize()))); - MainApp()->printer().set_win_formlen(); - } - return TRUE; -} - -#endif - -TPrinter::TPrinter() : _date(TODAY), _multiple_link(FALSE), _frozen(FALSE), _isgraphics(TRUE), - _lines_per_inch(6), _ch_size(12) - -{ - _footerhandler = _headerhandler = NULL; - _linkhandler = NULL; - _config = "printer.ini"; - _curprn = 0; // first in list if no default is specified - _curcode = 0; // first in list if no default is specified - _formlen = 66; - _frompage = 0; - _topage = 0xffff; - _hwformfeed = FALSE; - _currentpage = 1; - _currentrow = 1; - _fp = NULL; - _headersize = 0; - _footersize = 0; - _isopen = FALSE; - // read configuration file - read_configuration(_config); -#if XVT_OS == XVT_OS_WIN - print_begin(); - _print_rcd = get_print_rcd(&_print_rcd_size); - set_win_formlen(); -#else - _isgraphics = FALSE; -#endif -} - - -TToken_string& TPrinter::getprinternames() -{ -// per ora va solo in windows -#if XVT_OS == XVT_OS_WIN - _get_windows_printer_names(_printer_names); -#endif - return _printer_names; -} - -void TPrinter::read_configuration(const char* conf) -{ - - FILE* cnfp=fopen(conf, "r"); - if (cnfp == NULL) - fatal_box("Impossibile aprire il file %s", (const char*) _config); - - for (int i = 0; !feof(cnfp); i++) - { - if (fgets(__tmp_string,256,cnfp) == NULL) return; - // else - if (strncmp(__tmp_string, "[Default]",9) != 0) - // fgets(__tmp_string,256,cnfp); - // else - { - if (*__tmp_string == '[') - { - // fatal_box("[ expected in file of printer configuration"); - - char* u = strchr(__tmp_string, ']'); - if (u) *u = '\0'; - u = __tmp_string+1; - - PrinterDef* pp = new PrinterDef; - _printers.add(pp); - if (pp->read(u, cnfp) == FALSE) - break; - } - } - } - fclose(cnfp); - - TString s("printer.def"); -#if XVT_OS == XVT_OS_SCOUNIX - s << format(".%d", getuid()); -#endif - if (fexist(s)) - { - TScanner sc(s); - TToken_string t(sc.line()); - int where_print = t.get_int(1); - t = sc.line(); - _curprn = t.get_int(1); - t = sc.line(); - _printerfile = t.get(1); - t = sc.line(); - _curcode = t.get_int(1); -#if XVT_OS != XVT_OS_WIN - PrinterDef& def = (PrinterDef&)get_description(_curprn); -#endif - switch (where_print) - { - case 0: // stampante -#if XVT_OS == XVT_OS_WIN - _printertype = winprinter; -#else - switch (atoi(def._printertype)) - { - case 0: - _printertype = normprinter; - break; - case 1: - _printertype = localprinter; - break; - case 2: - _printertype = spoolprinter; - break; - } -#endif - break; - case 1: // file - _printertype = fileprinter; - break; - case 2: // video - _printertype = screenvis; - _curcode = 0; - break; - } - } -} - -TPrinter::~TPrinter() -{ -#if XVT_OS == XVT_OS_WIN - print_end(); -#endif -} - -const char* TPrinter::class_name() const -{ - return "Printer"; -} - -word TPrinter::class_id() const -{ - return CLASS_PRINTER; -} - -TPrintrow* TPrinter::getheaderline (int linetoget) -{ - return((TPrintrow*)_header.objptr(linetoget)); -} - -TPrintrow* TPrinter::getfooterline (int linetoget) -{ - return((TPrintrow*)_footer.objptr(linetoget)); -} - -void TPrinter::setheaderline (int linetoset, TPrintrow* line) -{ - _header.add(line, linetoset); - if (linetoset >= _headersize) _headersize = linetoset+1; -} - -void TPrinter::setheaderline (int linetoset, const TPrintrow& line) -{ - TPrintrow* p = new TPrintrow(line); - setheaderline(linetoset, p); -} - -void TPrinter::setfooterline (int linetoset, TPrintrow* line) -{ - _footer.add(line,linetoset); - // if (linetoset >= _footersize) _footersize = linetoset+1; -} - -void TPrinter::setfooterline (int linetoset, const TPrintrow& line) -{ - TPrintrow* p = new TPrintrow(line); - setfooterline(linetoset, p); -} - -void TPrinter::resetheader() -{ - _header.destroy(); - _headersize = 0; -} - -void TPrinter::resetfooter() -{ - _footer.destroy(); - // _footersize = 0; -} - -bool TPrinter::printrow(TPrintrow* rowtoprint) -{ - if (!isopen()) return FALSE; - - if (_currentpage < _frompage || _currentpage > _topage) - return TRUE; - - - TString rw(rowtoprint == NULL ? "" : (_printertype == screenvis || _printertype == winprinter ? - rowtoprint->row_codified() : - rowtoprint->row())); - rw.rtrim(); - - int lun = rw.len(); - int idx; - - for (idx = 0; idx < lun; idx++) - { - if (rw[idx] == '@') // gestione data e n. di pagina - { - switch(rw[idx+1]) - { - case '#': rw.overwrite(format("%-5u", _currentpage), idx++); break; - case '>': rw.overwrite(_date.string(4), idx++); break; - case '<': rw.overwrite(_date.string(2), idx++); break; - default : break; - } - } - } - - if (_printertype == screenvis) - { - if (!_vf->frozen()) _vf->add_line(rw); - else _frozen = TRUE; - return TRUE; - } - - if (_printertype == winprinter) - { - // add line to txt - if (!_frozen) _txt.append(rw); - return TRUE; - } - - const PrinterDef& pd = get_description(_curprn); - int prvstl = -1; - for (idx = 0; idx < lun; idx++) - { - int cst=rowtoprint->get_style(idx); - if (cst!=prvstl) - { - fprintf(_fp,"%s", pd._atstr[normalstyle]); - if (cst != normalstyle) - fprintf(_fp,"%s", pd._atstr[cst]); - } - prvstl=cst; - putc(rw[idx], _fp); - } - if (newline()) - putc(newline(), _fp); - - return TRUE; -} - -word TPrinter::rows_left() const -{ - word left = _formlen-_currentrow-_footersize+1; - if (_currentrow < 2) left -= _headersize; - return left; -} - -bool TPrinter::print(TPrintrow& rowtoprint) -{ - bool ok = TRUE; - - if (_currentrow > _formlen-_footersize) - ok = printfooter(); - -// if (ok && _currentrow <= _headersize) - if (ok && _currentrow == 1) - ok = printheader(); - - if (ok) - { - ok = printrow(&rowtoprint); - _currentrow++; - } - - return ok; -} - - -bool TPrinter::printheader () -{ - if (_headerhandler) _headerhandler(*this); - - bool ok = TRUE; - for(int i = 0; i < _headersize && ok; i++) - ok = printrow(getheaderline(i)); - - _currentrow = _headersize+1; - return ok; -} - -bool TPrinter::printfooter () -{ - if (_footerhandler) _footerhandler(*this); - - bool ok = TRUE; - for(int i = 0; i < _footersize && ok; i++) - ok = printrow(getfooterline(i)); - -#if XVT_OS != XVT_OS_WIN - if (ok) printformfeed(); -#endif - - _currentrow = 1; - _currentpage++; - - return ok; -} - -bool TPrinter::skip (int linestoskip) -{ - int jumpline; - - CHECK(linestoskip>=0, "Linestoskip can't be negative"); - jumpline=_currentrow+linestoskip; - return jump(jumpline); -} - -bool TPrinter::jump (int jumpline) -{ - int i=0; - bool ok=TRUE; - - CHECK(jumpline>=0, "Jumpline can't be negative"); - if (jumpline>_formlen-_footersize) ok=formfeed(); - else for(i=_currentrow;i_formlen-_footersize) ok=FALSE; - return ok; -} - -bool TPrinter::formfeed () -{ - const int lastrow = _formlen-_footersize; - for (;_currentrow <= lastrow; _currentrow++) - printrow(); - return printfooter(); -} - -void TPrinter::reset () -{ - resetheader(); - resetfooter(); - _currentpage=1; - _currentrow=1; -} - -bool TPrinter::printformfeed () -{ -#if XVT_OS != XVT_OS_WIN - const PrinterDef& pd = get_description(_curprn); - - if (_printertype != screenvis && _hwformfeed) - fprintf(_fp,"%s",(const char*)pd._ffcode); -#endif - return TRUE; -} - -bool TPrinter::open () -{ -// qui -#if XVT_OS==XVT_OS_SCOUNIX - if (_printertype==spoolprinter) - { - const PrinterDef& def = get_description(_curprn); - int pfd[2]; - - if (pipe(pfd) == -1) - return error_box("Impossibile creare processo di stampa ""(pipe)"); - - int ret = fork(); - if (ret == -1) - return error_box("Impossibile creare processo di stampa ""(fork)"); - - if (ret == 0) - { - if ((::close(0) != -1) && (::dup(pfd[0]) == 0) && - (::close(pfd[0]) == 0) && (::close(pfd[1]) != -1)) - { - char s0[80]; - - sprintf(s0, "-d%s", (const char*) def._devicename); - if ((def._filtername).not_empty()) - { - char s1[80]; - sprintf(s1, "-o %s", (const char*) def._filtername); - char *ws[5] = { "lpr", "-s", s0, s1, NULL}; - execvp(ws[0], ws); - } - else - { - char *ws[4] = { "lpr", "-s", s0, NULL}; - execvp(ws[0], ws); - } - exit(-1); - } - } - if ((::close(pfd[0])==-1) || ((_fp=fdopen(pfd[1],"w"))==NULL)) - return error_box("Impossibile creare processo di stampa""(close)"); - } - else -#endif - if (_printertype == screenvis) - { - _vf = new TViswin(NULL, "Anteprima di stampa", TRUE, TRUE, - _linksdescr.items() > 0); - _vf->open_modal(); - } - else if (_printertype == winprinter) - { - // prepare text object for new text - _txt.destroy(); - } - else - { - const PrinterDef& def = get_description(_curprn); - TFilename fname(_printerfile); - - if (_printertype == normprinter) fname = def._devicename; - _fp = fopen(fname, "w"); - - if (_fp == NULL) - return error_box("Errore di apertura file stampa: '%s'", - (const char*)fname); - - TString code(def.get_codes(_curcode)); - if (code.not_empty()) - { - const char* s = code; - fputs(esc((char*)s), _fp); - } - } - - _currentrow = 1; - _currentpage = 1; - - return _isopen = TRUE; -} - -void TPrinter::set() -{ - TMask mask("bagn001a.msk"); - TToken_string pn1(50), pn2(100); - int i; - - MainApp()->disable_menu_item(M_FILE_PG_SETUP); -#if XVT_OS != XVT_OS_WIN - for (i = 0; i < _printers.items(); i++) - { - pn1.add(i); - pn2.add(((PrinterDef&) _printers[i])._printername); - } - ((TList_field&)(mask.field(MSK_1_PRINTERS))).replace_items(pn1, pn2); - mask.hide(MSK_1_SETUP); - mask.hide(MSK_1_SIZE); - mask.hide(MSK_1_LINES); - pn1 = ""; - pn2 = ""; - for (i = 0; i < ((PrinterDef&)_printers[_curprn])._names.items(); i++ ) - { - pn1.add(format("%d", i)); - pn2.add((TString&)((PrinterDef&) _printers[_curprn])._names[i]); - } - ((TList_field&)(mask.field(MSK_1_CODES))).replace_items(pn1, pn2); - mask.set_handler(MSK_1_PRINTERS, printers_on_key); - if (_printertype == fileprinter) - mask.set(MSK_1_TYPE, "1"); - else - if (_printertype == screenvis) - mask.set(MSK_1_TYPE, "2"); - else - mask.set(MSK_1_TYPE, "0"); - - mask.set(MSK_1_PRINTERS, format("%d",_curprn)); - mask.set(MSK_1_CODES, format("%d",_curcode)); - mask.set(MSK_1_FILENAME, _printerfile); - mask.reset(MSK_1_SAVE); - - if (mask.run() == K_ESC) - { - MainApp()->enable_menu_item(M_FILE_PG_SETUP); - return; - } - if (mask.get(MSK_1_SAVE).not_empty()) - { - TString s("printer.def"); -#if XVT_OS == XVT_OS_SCOUNIX - s << format(".%d", getuid()); -#endif - mask.set_workfile(s); - mask.save(); - } - - - // get user choices - - _curprn = atoi(mask.get(MSK_1_PRINTERS)); - PrinterDef& def = (PrinterDef&)get_description(_curprn); - switch (atoi(mask.get(MSK_1_TYPE))) - { - case 0: // stampante - _printertype = normprinter; - _curcode = atoi(mask.get(MSK_1_CODES)); - switch (atoi(def._printertype)) - { - case 0: - _printertype = normprinter; - break; - case 1: - _printertype = localprinter; - break; - case 2: - _printertype = spoolprinter; - break; - } - break; - case 1: // file - _printertype = fileprinter; - _printerfile = mask.get(MSK_1_FILENAME); - _curcode = atoi(mask.get(MSK_1_CODES)); - break; - case 2: // video - _printertype = screenvis; - _curcode = 0; - break; - } - -#else - - static char defPrinter[80]; - static char szDevice[50]; - int defIndex; - - // get default printer driver - GetProfileString("windows","device",",,,",defPrinter, sizeof(defPrinter)); - TString pdev(defPrinter); - GetProfileString("devices", pdev, "", szDevice, sizeof(szDevice)); - pdev << "," << szDevice; - TToken_string dio(pdev, ','); - - // get printer names - _get_windows_printer_names(pn2); - // determine index of current default printer - for (i = 0; i < pn2.items(); i++) - { - if (TString(dio.get(0)) == TString(pn2.get(i))) - { - defIndex = i; - break; - } - } - if (defIndex == pn2.items()) defIndex = 0; // should never happen - - for (i = 0; i < pn2.items(); i++) pn1.add(i); - - ((TList_field&)(mask.field(MSK_1_PRINTERS))).replace_items(pn1, pn2); - mask.set(MSK_1_PRINTERS, pn1.get(defIndex)); - mask.hide(MSK_1_CODES); - mask.set(MSK_1_ISGRAPHICS, _isgraphics ? "X" : ""); - mask.set(MSK_1_SIZE, format("%d",_ch_size)); - mask.set(MSK_1_LINES, format("%d",_lines_per_inch)); - - if (_printertype == fileprinter) - mask.set(MSK_1_TYPE,"1"); - else - if (_printertype == screenvis) - mask.set(MSK_1_TYPE, "2"); - else - mask.set(MSK_1_TYPE, "0"); - - mask.set_handler(MSK_1_PRINTERS, set_windows_print_device); - mask.reset(MSK_1_SAVE); - - KEY k; - while ((k = mask.run()) != K_ESC && k != K_ENTER) - { - if (k == MSK_1_SETUP) - { - if (_print_rcd != NULL) - { - if (page_setup_dlg(_print_rcd)) - { - // see if user has changed printer - int dIndex; - // determine index of currently selected printer - // ACTHUNG! Deep hacking of XVT internals! NON PORTABLE! - for (i = 0; i < pn2.items(); i++) - if (strcmp((const char*)(_print_rcd+4), pn2.get(i)) == 0) - { - dIndex = i; - break; - } - mask.set(MSK_1_PRINTERS, pn1.get(dIndex)); - set_win_formlen(); - } - mask.set_focus(); - } - else beep(); - } - } - if (k == K_ESC) - { - // rimetti come prima - // WriteProfileString("windows","device", pdev); - if (_print_rcd != NULL) free_print_rcd(_print_rcd); - _print_rcd = get_print_rcd(&_print_rcd_size); - set_win_formlen(); - MainApp()->enable_menu_item(M_FILE_PG_SETUP); - return; - } - - if (mask.get(MSK_1_SAVE).not_empty()) - { - TString s("printer.def"); - mask.set_workfile(s); - mask.save(); - } - - switch (atoi(mask.get(MSK_1_TYPE))) - { - case 0: // stampante - _printertype = winprinter; - break; - case 1: // file - _printertype = fileprinter; - _printerfile = mask.get(MSK_1_FILENAME); - _curcode = atoi(mask.get(MSK_1_CODES)); - break; - case 2: // video - _printertype = screenvis; - _curcode = 0; - break; - } - - _isgraphics = mask.get_bool(MSK_1_ISGRAPHICS); - _ch_size = atoi(mask.get(MSK_1_SIZE)); - _lines_per_inch = atoi(mask.get(MSK_1_LINES)); - set_win_formlen(); - -#endif - - MainApp()->enable_menu_item(M_FILE_PG_SETUP); -} - - -void TPrinter::close () -{ - if (isopen() && _currentrow > 1 && - (_footersize || (_printertype != screenvis && _printertype != winprinter))) - formfeed(); - - if (_fp) - { - fclose(_fp); - _fp = NULL; - } - - if (_printertype == screenvis) - { - CHECK(_vf, "VF!"); - _vf->close_print(); - _vf->run(); - if (_vf->is_open()) _vf->close_modal(); - delete _vf; - _vf = NULL; - } -#if XVT_OS == XVT_OS_WIN - else if (_printertype == winprinter) - { - PrintWhat._prcd = _print_rcd; - PrintWhat._txt = &_txt; - PrintWhat._graphics = _isgraphics; - PrintWhat._charsize = _ch_size; - start_print_thread(start_winprint, (long)(&PrintWhat)); - } -#endif - else - - if (_printertype == localprinter) - { -#if XVT_OS == XVT_OS_SCOUNIX - TFilename s1 = tmpnam(NULL); - switch (fork()) - { - case -1: - break; - case 0: - execlp("localprint", "localprint", (const char*)s1, NULL); - default: - wait ((int*)NULL); - } - remove(s1); -#endif - } - _isopen = FALSE; -} - -// -// TFile_printer -// - -#include - -#if XVT_OS == XVT_OS_DOS -#define FORMAT_COMMAND "FORMAT" -#else -#define FORMAT_COMMAND "dosformat -fq" -#endif - -const long disk_sizes [] = { 360000, 1200000, 720000, 1400000, 2880000 }; - - -TFile_printer::TFile_printer (const char* ffile, const char * label, int len_rec, int num_rec_inizio, int num_rec_fine, int tipo_disco) -{ - set_printtype (fileprinter); - - _num_rec_testa_coda = num_rec_inizio + num_rec_fine; - _file = ffile; - _label = label; - _len_rec = len_rec; - _volume = 1; - _size = disk_sizes [tipo_disco]; - _num_rec_volume = int((_size / len_rec) - _num_rec_testa_coda); - _nome_file_fissato = TRUE; - _formatta = FALSE; - _label_fissata = TRUE; - -} - -void TFile_printer::open() -{ -} - -void TFile_printer::close() -{ -} - -bool TFile_printer::genera_dischetti() -{ - int r; - - warning_box ("Questa procedura richiede %2d dischetti", - _volume); - - for (int i = 0; i < _tmp_files.items(); i++) - { - // Avvisa l'utente di inserire un dischetto - r = yesno_box ("Inserire il dischetto n. %2d di %2d nel drive %2s", - i+1, _volume, _drive ); - if (!r) - return error_box ("Procedura interrotta!"); - - // e eventualmente lo formatta - if (_formatta) - { - TString dep (30); - if (_label != NULL) - dep << FORMAT_COMMAND << " " << "/v:" << _label << " " << _drive; - else - dep << FORMAT_COMMAND << " " << _drive; - - TExternal_app sys(dep); - sys.run(); - } - - // copia il file sul dischetto - fcopy ((const char *)&_tmp_files[i], (const char *)_drive); - - } - return TRUE; -} - -TFile_printer::~TFile_printer () -{ -} - -void TFile_printer::set() -{ - TMask m ("tfilepr"); - KEY tasto; - int f; - -// -// -// -------------------------------------------------------------------- -// Qui bisogna inserire la lista dei drive disponibili nella maschera -// Per ora tale lista e' fissa e contiene solo A: e B: -// -------------------------------------------------------------------- -// -// - - m.set (F_FILE_DESTINAZIONE, _file); - m.set (F_LABEL, _label); - - if (_nome_file_fissato) - m.disable (F_FILE_DESTINAZIONE); - - if (_label_fissata) - m.disable (F_LABEL); - - tasto = m.run(); - - if (tasto == K_ENTER) - { - f = atoi (m.get (F_FORMATO_DISCO)); - _drive = m.get (F_DRIVE); - _file = m.get (F_FILE_DESTINAZIONE); - _label = m.get (F_LABEL); - _formatta = (bool) (m.get (F_FORMATTA) == "X"); - _size = disk_sizes [f]; - _num_rec_volume = int((_size / _len_rec) - _num_rec_testa_coda); - } -} - -// -// TFile printer fine -// ->>>>>>> 1.2 +#include +#include + +#if XVT_OS==XVT_OS_SCOUNIX +#include +#include +#include +#else +#include +#endif + +#define STYLE_NUM 4 + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +struct PrDesc + { + TTextfile *_txt; + PRINT_RCD *_prcd; + bool _graphics; + int _formlen; + int _charsize; + int _lines_per_inch; + } +PrintWhat; + +#define LINES_PER_INCH (6.0) + +#if XVT_OS == XVT_OS_WIN + +#include + +void TPrinter :: +_get_windows_printer_names (TToken_string & t) +{ + char *buf = new char[4096]; // ammazzao' + + GetProfileString ("devices", NULL, "", buf, 4096); + + for (int i = 0; i < 4095; i++) + { + if (buf[i] == '\0' && buf[i + 1] == '\0') + break; + if (buf[i] == '\0' && buf[i + 1] != '\0') + buf[i] = '|'; + } + t = buf; + delete buf; +} + +BOOLEAN TPrinter :: +start_winprint (long data) +{ + PrDesc *pd = (PrDesc *) data; + TTextfile & txt = *(pd->_txt); + TPrintwin pw (pd->_prcd, txt, pd->_charsize); + pw.print_background (pd->_graphics); + pw.do_print (); + return pw.aborted (); +} +#endif + +// utils del caz +HIDDEN void +read_int (const char *s, int &n, int &cnt) +{ + static char nbuf[10]; + int j = 0; + while (!isdigit (s[cnt])) + cnt++; + while (isdigit (s[cnt])) + nbuf[j++] = s[cnt++]; + nbuf[j] = '\0'; + n = atoi (nbuf); +} + +#if XVT_OS == XVT_OS_WIN +void TPrinter :: +set_win_formlen () +{ + long pw, ph, phr, pvr; + xvt_escape (XVT_ESC_GET_PRINTER_INFO, _print_rcd, &ph, &pw, &pvr, &phr); + if (pvr != 0) + { + _formlen = (int) ((ph / pvr) * _lines_per_inch); + _dots_per_line = (int) (pvr / _lines_per_inch); + _vert_offset = (int) (ph % (long) (_formlen * _dots_per_line)); + _horz_offset = 0; // not implemented (font dependent) + + } + else + warning_box ("Il driver di stampante non e' valido. Non stampare prima di averlo" + " reinstallato"); +} +#endif + +void TPrinter :: +_parse_background () +{ + char op; + int x1, x2, y1, y2; + TToken_string tt (20); + TString txt (80); + TArray pix; + char ch; + int cnt = 0; + + while ((ch = _bg_desc[cnt++]) != '\0') + { + op = ch; + tt = ""; + char bf[2]; + bf[1] = '\0'; + switch (op) + { + case ' ': // ignore whitespace + + case '\t': + case '\n': + continue; + break; + case 'l': // line + + case 'b': // box + + case 'r': // round box + + cnt++; + read_int (_bg_desc, x1, cnt); + read_int (_bg_desc, y1, cnt); + read_int (_bg_desc, x2, cnt); + read_int (_bg_desc, y2, cnt); + cnt++; + tt << op; + tt.add (x1 - 1); + tt.add (y1 - 1); + tt.add (x2 - 1); + tt.add (y2 - 1); + break; + case 't': // text + + cnt++; + read_int (_bg_desc, x1, cnt); + read_int (_bg_desc, y1, cnt); + cnt++; + txt = ""; + while ((ch = _bg_desc[cnt++]) != '}') + txt << ch; + tt << op; + tt.add (x1 - 1); + tt.add (y1 - 1); + tt.add (txt); + break; + case 'P': // set pen style + + case 'B': // set brush + + case 'W': // set line width + + case 'C': // set pen color + + tt << op; + bf[0] = _bg_desc[cnt++]; + tt.add (bf); + break; + default: + yesnofatal_box ("Unknown background opcode: %c", op); + break; + } + pix.add (tt); + } + + // now build row descriptions + + // colors are listed in printapp: + + char curcol = 'n'; + char curpen = 'n'; + char curpat = 'n'; + char curwid = '1'; + + for (int l = 0; l < _formlen; l++) + { + + TString *rwd = (TString *) _background.objptr (l); + if (rwd == NULL) + { + _background.add (rwd = new TString, l); + if (curcol != 'n') + (*rwd) << 'C' << curcol; + if (curpat != 'n') + (*rwd) << 'B' << curpat; + if (curwid != '1') + (*rwd) << 'W' << curwid; + if (curpen != 'n') + (*rwd) << 'P' << curcol; + } + for (int j = 0; j < pix.items (); j++) + { + TToken_string & tt = (TToken_string &) pix[j]; + tt.restart (); + + // la stringa contiene l'opcode piu' i parametri in binario, + // incrementati di 1 per evitare lo 0 + + switch (*(tt.get (0))) + { + case 'b': + x1 = tt.get_int (1) + 1; + y1 = tt.get_int (2) + 1; + x2 = tt.get_int (3) + 1; + y2 = tt.get_int (4) + 1; + if (y1 == l + 1) // at ze biginnin + + { + (*rwd) << 'u' << char (x1); + (*rwd) << 'r' << char (x1) << char (x2); + (*rwd) << 'u' << char (x2); + } + else if (y2 == l + 1) // at ze end + + { + (*rwd) << 'o' << char (x1); + (*rwd) << 'r' << char (x1) << char (x2); + (*rwd) << 'o' << char (x2); + } + else if (y1 < l + 1 && y2 > l + 1) // in ze middol + + { + (*rwd) << 'v' << char (x1); + (*rwd) << 'v' << char (x2); + } + break; + case 'l': + x1 = tt.get_int (1) + 1; + y1 = tt.get_int (2) + 1; + x2 = tt.get_int (3) + 1; + y2 = tt.get_int (4) + 1; + if (y1 == y2 && y1 == l + 1) // orizzontale + + { + (*rwd) << 'h' << char (x1) << char (x2); + } + else if (y1 <= l + 1 && y2 >= l + 1) // verticale + + { + (*rwd) << 'v' << char (x1); + } + break; + case 't': + x1 = tt.get_int (1) + 1; + y1 = tt.get_int (2) + 1; // al gh'e' + + if (y1 == l + 1) + { + } + break; + case 'W': + curwid = *(tt.get (1)); + (*rwd) << 'W' << curwid; + break; + case 'P': + curpen = *(tt.get (1)); + (*rwd) << 'P' << curpen; + break; + case 'B': + curpat = *(tt.get (1)); + (*rwd) << 'B' << curpat; + break; + case 'C': + curcol = *(tt.get (1)); + (*rwd) << 'C' << curcol; + break; + } + } + } +} + +void TPrinter :: +setbackground (const char *b) +{ + _background.destroy (); + _bg_desc = b; + if (b != NULL) + _parse_background (); +} + +bool printers_on_key (TMask_field & f, KEY key); + +// fv support structs for config + +bool PrinterDef :: +read (const char *name, FILE * fd) +{ + _printername = name; + _printername.trim (); + + TToken_string tmp (64, '='); + TString l (48); + TString r (16); + + while (TRUE) + { + const long p = ftell (fd); // Memorizza inizio paragrafo + + if (fgets (__tmp_string, 256, fd) == NULL) + return FALSE; + tmp = __tmp_string; + tmp.trim (); + + if (tmp == "[End of File]") + return FALSE; + + if (tmp[0] == '[') + { + fseek (fd, p, SEEK_SET); // Ritorna ad inizio paragrafo + + break; + } + + l = tmp.get (); + l.trim (); + r = tmp.get (); + r.trim (); + + if (l == "Device name") + { + _devicename = r; + } + else if (l == "Filter name") + { + _filtername = r; + } + else if (l == "Printer type") + { + _printertype = r; + } + else if (l == "Normal") + { + strcpy (_atstr[normalstyle], r); + } + else if (l == "Bold") + { + strcpy (_atstr[boldstyle], r); + } + else if (l == "Italic") + { + strcpy (_atstr[italicstyle], r); + } + else if (l == "Underlined") + { + strcpy (_atstr[underlinedstyle], r); + } + else if (l == "Code") + { + TToken_string code (r); + _names.add (TString (code.get ())); + _codes.add (TString (code.get ())); + } + else if (l == "Form feed") + { + _ffcode = r; + } + else if (l == "Newline") + { + _nlcode = r; + } + else + return error_box ("Riga di configurazione stampante errata:\n%s", (const char *) l); + } + return TRUE; +} + +bool PrinterDef :: +isdefault () +{ + return strcmp (_printername, "Default") == 0; +} + +////////// TPRINTROW ////////// + +TPrintrow ::TPrintrow () +{ + reset (); +} + +TPrintrow ::TPrintrow (const TPrintrow & pr) +{ + _row = pr.row (); + memcpy (_attr, pr._attr, MAXSTR); + memcpy (_cols, pr._cols, MAXSTR); + _currentcolor = 'w'; + _currentcolor <<= 8; + _currentcolor += 'n'; + _currentstyle = pr._currentstyle; + for (int i = 0; i < MAXSTR; i++) + _cols[i] = _currentcolor; + _lastpos = pr._lastpos; +} + +TObject *TPrintrow :: +dup () + const + { + return new TPrintrow (*this); + } + + const char *TPrintrow ::class_name () + const + { + return "Printrow"; + } + + word TPrintrow ::class_id () + const + { + return CLASS_PRINTROW; + } + +TPrintrow & TPrintrow :: +reset () +{ + _row.spaces (sizeof (_attr)); + _currentcolor = 'w'; + _currentcolor <<= 8; + _currentcolor += 'n'; + memset (_attr, normalstyle, sizeof (_attr)); + for (int i = 0; i < MAXSTR; i++) + _cols[i] = _currentcolor; + _lastpos = 0; + _currentstyle = normalstyle; + return *this; +} + +const char *TPrintrow :: +row_codified () +{ + // returns the row with @-codes for font style and color + char last_attr = -1; + int last_color = -1; + int k = 0; + _row.rtrim (); + for (int i = 0; i < _row.len (); i++) + { + if (_attr[i] != last_attr) + { + __tmp_string[k++] = '@'; + switch (_attr[i]) + { + case normalstyle: + __tmp_string[k++] = 'r'; + break; + case boldstyle: + __tmp_string[k++] = 'b'; + break; + case italicstyle: + __tmp_string[k++] = 'i'; + break; + case underlinedstyle: + __tmp_string[k++] = 'u'; + break; + } + last_attr = _attr[i]; + } + if (_cols[i] != last_color) + { + __tmp_string[k++] = '$'; + __tmp_string[k++] = '['; + __tmp_string[k++] = (char) (_cols[i] & 0x00ff); + __tmp_string[k++] = ','; + __tmp_string[k++] = (char) (_cols[i] >> 8); + __tmp_string[k++] = ']'; + last_color = _cols[i]; + } + __tmp_string[k++] = _row[i]; + } + // k = k > 255 ? 255 : k; + __tmp_string[k] = '\0'; + return __tmp_string; +} + +TPrintrow & TPrintrow ::put (const char *str, int position, int len) +{ + if (len < 1) + len = strlen (str); + + if (position < 0) + position = _lastpos; + + char bg = 'w', fg = 'n'; + for (int i = 0; i < len; i++) + { + char c = str[i]; + if (c == '$' && str[i + 1] == '[') + { + ++i; + fg = str[++i]; + c = str[++i]; + if (c == ']') + bg = _currentcolor >> 8; + else if (c == ',') + { + bg = str[++i]; + i++; + } + else + { + CHECK (0, "Error in color specification"); + } + _currentcolor = (bg << 8) + fg; + } + else if (c == '@') + { + c = str[++i]; + switch (toupper (c)) + { + case '#': + case '<': + case '>': + // printer MUST handle them + { + const int n = (c == '#') ? 5 : ((c == '>') ? 10 : 8); + _row[position] = '@'; + _attr[position++] = _currentstyle; + for (int j = 1; j < n; j++) + { + _row[position] = c; + _attr[position++] = _currentstyle; + } + } + break; + case 'B': + _currentstyle = boldstyle; + break; + case 'I': + _currentstyle = italicstyle; + break; + case 'U': + _currentstyle = underlinedstyle; + break; + case 'R': + _currentstyle = normalstyle; + break; + default: + // should be number followed by skip or jump + if (isdigit (c)) + { + // read number + char digbuf[8]; + int cnt = 0; + digbuf[cnt++] = c; + while (isdigit (c = str[++i])) + digbuf[cnt++] = c; + digbuf[cnt] = '\0'; + int pp = atoi (digbuf); + if (toupper (c) == 'G') + { + if (pp >= MAXSTR) + fatal_box ("printrow reaches position %d", pp); + if (pp > position) + for (int k = position; k < pp; k++) + { + _attr[k] = _currentstyle; + _cols[k] = _currentcolor; + } + position = pp; + } + else if (toupper (c) == 'J') + { + if (pp + position >= MAXSTR) + fatal_box ("printrow reaches position %d", pp + position); + for (int k = 0; k < pp; k++) + { + _attr[k + position] = _currentstyle; + _cols[k + position] = _currentcolor; + } + position += pp; + } + } + else + { + _row[position] = c; + _attr[position++] = _currentstyle; + _cols[position++] = _currentcolor; + } + } // switch + + } + else + { + _row[position] = c; + _attr[position] = _currentstyle; + _cols[position++] = _currentcolor; + } + } // for + + _lastpos = position; + return *this; +} + +////////// TPRINTER ////////// + +bool +printers_on_key (TMask_field & f, KEY key) +{ + if (key == K_SPACE) + { + TToken_string pn1 (10), pn2 (20); + + const PrinterDef & def = MainApp ()->printer ().get_description (atoi (f.get ())); + const char *s; + int j = 0; + while ((s = def.get_codenames (j)) != NULL) + { + pn1.add (format ("%02d", j)); + pn2.add (s); + j++; + } + ((TList_field &) f.mask ().field (MSK_1_CODES)).replace_items (pn1, pn2); + } + return TRUE; +} + +#if XVT_OS == XVT_OS_WIN + +bool +set_windows_print_device (TMask_field & f, KEY key) +{ + static char szDevice[80]; + if (key == K_SPACE) + { + if (MainApp ()->printer ().get_printrcd () != NULL) + free_print_rcd (MainApp ()->printer ().get_printrcd ()); + TToken_string & pn = MainApp ()->printer ().getprinternames (); + TString pdev (pn.get (atoi (f.get ()))); + GetProfileString ("devices", pdev, "", szDevice, sizeof (szDevice)); + pdev << "," << szDevice; +// WriteProfileString("windows","device", pdev); + // madonna bona + MainApp ()->printer ().set_printrcd (get_print_rcd (&(MainApp ()->printer ().get_printrcdsize ()))); + MainApp ()->printer ().set_win_formlen (); + } + return TRUE; +} + +#endif + +TPrinter :: TPrinter ():_date (TODAY), _multiple_link (FALSE), _frozen (FALSE), _isgraphics (TRUE), +_lines_per_inch (6), _ch_size (12) + +{ + _footerhandler = _headerhandler = NULL; + _linkhandler = NULL; + _config = "printer.ini"; + _curprn = 0; // first in list if no default is specified + + _curcode = 0; // first in list if no default is specified + + _formlen = 66; + _frompage = 0; + _topage = 0xffff; + _hwformfeed = FALSE; + _currentpage = 1; + _currentrow = 1; + _fp = NULL; + _headersize = 0; + _footersize = 0; + _isopen = FALSE; + // read configuration file + read_configuration (_config); +#if XVT_OS == XVT_OS_WIN + print_begin (); + _print_rcd = get_print_rcd (&_print_rcd_size); + set_win_formlen (); +#else + _isgraphics = FALSE; +#endif +} + +TToken_string & TPrinter ::getprinternames () +{ +// per ora va solo in windows +#if XVT_OS == XVT_OS_WIN + _get_windows_printer_names (_printer_names); +#endif + return _printer_names; +} + +void TPrinter :: +read_configuration (const char *conf) +{ + + FILE *cnfp = fopen (conf, "r"); + if (cnfp == NULL) + fatal_box ("Impossibile aprire il file %s", (const char *) _config); + + for (int i = 0; !feof (cnfp); i++) + { + if (fgets (__tmp_string, 256, cnfp) == NULL) + return; + // else + if (strncmp (__tmp_string, "[Default]", 9) != 0) + // fgets(__tmp_string,256,cnfp); + // else + { + if (*__tmp_string == '[') + { + // fatal_box("[ expected in file of printer configuration"); + + char *u = strchr (__tmp_string, ']'); + if (u) + *u = '\0'; + u = __tmp_string + 1; + + PrinterDef *pp = new PrinterDef; + _printers.add (pp); + if (pp->read (u, cnfp) == FALSE) + break; + } + } + } + fclose (cnfp); + + TString s ("printer.def"); +#if XVT_OS == XVT_OS_SCOUNIX + s << format (".%d", getuid ()); +#endif + if (fexist (s)) + { + TScanner sc (s); + TToken_string t (sc.line ()); + int where_print = t.get_int (1); + t = sc.line (); + _curprn = t.get_int (1); + t = sc.line (); + _printerfile = t.get (1); + t = sc.line (); + _curcode = t.get_int (1); +#if XVT_OS != XVT_OS_WIN + PrinterDef & def = (PrinterDef &) get_description (_curprn); +#endif + switch (where_print) + { + case 0: // stampante +#if XVT_OS == XVT_OS_WIN + _printertype = winprinter; +#else + switch (atoi (def._printertype)) + { + case 0: + _printertype = normprinter; + break; + case 1: + _printertype = localprinter; + break; + case 2: + _printertype = spoolprinter; + break; + } +#endif + break; + case 1: // file + + _printertype = fileprinter; + break; + case 2: // video + + _printertype = screenvis; + _curcode = 0; + break; + } + } +} + +TPrinter ::~TPrinter () +{ +#if XVT_OS == XVT_OS_WIN + print_end (); +#endif +} + +const char *TPrinter :: +class_name () + const + { + return "Printer"; + } + + word TPrinter ::class_id () + const + { + return CLASS_PRINTER; + } + + TPrintrow *TPrinter ::getheaderline (int linetoget) +{ + return ((TPrintrow *) _header.objptr (linetoget)); +} + +TPrintrow *TPrinter :: +getfooterline (int linetoget) +{ + return ((TPrintrow *) _footer.objptr (linetoget)); +} + +void TPrinter :: +setheaderline (int linetoset, TPrintrow * line) +{ + _header.add (line, linetoset); + if (linetoset >= _headersize) + _headersize = linetoset + 1; +} + +void TPrinter :: +setheaderline (int linetoset, const TPrintrow & line) +{ + TPrintrow *p = new TPrintrow (line); + setheaderline (linetoset, p); +} + +void TPrinter :: +setfooterline (int linetoset, TPrintrow * line) +{ + _footer.add (line, linetoset); + // if (linetoset >= _footersize) _footersize = linetoset+1; +} + +void TPrinter :: +setfooterline (int linetoset, const TPrintrow & line) +{ + TPrintrow *p = new TPrintrow (line); + setfooterline (linetoset, p); +} + +void TPrinter :: +resetheader () +{ + _header.destroy (); + _headersize = 0; +} + +void TPrinter :: +resetfooter () +{ + _footer.destroy (); + // _footersize = 0; +} + +bool TPrinter :: +printrow (TPrintrow * rowtoprint) +{ + if (!isopen ()) + return FALSE; + + if (_currentpage < _frompage || _currentpage > _topage) + return TRUE; + + TString rw (rowtoprint == NULL ? "" : (_printertype == screenvis || _printertype == winprinter ? + rowtoprint->row_codified () : + rowtoprint->row ())); + rw.rtrim (); + + int lun = rw.len (); + int idx; + + for (idx = 0; idx < lun; idx++) + { + if (rw[idx] == '@') // gestione data e n. di pagina + + { + switch (rw[idx + 1]) + { + case '#': + rw.overwrite (format ("%-5u", _currentpage), idx++); + break; + case '>': + rw.overwrite (_date.string (4), idx++); + break; + case '<': + rw.overwrite (_date.string (2), idx++); + break; + default: + break; + } + } + } + + if (_printertype == screenvis) + { + if (!_vf->frozen ()) + _vf->add_line (rw); + else + _frozen = TRUE; + return TRUE; + } + + if (_printertype == winprinter) + { + // add line to txt + if (!_frozen) + _txt.append (rw); + return TRUE; + } + + const PrinterDef & pd = get_description (_curprn); + int prvstl = -1; + for (idx = 0; idx < lun; idx++) + { + int cst = rowtoprint->get_style (idx); + if (cst != prvstl) + { + fprintf (_fp, "%s", pd._atstr[normalstyle]); + if (cst != normalstyle) + fprintf (_fp, "%s", pd._atstr[cst]); + } + prvstl = cst; + putc (rw[idx], _fp); + } + if (newline ()) + putc (newline (), _fp); + + return TRUE; +} + +word TPrinter :: +rows_left () + const + { + word left = _formlen - _currentrow - _footersize + 1; + if (_currentrow < 2) + left -= _headersize; + return left; + } + + bool TPrinter ::print (TPrintrow & rowtoprint) +{ + bool ok = TRUE; + + if (_currentrow > _formlen - _footersize) + ok = printfooter (); + +// if (ok && _currentrow <= _headersize) + if (ok && _currentrow == 1) + ok = printheader (); + + if (ok) + { + ok = printrow (&rowtoprint); + _currentrow++; + } + + return ok; +} + +bool TPrinter :: +printheader () +{ + if (_headerhandler) + _headerhandler (*this); + + bool ok = TRUE; + for (int i = 0; i < _headersize && ok; i++) + ok = printrow (getheaderline (i)); + + _currentrow = _headersize + 1; + return ok; +} + +bool TPrinter :: +printfooter () +{ + if (_footerhandler) + _footerhandler (*this); + + bool ok = TRUE; + for (int i = 0; i < _footersize && ok; i++) + ok = printrow (getfooterline (i)); + +#if XVT_OS != XVT_OS_WIN + if (ok) + printformfeed (); +#endif + + _currentrow = 1; + _currentpage++; + + return ok; +} + +bool TPrinter :: +skip (int linestoskip) +{ + int jumpline; + + CHECK (linestoskip >= 0, "Linestoskip can't be negative"); + jumpline = _currentrow + linestoskip; + return jump (jumpline); +} + +bool TPrinter :: +jump (int jumpline) +{ + int i = 0; + bool ok = TRUE; + + CHECK (jumpline >= 0, "Jumpline can't be negative"); + if (jumpline > _formlen - _footersize) + ok = formfeed (); + else + for (i = _currentrow; i < jumpline; i++) + if (!printrow ()) + ok = FALSE; + if (jumpline > _formlen - _footersize) + ok = FALSE; + return ok; +} + +bool TPrinter :: +formfeed () +{ + const int lastrow = _formlen - _footersize; + for (; _currentrow <= lastrow; _currentrow++) + printrow (); + return printfooter (); +} + +void TPrinter :: +reset () +{ + resetheader (); + resetfooter (); + _currentpage = 1; + _currentrow = 1; +} + +bool TPrinter :: +printformfeed () +{ +#if XVT_OS != XVT_OS_WIN + const PrinterDef & pd = get_description (_curprn); + + if (_printertype != screenvis && _hwformfeed) + fprintf (_fp, "%s", (const char *) pd._ffcode); +#endif + return TRUE; +} + +bool TPrinter :: +open () +{ +// qui +#if XVT_OS==XVT_OS_SCOUNIX + if (_printertype == spoolprinter) + { + const PrinterDef & def = get_description (_curprn); + int pfd[2]; + + if (pipe (pfd) == -1) + return error_box ("Impossibile creare processo di stampa " "(pipe)"); + + int ret = fork (); + if (ret == -1) + return error_box ("Impossibile creare processo di stampa " "(fork)"); + + if (ret == 0) + { + if (( :: close (0) != -1) && ( ::dup (pfd[0]) == 0) && + ( :: close (pfd[0]) == 0) && ( ::close (pfd[1]) != -1)) + { + char s0[80]; + + sprintf (s0, "-d%s", (const char *) def._devicename); + if ((def._filtername).not_empty ()) + { + char s1[80]; + sprintf (s1, "-o %s", (const char *) def._filtername); + char *ws[5] = + {"lpr", "-s", s0, s1, NULL}; + execvp (ws[0], ws); + } + else + { + char *ws[4] = + {"lpr", "-s", s0, NULL}; + execvp (ws[0], ws); + } + exit (-1); + } + } + if (( ::close (pfd[0]) == -1) || ((_fp = fdopen (pfd[1], "w")) == NULL)) + return error_box ("Impossibile creare processo di stampa" "(close)"); + } + else +#endif + if (_printertype == screenvis) + { + _vf = new TViswin (NULL, "Anteprima di stampa", TRUE, TRUE, + _linksdescr.items () > 0); + _vf->open_modal (); + } + else if (_printertype == winprinter) + { + // prepare text object for new text + _txt.destroy (); + } + else + { + const PrinterDef & def = get_description (_curprn); + TFilename fname (_printerfile); + + if (_printertype == normprinter) + fname = def._devicename; + _fp = fopen (fname, "w"); + + if (_fp == NULL) + return error_box ("Errore di apertura file stampa: '%s'", + (const char *) fname); + + TString code (def.get_codes (_curcode)); + if (code.not_empty ()) + { + const char *s = code; + fputs (esc ((char *) s), _fp); + } + } + + _currentrow = 1; + _currentpage = 1; + + return _isopen = TRUE; +} + +void TPrinter :: +set () +{ + TMask mask ("bagn001a.msk"); + TToken_string pn1 (50), pn2 (100); + int i; + + MainApp ()->disable_menu_item (M_FILE_PG_SETUP); +#if XVT_OS != XVT_OS_WIN + for (i = 0; i < _printers.items (); i++) + { + pn1.add (i); + pn2.add (((PrinterDef &) _printers[i])._printername); + } + ((TList_field &) (mask.field (MSK_1_PRINTERS))).replace_items (pn1, pn2); + mask.hide (MSK_1_SETUP); + mask.hide (MSK_1_SIZE); + mask.hide (MSK_1_LINES); + pn1 = ""; + pn2 = ""; + for (i = 0; i < ((PrinterDef &) _printers[_curprn])._names.items (); i++) + { + pn1.add (format ("%d", i)); + pn2.add ((TString &) ((PrinterDef &) _printers[_curprn])._names[i]); + } + ((TList_field &) (mask.field (MSK_1_CODES))).replace_items (pn1, pn2); + mask.set_handler (MSK_1_PRINTERS, printers_on_key); + if (_printertype == fileprinter) + mask.set (MSK_1_TYPE, "1"); + else if (_printertype == screenvis) + mask.set (MSK_1_TYPE, "2"); + else + mask.set (MSK_1_TYPE, "0"); + + mask.set (MSK_1_PRINTERS, format ("%d", _curprn)); + mask.set (MSK_1_CODES, format ("%d", _curcode)); + mask.set (MSK_1_FILENAME, _printerfile); + mask.reset (MSK_1_SAVE); + + if (mask.run () == K_ESC) + return; + + if (mask.get (MSK_1_SAVE).not_empty ()) + { + TString s ("printer.def"); +#if XVT_OS == XVT_OS_SCOUNIX + s << format (".%d", getuid ()); +#endif + mask.set_workfile (s); + mask.save (); + } + + // get user choices + + _curprn = atoi (mask.get (MSK_1_PRINTERS)); + PrinterDef & def = (PrinterDef &) get_description (_curprn); + switch (atoi (mask.get (MSK_1_TYPE))) + { + case 0: // stampante + + _printertype = normprinter; + _curcode = atoi (mask.get (MSK_1_CODES)); + switch (atoi (def._printertype)) + { + case 0: + _printertype = normprinter; + break; + case 1: + _printertype = localprinter; + break; + case 2: + _printertype = spoolprinter; + break; + } + break; + case 1: // file + + _printertype = fileprinter; + _printerfile = mask.get (MSK_1_FILENAME); + _curcode = atoi (mask.get (MSK_1_CODES)); + break; + case 2: // video + + _printertype = screenvis; + _curcode = 0; + break; + } + +#else + + static char defPrinter[80]; + static char szDevice[50]; + int defIndex; + + // get default printer driver + GetProfileString ("windows", "device", ",,,", defPrinter, sizeof (defPrinter)); + TString pdev (defPrinter); + GetProfileString ("devices", pdev, "", szDevice, sizeof (szDevice)); + pdev << "," << szDevice; + TToken_string dio (pdev, ','); + + // get printer names + _get_windows_printer_names (pn2); + // determine index of current default printer + for (i = 0; i < pn2.items (); i++) + { + if (TString (dio.get (0)) == TString (pn2.get (i))) + { + defIndex = i; + break; + } + } + if (defIndex == pn2.items ()) + defIndex = 0; // should never happen + + for (i = 0; i < pn2.items (); i++) + pn1.add (i); + + ((TList_field &) (mask.field (MSK_1_PRINTERS))).replace_items (pn1, pn2); + mask.set (MSK_1_PRINTERS, pn1.get (defIndex)); + mask.hide (MSK_1_CODES); + mask.set (MSK_1_ISGRAPHICS, _isgraphics ? "X" : ""); + mask.set (MSK_1_SIZE, format ("%d", _ch_size)); + mask.set (MSK_1_LINES, format ("%d", _lines_per_inch)); + + if (_printertype == fileprinter) + mask.set (MSK_1_TYPE, "1"); + else if (_printertype == screenvis) + mask.set (MSK_1_TYPE, "2"); + else + mask.set (MSK_1_TYPE, "0"); + + mask.set_handler (MSK_1_PRINTERS, set_windows_print_device); + mask.reset (MSK_1_SAVE); + + KEY k; + while ((k = mask.run ()) != K_ESC && k != K_ENTER) + { + if (k == MSK_1_SETUP) + { + if (_print_rcd != NULL) + { + if (page_setup_dlg (_print_rcd)) + { + // see if user has changed printer + int dIndex; + // determine index of currently selected printer + // ACTHUNG! Deep hacking of XVT internals! NON PORTABLE! + for (i = 0; i < pn2.items (); i++) + if (strcmp ((const char *) (_print_rcd + 4), pn2.get (i)) == 0) + { + dIndex = i; + break; + } + mask.set (MSK_1_PRINTERS, pn1.get (dIndex)); + set_win_formlen (); + } + mask.set_focus (); + } + else + beep (); + } + } + if (k == K_ESC) + { + // rimetti come prima + // WriteProfileString("windows","device", pdev); + if (_print_rcd != NULL) + free_print_rcd (_print_rcd); + _print_rcd = get_print_rcd (&_print_rcd_size); + set_win_formlen (); + return; + } + + if (mask.get (MSK_1_SAVE).not_empty ()) + { + TString s ("printer.def"); + mask.set_workfile (s); + mask.save (); + } + + switch (atoi (mask.get (MSK_1_TYPE))) + { + case 0: // stampante + + _printertype = winprinter; + break; + case 1: // file + + _printertype = fileprinter; + _printerfile = mask.get (MSK_1_FILENAME); + _curcode = atoi (mask.get (MSK_1_CODES)); + break; + case 2: // video + + _printertype = screenvis; + _curcode = 0; + break; + } + + _isgraphics = mask.get_bool (MSK_1_ISGRAPHICS); + _ch_size = atoi (mask.get (MSK_1_SIZE)); + _lines_per_inch = atoi (mask.get (MSK_1_LINES)); + set_win_formlen (); + +#endif + + MainApp ()->enable_menu_item (M_FILE_PG_SETUP); +} + +void TPrinter :: +close () +{ + if (isopen () && _currentrow > 1 && + (_footersize || (_printertype != screenvis && _printertype != winprinter))) + formfeed (); + + if (_fp) + { + fclose (_fp); + _fp = NULL; + } + + if (_printertype == screenvis) + { + CHECK (_vf, "VF!"); + _vf->close_print (); + _vf->run (); + if (_vf->is_open ()) + _vf->close_modal (); + delete _vf; + freeze (FALSE); + _vf = NULL; + } +#if XVT_OS == XVT_OS_WIN + else if (_printertype == winprinter) + { + PrintWhat._prcd = _print_rcd; + PrintWhat._txt = &_txt; + PrintWhat._graphics = _isgraphics; + PrintWhat._charsize = _ch_size; + start_print_thread (start_winprint, (long) (&PrintWhat)); + } +#endif + else if (_printertype == localprinter) + { +#if XVT_OS == XVT_OS_SCOUNIX + TFilename s1 = tmpnam (NULL); + switch (fork ()) + { + case -1: + break; + case 0: + execlp ("localprint", "localprint", (const char *) s1, NULL); + default: + wait ((int *) NULL); + } + remove (s1); +#endif + } + _isopen = FALSE; +} + +// +// TFile_printer +// + +#include + +#if XVT_OS == XVT_OS_DOS +#define FORMAT_COMMAND "FORMAT" +#else +#define FORMAT_COMMAND "dosformat -fq" +#endif + +const long disk_sizes[] = +{360000, 1200000, 720000, 1400000, 2880000}; + +TFile_printer ::TFile_printer (const char *ffile, const char *label, int len_rec, int num_rec_inizio, int num_rec_fine, int tipo_disco) +{ + set_printtype (fileprinter); + + _num_rec_testa_coda = num_rec_inizio + num_rec_fine; + _file = ffile; + _label = label; + _len_rec = len_rec; + _volume = 1; + _size = disk_sizes[tipo_disco]; + _num_rec_volume = int ((_size / len_rec) - _num_rec_testa_coda); + _nome_file_fissato = TRUE; + _formatta = FALSE; + _label_fissata = TRUE; + +} + +void TFile_printer :: +open () +{ +} + +void TFile_printer :: +close () +{ +} + +bool TFile_printer :: +genera_dischetti () +{ + int r; + + warning_box ("Questa procedura richiede %2d dischetti", + _volume); + + for (int i = 0; i < _tmp_files.items (); i++) + { + // Avvisa l'utente di inserire un dischetto + r = yesno_box ("Inserire il dischetto n. %2d di %2d nel drive %2s", + i + 1, _volume, _drive); + if (!r) + return error_box ("Procedura interrotta!"); + + // e eventualmente lo formatta + if (_formatta) + { + TString dep (30); + if (_label != NULL) + dep << FORMAT_COMMAND << " " << "/v:" << _label << " " << _drive; + else + dep << FORMAT_COMMAND << " " << _drive; + + TExternal_app sys (dep); + sys.run (); + } + + // copia il file sul dischetto + fcopy ((const char *) &_tmp_files[i], (const char *) _drive); + + } + return TRUE; +} + +TFile_printer ::~TFile_printer () +{ +} + +void TFile_printer :: +set () +{ + TMask m ("tfilepr"); + KEY tasto; + int f; + +// + // + // -------------------------------------------------------------------- + // Qui bisogna inserire la lista dei drive disponibili nella maschera + // Per ora tale lista e' fissa e contiene solo A: e B: + // -------------------------------------------------------------------- + // + // + + m.set (F_FILE_DESTINAZIONE, _file); + m.set (F_LABEL, _label); + + if (_nome_file_fissato) + m.disable (F_FILE_DESTINAZIONE); + + if (_label_fissata) + m.disable (F_LABEL); + + tasto = m.run (); + + if (tasto == K_ENTER) + { + f = atoi (m.get (F_FORMATO_DISCO)); + _drive = m.get (F_DRIVE); + _file = m.get (F_FILE_DESTINAZIONE); + _label = m.get (F_LABEL); + _formatta = (bool) (m.get (F_FORMATTA) == "X"); + _size = disk_sizes[f]; + _num_rec_volume = int ((_size / _len_rec) - _num_rec_testa_coda); + } +} + +// +// TFile printer fine +// +#include +#include + +#if XVT_OS==XVT_OS_SCOUNIX +#include +#include +#include +#else +#include +#endif + +#define STYLE_NUM 4 + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +struct PrDesc +{ + TTextfile *_txt; + PRINT_RCD *_prcd; + bool _graphics; + int _formlen; + int _charsize; + int _lines_per_inch; +} +PrintWhat; + +#define LINES_PER_INCH (6.0) + +#if XVT_OS == XVT_OS_WIN + +#include + +void TPrinter :: +_get_windows_printer_names (TToken_string & t) +{ + char *buf = new char[4096]; // ammazzao' + + GetProfileString ("devices", NULL, "", buf, 4096); + + for (int i = 0; i < 4095; i++) + { + if (buf[i] == '\0' && buf[i + 1] == '\0') + break; + if (buf[i] == '\0' && buf[i + 1] != '\0') + buf[i] = '|'; + } + t = buf; + delete buf; +} + +BOOLEAN TPrinter :: +start_winprint (long data) +{ + PrDesc *pd = (PrDesc *) data; + TTextfile & txt = *(pd->_txt); + TPrintwin pw (pd->_prcd, txt, pd->_charsize); + pw.print_background (pd->_graphics); + pw.do_print (); + return pw.aborted (); +} +#endif + +// utils del caz +HIDDEN void +read_int (const char *s, int &n, int &cnt) +{ + static char nbuf[10]; + int j = 0; + while (!isdigit (s[cnt])) + cnt++; + while (isdigit (s[cnt])) + nbuf[j++] = s[cnt++]; + nbuf[j] = '\0'; + n = atoi (nbuf); +} + + + +#if XVT_OS == XVT_OS_WIN +void TPrinter :: +set_win_formlen () +{ + long pw, ph, phr, pvr; + xvt_escape (XVT_ESC_GET_PRINTER_INFO, _print_rcd, &ph, &pw, &pvr, &phr); + if (pvr != 0) + { + _formlen = (int) ((ph / pvr) * _lines_per_inch); + _dots_per_line = (int) (pvr / _lines_per_inch); + _vert_offset = (int) (ph % (long) (_formlen * _dots_per_line)); + _horz_offset = 0; // not implemented (font dependent) + + } + else + warning_box ("Il driver di stampante non e' valido. Non stampare prima di averlo" + " reinstallato"); +} +#endif + +void TPrinter :: +_parse_background () +{ + char op; + int x1, x2, y1, y2; + TToken_string tt (20); + TString txt (80); + TArray pix; + char ch; + int cnt = 0; + + while ((ch = _bg_desc[cnt++]) != '\0') + { + op = ch; + tt = ""; + char bf[2]; + bf[1] = '\0'; + switch (op) + { + case ' ': // ignore whitespace + + case '\t': + case '\n': + continue; + break; + case 'l': // line + + case 'b': // box + + case 'r': // round box + + cnt++; + read_int (_bg_desc, x1, cnt); + read_int (_bg_desc, y1, cnt); + read_int (_bg_desc, x2, cnt); + read_int (_bg_desc, y2, cnt); + cnt++; + tt << op; + tt.add (x1 - 1); + tt.add (y1 - 1); + tt.add (x2 - 1); + tt.add (y2 - 1); + break; + case 't': // text + + cnt++; + read_int (_bg_desc, x1, cnt); + read_int (_bg_desc, y1, cnt); + cnt++; + txt = ""; + while ((ch = _bg_desc[cnt++]) != '}') + txt << ch; + tt << op; + tt.add (x1 - 1); + tt.add (y1 - 1); + tt.add (txt); + break; + case 'P': // set pen style + + case 'B': // set brush + + case 'W': // set line width + + case 'C': // set pen color + + tt << op; + bf[0] = _bg_desc[cnt++]; + tt.add (bf); + break; + default: + yesnofatal_box ("Unknown background opcode: %c", op); + break; + } + pix.add (tt); + } + + // now build row descriptions + + // colors are listed in printapp: + + char curcol = 'n'; + char curpen = 'n'; + char curpat = 'n'; + char curwid = '1'; + + for (int l = 0; l < _formlen; l++) + { + + TString *rwd = (TString *) _background.objptr (l); + if (rwd == NULL) + { + _background.add (rwd = new TString, l); + if (curcol != 'n') + (*rwd) << 'C' << curcol; + if (curpat != 'n') + (*rwd) << 'B' << curpat; + if (curwid != '1') + (*rwd) << 'W' << curwid; + if (curpen != 'n') + (*rwd) << 'P' << curcol; + } + for (int j = 0; j < pix.items (); j++) + { + TToken_string & tt = (TToken_string &) pix[j]; + tt.restart (); + + // la stringa contiene l'opcode piu' i parametri in binario, + // incrementati di 1 per evitare lo 0 + + switch (*(tt.get (0))) + { + case 'b': + x1 = tt.get_int (1) + 1; + y1 = tt.get_int (2) + 1; + x2 = tt.get_int (3) + 1; + y2 = tt.get_int (4) + 1; + if (y1 == l + 1) // at ze biginnin + + { + (*rwd) << 'u' << char (x1); + (*rwd) << 'r' << char (x1) << char (x2); + (*rwd) << 'u' << char (x2); + } + else if (y2 == l + 1) // at ze end + + { + (*rwd) << 'o' << char (x1); + (*rwd) << 'r' << char (x1) << char (x2); + (*rwd) << 'o' << char (x2); + } + else if (y1 < l + 1 && y2 > l + 1) // in ze middol + + { + (*rwd) << 'v' << char (x1); + (*rwd) << 'v' << char (x2); + } + break; + case 'l': + x1 = tt.get_int (1) + 1; + y1 = tt.get_int (2) + 1; + x2 = tt.get_int (3) + 1; + y2 = tt.get_int (4) + 1; + if (y1 == y2 && y1 == l + 1) // orizzontale + + { + (*rwd) << 'h' << char (x1) << char (x2); + } + else if (y1 <= l + 1 && y2 >= l + 1) // verticale + + { + (*rwd) << 'v' << char (x1); + } + break; + case 't': + x1 = tt.get_int (1) + 1; + y1 = tt.get_int (2) + 1; // al gh'e' + + if (y1 == l + 1) + { + } + break; + case 'W': + curwid = *(tt.get (1)); + (*rwd) << 'W' << curwid; + break; + case 'P': + curpen = *(tt.get (1)); + (*rwd) << 'P' << curpen; + break; + case 'B': + curpat = *(tt.get (1)); + (*rwd) << 'B' << curpat; + break; + case 'C': + curcol = *(tt.get (1)); + (*rwd) << 'C' << curcol; + break; + } + } + } +} + +void TPrinter :: +setbackground (const char *b) +{ + _background.destroy (); + _bg_desc = b; + if (b != NULL) + _parse_background (); +} + +bool printers_on_key (TMask_field & f, KEY key); + +// fv support structs for config + +bool PrinterDef :: +read (const char *name, FILE * fd) +{ + _printername = name; + _printername.trim (); + + TToken_string tmp (64, '='); + TString l (48); + TString r (16); + + while (TRUE) + { + const long p = ftell (fd); // Memorizza inizio paragrafo + + if (fgets (__tmp_string, 256, fd) == NULL) + return FALSE; + tmp = __tmp_string; + tmp.trim (); + + if (tmp == "[End of File]") + return FALSE; + + if (tmp[0] == '[') + { + fseek (fd, p, SEEK_SET); // Ritorna ad inizio paragrafo + + break; + } + + l = tmp.get (); + l.trim (); + r = tmp.get (); + r.trim (); + + if (l == "Device name") + { + _devicename = r; + } + else if (l == "Filter name") + { + _filtername = r; + } + else if (l == "Printer type") + { + _printertype = r; + } + else if (l == "Normal") + { + strcpy (_atstr[normalstyle], r); + } + else if (l == "Bold") + { + strcpy (_atstr[boldstyle], r); + } + else if (l == "Italic") + { + strcpy (_atstr[italicstyle], r); + } + else if (l == "Underlined") + { + strcpy (_atstr[underlinedstyle], r); + } + else if (l == "Code") + { + TToken_string code (r); + _names.add (TString (code.get ())); + _codes.add (TString (code.get ())); + } + else if (l == "Form feed") + { + _ffcode = r; + } + else if (l == "Newline") + { + _nlcode = r; + } + else + return error_box ("Riga di configurazione stampante errata:\n%s", (const char *) l); + } + return TRUE; +} + +bool PrinterDef :: +isdefault () +{ + return strcmp (_printername, "Default") == 0; +} + +////////// TPRINTROW ////////// + +TPrintrow ::TPrintrow () +{ + reset (); +} + +TPrintrow ::TPrintrow (const TPrintrow & pr) +{ + _row = pr.row (); + memcpy (_attr, pr._attr, MAXSTR); + memcpy (_cols, pr._cols, MAXSTR); + _currentcolor = 'w'; + _currentcolor <<= 8; + _currentcolor += 'n'; + _currentstyle = pr._currentstyle; + for (int i = 0; i < MAXSTR; i++) + _cols[i] = _currentcolor; + _lastpos = pr._lastpos; +} + +TObject *TPrintrow :: +dup () + const + { + return new TPrintrow (*this); + } + + const char *TPrintrow ::class_name () + const + { + return "Printrow"; + } + + word TPrintrow ::class_id () + const + { + return CLASS_PRINTROW; + } + +TPrintrow & TPrintrow :: +reset () +{ + _row.spaces (sizeof (_attr)); + _currentcolor = 'w'; + _currentcolor <<= 8; + _currentcolor += 'n'; + memset (_attr, normalstyle, sizeof (_attr)); + for (int i = 0; i < MAXSTR; i++) + _cols[i] = _currentcolor; + _lastpos = 0; + _currentstyle = normalstyle; + return *this; +} + +const char *TPrintrow :: +row_codified () +{ + // returns the row with @-codes for font style and color + char last_attr = -1; + int last_color = -1; + int k = 0; + _row.rtrim (); + for (int i = 0; i < _row.len (); i++) + { + if (_attr[i] != last_attr) + { + __tmp_string[k++] = '@'; + switch (_attr[i]) + { + case normalstyle: + __tmp_string[k++] = 'r'; + break; + case boldstyle: + __tmp_string[k++] = 'b'; + break; + case italicstyle: + __tmp_string[k++] = 'i'; + break; + case underlinedstyle: + __tmp_string[k++] = 'u'; + break; + } + last_attr = _attr[i]; + } + if (_cols[i] != last_color) + { + __tmp_string[k++] = '$'; + __tmp_string[k++] = '['; + __tmp_string[k++] = (char) (_cols[i] & 0x00ff); + __tmp_string[k++] = ','; + __tmp_string[k++] = (char) (_cols[i] >> 8); + __tmp_string[k++] = ']'; + last_color = _cols[i]; + } + __tmp_string[k++] = _row[i]; + } + // k = k > 255 ? 255 : k; + __tmp_string[k] = '\0'; + return __tmp_string; +} + +TPrintrow & TPrintrow ::put (const char *str, int position, int len) +{ + if (len < 1) + len = strlen (str); + + if (position < 0) + position = _lastpos; + + char bg = 'w', fg = 'n'; + for (int i = 0; i < len; i++) + { + char c = str[i]; + if (c == '$' && str[i + 1] == '[') + { + ++i; + fg = str[++i]; + c = str[++i]; + if (c == ']') + bg = _currentcolor >> 8; + else if (c == ',') + { + bg = str[++i]; + i++; + } + else + { + CHECK (0, "Error in color specification"); + } + _currentcolor = (bg << 8) + fg; + } + else if (c == '@') + { + c = str[++i]; + switch (toupper (c)) + { + case '#': + case '<': + case '>': + // printer MUST handle them + { + const int n = (c == '#') ? 5 : ((c == '>') ? 10 : 8); + _row[position] = '@'; + _attr[position++] = _currentstyle; + for (int j = 1; j < n; j++) + { + _row[position] = c; + _attr[position++] = _currentstyle; + } + } + break; + case 'B': + _currentstyle = boldstyle; + break; + case 'I': + _currentstyle = italicstyle; + break; + case 'U': + _currentstyle = underlinedstyle; + break; + case 'R': + _currentstyle = normalstyle; + break; + default: + // should be number followed by skip or jump + if (isdigit (c)) + { + // read number + char digbuf[8]; + int cnt = 0; + digbuf[cnt++] = c; + while (isdigit (c = str[++i])) + digbuf[cnt++] = c; + digbuf[cnt] = '\0'; + int pp = atoi (digbuf); + if (toupper (c) == 'G') + { + if (pp >= MAXSTR) + fatal_box ("printrow reaches position %d", pp); + if (pp > position) + for (int k = position; k < pp; k++) + { + _attr[k] = _currentstyle; + _cols[k] = _currentcolor; + } + position = pp; + } + else if (toupper (c) == 'J') + { + if (pp + position >= MAXSTR) + fatal_box ("printrow reaches position %d", pp + position); + for (int k = 0; k < pp; k++) + { + _attr[k + position] = _currentstyle; + _cols[k + position] = _currentcolor; + } + position += pp; + } + } + else + { + _row[position] = c; + _attr[position++] = _currentstyle; + _cols[position++] = _currentcolor; + } + } // switch + + } + else + { + _row[position] = c; + _attr[position] = _currentstyle; + _cols[position++] = _currentcolor; + } + } // for + + _lastpos = position; + return *this; +} + +////////// TPRINTER ////////// + +bool +printers_on_key (TMask_field & f, KEY key) +{ + if (key == K_SPACE) + { + TToken_string pn1 (10), pn2 (20); + + const PrinterDef & def = MainApp ()->printer ().get_description (atoi (f.get ())); + const char *s; + int j = 0; + while ((s = def.get_codenames (j)) != NULL) + { + pn1.add (format ("%02d", j)); + pn2.add (s); + j++; + } + ((TList_field &) f.mask ().field (MSK_1_CODES)).replace_items (pn1, pn2); + } + return TRUE; +} + +#if XVT_OS == XVT_OS_WIN + +bool +set_windows_print_device (TMask_field & f, KEY key) +{ + static char szDevice[80]; + if (key == K_SPACE) + { + if (MainApp ()->printer ().get_printrcd () != NULL) + free_print_rcd (MainApp ()->printer ().get_printrcd ()); + TToken_string & pn = MainApp ()->printer ().getprinternames (); + TString pdev (pn.get (atoi (f.get ()))); + GetProfileString ("devices", pdev, "", szDevice, sizeof (szDevice)); + pdev << "," << szDevice; +// WriteProfileString("windows","device", pdev); + // madonna bona + MainApp ()->printer ().set_printrcd (get_print_rcd (&(MainApp ()->printer ().get_printrcdsize ()))); + MainApp ()->printer ().set_win_formlen (); + } + return TRUE; +} + +#endif + +TPrinter :: TPrinter ():_date (TODAY), _multiple_link (FALSE), _frozen (FALSE), _isgraphics (TRUE), +_lines_per_inch (6), _ch_size (12) + +{ + _footerhandler = _headerhandler = NULL; + _linkhandler = NULL; + _config = "printer.ini"; + _curprn = 0; // first in list if no default is specified + + _curcode = 0; // first in list if no default is specified + + _formlen = 66; + _frompage = 0; + _topage = 0xffff; + _hwformfeed = FALSE; + _currentpage = 1; + _currentrow = 1; + _fp = NULL; + _headersize = 0; + _footersize = 0; + _isopen = FALSE; + // read configuration file + read_configuration (_config); +#if XVT_OS == XVT_OS_WIN + print_begin (); + _print_rcd = get_print_rcd (&_print_rcd_size); + set_win_formlen (); +#else + _isgraphics = FALSE; +#endif +} + +TToken_string & TPrinter ::getprinternames () +{ +// per ora va solo in windows +#if XVT_OS == XVT_OS_WIN + _get_windows_printer_names (_printer_names); +#endif + return _printer_names; +} + +void TPrinter :: +read_configuration (const char *conf) +{ + + FILE *cnfp = fopen (conf, "r"); + if (cnfp == NULL) + fatal_box ("Impossibile aprire il file %s", (const char *) _config); + + for (int i = 0; !feof (cnfp); i++) + { + if (fgets (__tmp_string, 256, cnfp) == NULL) + return; + // else + if (strncmp (__tmp_string, "[Default]", 9) != 0) + // fgets(__tmp_string,256,cnfp); + // else + { + if (*__tmp_string == '[') + { + // fatal_box("[ expected in file of printer configuration"); + + char *u = strchr (__tmp_string, ']'); + if (u) + *u = '\0'; + u = __tmp_string + 1; + + PrinterDef *pp = new PrinterDef; + _printers.add (pp); + if (pp->read (u, cnfp) == FALSE) + break; + } + } + } + fclose (cnfp); + + TString s ("printer.def"); +#if XVT_OS == XVT_OS_SCOUNIX + s << format (".%d", getuid ()); +#endif + if (fexist (s)) + { + TScanner sc (s); + TToken_string t (sc.line ()); + int where_print = t.get_int (1); + t = sc.line (); + _curprn = t.get_int (1); + t = sc.line (); + _printerfile = t.get (1); + t = sc.line (); + _curcode = t.get_int (1); +#if XVT_OS != XVT_OS_WIN + PrinterDef & def = (PrinterDef &) get_description (_curprn); +#endif + switch (where_print) + { + case 0: // stampante +#if XVT_OS == XVT_OS_WIN + _printertype = winprinter; +#else + switch (atoi (def._printertype)) + { + case 0: + _printertype = normprinter; + break; + case 1: + _printertype = localprinter; + break; + case 2: + _printertype = spoolprinter; + break; + } +#endif + break; + case 1: // file + + _printertype = fileprinter; + break; + case 2: // video + + _printertype = screenvis; + _curcode = 0; + break; + } + } +} + +TPrinter ::~TPrinter () +{ +#if XVT_OS == XVT_OS_WIN + print_end (); +#endif +} + +const char *TPrinter :: +class_name () + const + { + return "Printer"; + } + + word TPrinter ::class_id () + const + { + return CLASS_PRINTER; + } + + TPrintrow *TPrinter ::getheaderline (int linetoget) +{ + return ((TPrintrow *) _header.objptr (linetoget)); +} + +TPrintrow *TPrinter :: +getfooterline (int linetoget) +{ + return ((TPrintrow *) _footer.objptr (linetoget)); +} + +void TPrinter :: +setheaderline (int linetoset, TPrintrow * line) +{ + _header.add (line, linetoset); + if (linetoset >= _headersize) + _headersize = linetoset + 1; +} + +void TPrinter :: +setheaderline (int linetoset, const TPrintrow & line) +{ + TPrintrow *p = new TPrintrow (line); + setheaderline (linetoset, p); +} + +void TPrinter :: +setfooterline (int linetoset, TPrintrow * line) +{ + _footer.add (line, linetoset); + // if (linetoset >= _footersize) _footersize = linetoset+1; +} + +void TPrinter :: +setfooterline (int linetoset, const TPrintrow & line) +{ + TPrintrow *p = new TPrintrow (line); + setfooterline (linetoset, p); +} + +void TPrinter :: +resetheader () +{ + _header.destroy (); + _headersize = 0; +} + +void TPrinter :: +resetfooter () +{ + _footer.destroy (); + // _footersize = 0; +} + +bool TPrinter :: +printrow (TPrintrow * rowtoprint) +{ + if (!isopen ()) + return FALSE; + + if (_currentpage < _frompage || _currentpage > _topage) + return TRUE; + + TString rw (rowtoprint == NULL ? "" : (_printertype == screenvis || _printertype == winprinter ? + rowtoprint->row_codified () : + rowtoprint->row ())); + rw.rtrim (); + + int lun = rw.len (); + int idx; + + for (idx = 0; idx < lun; idx++) + { + if (rw[idx] == '@') // gestione data e n. di pagina + + { + switch (rw[idx + 1]) + { + case '#': + rw.overwrite (format ("%-5u", _currentpage), idx++); + break; + case '>': + rw.overwrite (_date.string (4), idx++); + break; + case '<': + rw.overwrite (_date.string (2), idx++); + break; + default: + break; + } + } + } + + if (_printertype == screenvis) + { + if (!_vf->frozen ()) + _vf->add_line (rw); + else + _frozen = TRUE; + return TRUE; + } + + if (_printertype == winprinter) + { + // add line to txt + if (!_frozen) + _txt.append (rw); + return TRUE; + } + + const PrinterDef & pd = get_description (_curprn); + int prvstl = -1; + for (idx = 0; idx < lun; idx++) + { + int cst = rowtoprint->get_style (idx); + if (cst != prvstl) + { + fprintf (_fp, "%s", pd._atstr[normalstyle]); + if (cst != normalstyle) + fprintf (_fp, "%s", pd._atstr[cst]); + } + prvstl = cst; + putc (rw[idx], _fp); + } + if (newline ()) + putc (newline (), _fp); + + return TRUE; +} + +word TPrinter :: +rows_left () + const + { + word left = _formlen - _currentrow - _footersize + 1; + if (_currentrow < 2) + left -= _headersize; + return left; + } + + bool TPrinter ::print (TPrintrow & rowtoprint) +{ + bool ok = TRUE; + + if (_currentrow > _formlen - _footersize) + ok = printfooter (); + +// if (ok && _currentrow <= _headersize) + if (ok && _currentrow == 1) + ok = printheader (); + + if (ok) + { + ok = printrow (&rowtoprint); + _currentrow++; + } + + return ok; +} + +bool TPrinter :: +printheader () +{ + if (_headerhandler) + _headerhandler (*this); + + bool ok = TRUE; + for (int i = 0; i < _headersize && ok; i++) + ok = printrow (getheaderline (i)); + + _currentrow = _headersize + 1; + return ok; +} + +bool TPrinter :: +printfooter () +{ + if (_footerhandler) + _footerhandler (*this); + + bool ok = TRUE; + for (int i = 0; i < _footersize && ok; i++) + ok = printrow (getfooterline (i)); + +#if XVT_OS != XVT_OS_WIN + if (ok) + printformfeed (); +#endif + + _currentrow = 1; + _currentpage++; + + return ok; +} + +bool TPrinter :: +skip (int linestoskip) +{ + int jumpline; + + CHECK (linestoskip >= 0, "Linestoskip can't be negative"); + jumpline = _currentrow + linestoskip; + return jump (jumpline); +} + +bool TPrinter :: +jump (int jumpline) +{ + int i = 0; + bool ok = TRUE; + + CHECK (jumpline >= 0, "Jumpline can't be negative"); + if (jumpline > _formlen - _footersize) + ok = formfeed (); + else + for (i = _currentrow; i < jumpline; i++) + if (!printrow ()) + ok = FALSE; + if (jumpline > _formlen - _footersize) + ok = FALSE; + return ok; +} + +bool TPrinter :: +formfeed () +{ + const int lastrow = _formlen - _footersize; + for (; _currentrow <= lastrow; _currentrow++) + printrow (); + return printfooter (); +} + +void TPrinter :: +reset () +{ + resetheader (); + resetfooter (); + _currentpage = 1; + _currentrow = 1; +} + +bool TPrinter :: +printformfeed () +{ +#if XVT_OS != XVT_OS_WIN + const PrinterDef & pd = get_description (_curprn); + + if (_printertype != screenvis && _hwformfeed) + fprintf (_fp, "%s", (const char *) pd._ffcode); +#endif + return TRUE; +} + +bool TPrinter :: +open () +{ +// qui +#if XVT_OS==XVT_OS_SCOUNIX + if (_printertype == spoolprinter) + { + const PrinterDef & def = get_description (_curprn); + int pfd[2]; + + if (pipe (pfd) == -1) + return error_box ("Impossibile creare processo di stampa " "(pipe)"); + + int ret = fork (); + if (ret == -1) + return error_box ("Impossibile creare processo di stampa " "(fork)"); + + if (ret == 0) + { + if (( :: close (0) != -1) && ( ::dup (pfd[0]) == 0) && + ( :: close (pfd[0]) == 0) && ( ::close (pfd[1]) != -1)) + { + char s0[80]; + + sprintf (s0, "-d%s", (const char *) def._devicename); + if ((def._filtername).not_empty ()) + { + char s1[80]; + sprintf (s1, "-o %s", (const char *) def._filtername); + char *ws[5] = + {"lpr", "-s", s0, s1, NULL}; + execvp (ws[0], ws); + } + else + { + char *ws[4] = + {"lpr", "-s", s0, NULL}; + execvp (ws[0], ws); + } + exit (-1); + } + } + if (( ::close (pfd[0]) == -1) || ((_fp = fdopen (pfd[1], "w")) == NULL)) + return error_box ("Impossibile creare processo di stampa" "(close)"); + } + else +#endif + if (_printertype == screenvis) + { + _vf = new TViswin (NULL, "Anteprima di stampa", TRUE, TRUE, + _linksdescr.items () > 0); + _vf->open_modal (); + } + else if (_printertype == winprinter) + { + // prepare text object for new text + _txt.destroy (); + } + else + { + const PrinterDef & def = get_description (_curprn); + TFilename fname (_printerfile); + + if (_printertype == normprinter) + fname = def._devicename; + _fp = fopen (fname, "w"); + + if (_fp == NULL) + return error_box ("Errore di apertura file stampa: '%s'", + (const char *) fname); + + TString code (def.get_codes (_curcode)); + if (code.not_empty ()) + { + const char *s = code; + fputs (esc ((char *) s), _fp); + } + } + + _currentrow = 1; + _currentpage = 1; + + return _isopen = TRUE; +} + +void TPrinter :: +set () +{ + TMask mask ("bagn001a.msk"); + TToken_string pn1 (50), pn2 (100); + int i; + + MainApp ()->disable_menu_item (M_FILE_PG_SETUP); +#if XVT_OS != XVT_OS_WIN + for (i = 0; i < _printers.items (); i++) + { + pn1.add (i); + pn2.add (((PrinterDef &) _printers[i])._printername); + } + ((TList_field &) (mask.field (MSK_1_PRINTERS))).replace_items (pn1, pn2); + mask.hide (MSK_1_SETUP); + mask.hide (MSK_1_SIZE); + mask.hide (MSK_1_LINES); + pn1 = ""; + pn2 = ""; + for (i = 0; i < ((PrinterDef &) _printers[_curprn])._names.items (); i++) + { + pn1.add (format ("%d", i)); + pn2.add ((TString &) ((PrinterDef &) _printers[_curprn])._names[i]); + } + ((TList_field &) (mask.field (MSK_1_CODES))).replace_items (pn1, pn2); + mask.set_handler (MSK_1_PRINTERS, printers_on_key); + if (_printertype == fileprinter) + mask.set (MSK_1_TYPE, "1"); + else if (_printertype == screenvis) + mask.set (MSK_1_TYPE, "2"); + else + mask.set (MSK_1_TYPE, "0"); + + mask.set (MSK_1_PRINTERS, format ("%d", _curprn)); + mask.set (MSK_1_CODES, format ("%d", _curcode)); + mask.set (MSK_1_FILENAME, _printerfile); + mask.reset (MSK_1_SAVE); + + if (mask.run () == K_ESC) + { + MainApp ()->enable_menu_item (M_FILE_PG_SETUP); + return; + } + if (mask.get (MSK_1_SAVE).not_empty ()) + { + TString s ("printer.def"); +#if XVT_OS == XVT_OS_SCOUNIX + s << format (".%d", getuid ()); +#endif + mask.set_workfile (s); + mask.save (); + } + + // get user choices + + _curprn = atoi (mask.get (MSK_1_PRINTERS)); + PrinterDef & def = (PrinterDef &) get_description (_curprn); + switch (atoi (mask.get (MSK_1_TYPE))) + { + case 0: // stampante + + _printertype = normprinter; + _curcode = atoi (mask.get (MSK_1_CODES)); + switch (atoi (def._printertype)) + { + case 0: + _printertype = normprinter; + break; + case 1: + _printertype = localprinter; + break; + case 2: + _printertype = spoolprinter; + break; + } + break; + case 1: // file + + _printertype = fileprinter; + _printerfile = mask.get (MSK_1_FILENAME); + _curcode = atoi (mask.get (MSK_1_CODES)); + break; + case 2: // video + + _printertype = screenvis; + _curcode = 0; + break; + } + +#else + + static char defPrinter[80]; + static char szDevice[50]; + int defIndex; + + // get default printer driver + GetProfileString ("windows", "device", ",,,", defPrinter, sizeof (defPrinter)); + TString pdev (defPrinter); + GetProfileString ("devices", pdev, "", szDevice, sizeof (szDevice)); + pdev << "," << szDevice; + TToken_string dio (pdev, ','); + + // get printer names + _get_windows_printer_names (pn2); + // determine index of current default printer + for (i = 0; i < pn2.items (); i++) + { + if (TString (dio.get (0)) == TString (pn2.get (i))) + { + defIndex = i; + break; + } + } + if (defIndex == pn2.items ()) + defIndex = 0; // should never happen + + for (i = 0; i < pn2.items (); i++) + pn1.add (i); + + ((TList_field &) (mask.field (MSK_1_PRINTERS))).replace_items (pn1, pn2); + mask.set (MSK_1_PRINTERS, pn1.get (defIndex)); + mask.hide (MSK_1_CODES); + mask.set (MSK_1_ISGRAPHICS, _isgraphics ? "X" : ""); + mask.set (MSK_1_SIZE, format ("%d", _ch_size)); + mask.set (MSK_1_LINES, format ("%d", _lines_per_inch)); + + if (_printertype == fileprinter) + mask.set (MSK_1_TYPE, "1"); + else if (_printertype == screenvis) + mask.set (MSK_1_TYPE, "2"); + else + mask.set (MSK_1_TYPE, "0"); + + mask.set_handler (MSK_1_PRINTERS, set_windows_print_device); + mask.reset (MSK_1_SAVE); + + KEY k; + while ((k = mask.run ()) != K_ESC && k != K_ENTER) + { + if (k == MSK_1_SETUP) + { + if (_print_rcd != NULL) + { + if (page_setup_dlg (_print_rcd)) + { + // see if user has changed printer + int dIndex; + // determine index of currently selected printer + // ACTHUNG! Deep hacking of XVT internals! NON PORTABLE! + for (i = 0; i < pn2.items (); i++) + if (strcmp ((const char *) (_print_rcd + 4), pn2.get (i)) == 0) + { + dIndex = i; + break; + } + mask.set (MSK_1_PRINTERS, pn1.get (dIndex)); + set_win_formlen (); + } + mask.set_focus (); + } + else + beep (); + } + } + if (k == K_ESC) + { + // rimetti come prima + // WriteProfileString("windows","device", pdev); + if (_print_rcd != NULL) + free_print_rcd (_print_rcd); + _print_rcd = get_print_rcd (&_print_rcd_size); + set_win_formlen (); + MainApp ()->enable_menu_item (M_FILE_PG_SETUP); + return; + } + + if (mask.get (MSK_1_SAVE).not_empty ()) + { + TString s ("printer.def"); + mask.set_workfile (s); + mask.save (); + } + + switch (atoi (mask.get (MSK_1_TYPE))) + { + case 0: // stampante + + _printertype = winprinter; + break; + case 1: // file + + _printertype = fileprinter; + _printerfile = mask.get (MSK_1_FILENAME); + _curcode = atoi (mask.get (MSK_1_CODES)); + break; + case 2: // video + + _printertype = screenvis; + _curcode = 0; + break; + } + + _isgraphics = mask.get_bool (MSK_1_ISGRAPHICS); + _ch_size = atoi (mask.get (MSK_1_SIZE)); + _lines_per_inch = atoi (mask.get (MSK_1_LINES)); + set_win_formlen (); + +#endif + + MainApp ()->enable_menu_item (M_FILE_PG_SETUP); +} + +void TPrinter :: +close () +{ + if (isopen () && _currentrow > 1 && + (_footersize || (_printertype != screenvis && _printertype != winprinter))) + formfeed (); + + if (_fp) + { + fclose (_fp); + _fp = NULL; + } + + if (_printertype == screenvis) + { + CHECK (_vf, "VF!"); + _vf->close_print (); + _vf->run (); + if (_vf->is_open ()) + _vf->close_modal (); + delete _vf; + _vf = NULL; + } +#if XVT_OS == XVT_OS_WIN + else if (_printertype == winprinter) + { + PrintWhat._prcd = _print_rcd; + PrintWhat._txt = &_txt; + PrintWhat._graphics = _isgraphics; + PrintWhat._charsize = _ch_size; + start_print_thread (start_winprint, (long) (&PrintWhat)); + } +#endif + else if (_printertype == localprinter) + { +#if XVT_OS == XVT_OS_SCOUNIX + TFilename s1 = tmpnam (NULL); + switch (fork ()) + { + case -1: + break; + case 0: + execlp ("localprint", "localprint", (const char *) s1, NULL); + default: + wait ((int *) NULL); + } + remove (s1); +#endif + } + _isopen = FALSE; +} + +// +// TFile_printer +// + +#include + +#if XVT_OS == XVT_OS_DOS +#define FORMAT_COMMAND "FORMAT" +#else +#define FORMAT_COMMAND "dosformat -fq" +#endif + +const long disk_sizes[] = +{360000, 1200000, 720000, 1400000, 2880000}; + +TFile_printer ::TFile_printer (const char *ffile, const char *label, int len_rec, int num_rec_inizio, int num_rec_fine, int tipo_disco) +{ + set_printtype (fileprinter); + + _num_rec_testa_coda = num_rec_inizio + num_rec_fine; + _file = ffile; + _label = label; + _len_rec = len_rec; + _volume = 1; + _size = disk_sizes[tipo_disco]; + _num_rec_volume = int ((_size / len_rec) - _num_rec_testa_coda); + _nome_file_fissato = TRUE; + _formatta = FALSE; + _label_fissata = TRUE; + +} + +void TFile_printer :: +open () +{ +} + +void TFile_printer :: +close () +{ +} + +bool TFile_printer :: +genera_dischetti () +{ + int r; + + warning_box ("Questa procedura richiede %2d dischetti", + _volume); + + for (int i = 0; i < _tmp_files.items (); i++) + { + // Avvisa l'utente di inserire un dischetto + r = yesno_box ("Inserire il dischetto n. %2d di %2d nel drive %2s", + i + 1, _volume, _drive); + if (!r) + return error_box ("Procedura interrotta!"); + + // e eventualmente lo formatta + if (_formatta) + { + TString dep (30); + if (_label != NULL) + dep << FORMAT_COMMAND << " " << "/v:" << _label << " " << _drive; + else + dep << FORMAT_COMMAND << " " << _drive; + + TExternal_app sys (dep); + sys.run (); + } + + // copia il file sul dischetto + fcopy ((const char *) &_tmp_files[i], (const char *) _drive); + + } + return TRUE; +} + +TFile_printer ::~TFile_printer () +{ +} + +void TFile_printer :: +set () +{ + TMask m ("tfilepr"); + KEY tasto; + int f; + +// + // + // -------------------------------------------------------------------- + // Qui bisogna inserire la lista dei drive disponibili nella maschera + // Per ora tale lista e' fissa e contiene solo A: e B: + // -------------------------------------------------------------------- + // + // + + m.set (F_FILE_DESTINAZIONE, _file); + m.set (F_LABEL, _label); + + if (_nome_file_fissato) + m.disable (F_FILE_DESTINAZIONE); + + if (_label_fissata) + m.disable (F_LABEL); + + tasto = m.run (); + + if (tasto == K_ENTER) + { + f = atoi (m.get (F_FORMATO_DISCO)); + _drive = m.get (F_DRIVE); + _file = m.get (F_FILE_DESTINAZIONE); + _label = m.get (F_LABEL); + _formatta = (bool) (m.get (F_FORMATTA) == "X"); + _size = disk_sizes[f]; + _num_rec_volume = int ((_size / _len_rec) - _num_rec_testa_coda); + } +} + +// +// TFile printer fine +// +>>>>>>>1.2 diff --git a/include/real.cpp b/include/real.cpp index a02c42aa7..3975b3474 100755 --- a/include/real.cpp +++ b/include/real.cpp @@ -1,788 +1,813 @@ #include #include #include - -extern "C" { double pow(double, double); } // Should be #include + +extern "C" +{ + double pow (double, double); +} // Should be #include #include #include HIDDEN real __tmp_real; HIDDEN char __string[80]; -const real ZERO(0.0); +const real ZERO (0.0); -real::real() -{ dzero(ptr()); } - -real::real(const real& b) -{ dcpy(ptr(), b.ptr()); } - -real::real(double a) -{ - dftodr(ptr(), a, 9); // Round the number (1.0 is NOT 0.999999999) - deltrz(ptr(), ptr()); // Delete Trailing zeroes -} - -char* real::eng2ita(char* s) +real ::real () { - if (s) - { - char* dot = strchr(s, '.'); - if (dot) *dot = ','; - } - return s; + dzero (ptr ()); } -char* real::ita2eng(const char* s) +real ::real (const real & b) { - int j = 0; - if (s) for (int i = 0; s[i]; i++) - { - switch(s[i]) - { - case ' ': - case '.': - break; - case ',': - __string[j++] = '.'; - break; - default : - __string[j++] = s[i]; - break; - } - } - __string[j] = '\0'; - return __string; + dcpy (ptr (), b.ptr ()); } -bool real::is_real(const char* s) -{ +real ::real (double a) +{ + dftodr (ptr (), a, 9); // Round the number (1.0 is NOT 0.999999999) + + deltrz (ptr (), ptr ()); // Delete Trailing zeroes + +} + +char *real :: +eng2ita (char *s) +{ + if (s) + { + char *dot = strchr (s, '.'); + if (dot) + *dot = ','; + } + return s; +} + +char *real :: +ita2eng (const char *s) +{ + int j = 0; + if (s) + for (int i = 0; s[i]; i++) + { + switch (s[i]) + { + case ' ': + case '.': + break; + case ',': + __string[j++] = '.'; + break; + default: + __string[j++] = s[i]; + break; + } + } + __string[j] = '\0'; + return __string; +} + +bool real :: +is_real (const char *s) +{ bool ok = FALSE; - if (s) - { - while(*s == ' ') s++; // Remove leading spaces before atod - ok = atod(__tmp_real.ptr(), (char*)s) != GM_NULL; - } - return ok; + if (s) + { + while (*s == ' ') + s++; // Remove leading spaces before atod + + ok = atod (__tmp_real.ptr (), (char *) s) != GM_NULL; + } + return ok; } -real::real(const char* s) +real ::real (const char *s) { - if (s) - while(*s == ' ') s++; // Remove leading spaces before atod + if (s) + while (*s == ' ') + s++; // Remove leading spaces before atod - if (s && *s) - atod(ptr(), (char*)s); - else - dzero(ptr()); + if (s && *s) + atod (ptr (), (char *) s); + else + dzero (ptr ()); } -real& real::operator =(const real& b) +real & real ::operator = (const real & b) { - dcpy(ptr(), b.ptr()); + dcpy (ptr (), b.ptr ()); return *this; } -real& real::operator =(double a) +real & real ::operator = (double a) { - const real n(a); - operator =(n); - return *this; + const real n (a); + operator = (n); + return *this; } -real& real::operator +=(const real& b) +real & real ::operator += (const real & b) { - dadd(ptr(), ptr(), b.ptr()); - return *this; + dadd (ptr (), ptr (), b.ptr ()); + return *this; } -real& real::operator +=(double a) +real & real ::operator += (double a) { - __tmp_real = *this; - adddfd(ptr(), __tmp_real.ptr(), a); - return *this; + __tmp_real = *this; + adddfd (ptr (), __tmp_real.ptr (), a); + return *this; } -real& real::operator -=(const real& b) +real & real ::operator -= (const real & b) { - __tmp_real = *this; - dsub( ptr(), __tmp_real.ptr(), b.ptr()); - return *this; + __tmp_real = *this; + dsub (ptr (), __tmp_real.ptr (), b.ptr ()); + return *this; } -real& real::operator *=(const real& b) +real & real ::operator *= (const real & b) { - dmul( ptr(), ptr(), b.ptr()); - return *this; + dmul (ptr (), ptr (), b.ptr ()); + return *this; } -real& real::operator /=(const real& b) -{ - const DEC* dst = ddiv(ptr(), ptr(), b.ptr()); +real & real ::operator /= (const real & b) +{ + const DEC *dst = ddiv (ptr (), ptr (), b.ptr ()); #ifdef DBG - if (dst == GM_NULL) - { - errname(__string, gmec()); - error_box("Division error: %s", __string); - } + if (dst == GM_NULL) + { + errname (__string, gmec ()); + error_box ("Division error: %s", __string); + } #endif - return *this; + return *this; } -TObject* real::dup() const -{ return new real(*this); } +TObject *real :: +dup () + const + { + return new real (*this); + } -bool real::is_zero() const -{ - return diszero(ptr()); -} + bool real ::is_zero () + const + { + return diszero (ptr ()); + } -int real::sign() const -{ return dsign(ptr()); } + int real ::sign () + const + { + return dsign (ptr ()); + } + real real ::operator - () + const + { + real n; + dchgs (n.ptr (), ptr ()); + return n; + } -real real::operator -() const -{ - real n; - dchgs(n.ptr(), ptr()); - return n; -} - - -int real::integer() const -{ return dtoi(ptr()); } - + int real ::integer () + const + { + return dtoi (ptr ()); + } // Certified 91% -char* real::string(int len, int dec, char pad) const -{ - __tmp_real = *this; - if (dec != UNDEFINED) __tmp_real.round(dec); - else deltrz(__tmp_real.ptr(), __tmp_real.ptr()); + char *real ::string (int len, int dec, char pad) + const + { + __tmp_real = *this; + if (dec != UNDEFINED) + __tmp_real.round (dec); + else + deltrz (__tmp_real.ptr (), __tmp_real.ptr ()); // if (len == 0) - dtoa(__string, __tmp_real.ptr()); -/* - else - { - char f[16]; - if (dec == UNDEFINED) sprintf(f, "%%%dt", len); - else - sprintf(f, "%%%d.%dt", len, dec); - dsprintf(__string, f, __tmp_real.ptr()); - } + dtoa (__string, __tmp_real.ptr ()); +/* + * else + * { + * char f[16]; + * if (dec == UNDEFINED) sprintf(f, "%%%dt", len); + * else + * sprintf(f, "%%%d.%dt", len, dec); + * dsprintf(__string, f, __tmp_real.ptr()); + * } + * + * if (dec <= 0 || dec == UNDEFINED) // Toglie una eventuale parte decimale .00 + * { + * if (dot) + * { + * for (const char* z = dot + 1; *z; z++) + * if (*z != '0') break; + * if (!*z) *dot = '\0'; + * } + * } + */ + int lun = strlen (__string); - if (dec <= 0 || dec == UNDEFINED) // Toglie una eventuale parte decimale .00 - { - if (dot) - { - for (const char* z = dot + 1; *z; z++) - if (*z != '0') break; - if (!*z) *dot = '\0'; - } - } -*/ - int lun = strlen(__string); - -/* - char* dot = strchr(__string, '.'); - - int d = dot ? strlen(dot+1) : 0; // Decimals already there +/* + * char* dot = strchr(__string, '.'); + * + * int d = dot ? strlen(dot+1) : 0; // Decimals already there + * + * if (d < dec) + * { + * if (dot == NULL) __string[lun++] = '.'); + * for (;d < dec; d++) __string[lun++] = '0'; + * __string[lun] = '\0'; + * } else + * if (dec >= 0 && d > dec) + * { + * *(dot+dec+(dec>0)) = '\0'; + * lun = strlen(__string); + * } + */ + if (lun < len) + { + const int delta = len - lun; + for (int i = lun; i >= 0; i--) + __string[i + delta] = __string[i]; + for (i = 0; i < delta; i++) + __string[i] = pad; + } - if (d < dec) - { - if (dot == NULL) __string[lun++] = '.'); - for (;d < dec; d++) __string[lun++] = '0'; - __string[lun] = '\0'; - } else - if (dec >= 0 && d > dec) - { - *(dot+dec+(dec>0)) = '\0'; - lun = strlen(__string); - } -*/ - if (lun < len) - { - const int delta = len - lun; - for (int i = lun; i >= 0; i--) - __string[i+delta] = __string[i]; - for (i = 0; i < delta; i++) __string[i] = pad; - } - - return __string; -} + return __string; + } // Certified 99% -char* real::stringa(int len, int dec, char pad) const - -{ - string(len, dec, pad); - if (dec > 0 || dec == UNDEFINED) - eng2ita(__string); - return __string; -} +char *real :: +stringa (int len, int dec, char pad) + const + { + string (len, dec, pad); + if (dec > 0 || dec == UNDEFINED) + eng2ita (__string); + return __string; + } // Certified 75% -char* real::literals() const -{ - const char* primi20[] = { "", "uno","due","tre","quattro", - "cinque","sei","sette","otto", - "nove","dieci","undici","dodici", - "tredici","quattordici","quindici","sedici" - "diciassette","diciotto","diciannove" }; - const char* decine[] = { "zero", "dieci", "venti", "trenta", "quaranta", - "cinquanta", "sessanta", "settanta", "ottanta", - "novanta", "cento" }; - const char* uni[] = { "uno", "mille", "unmilione", "unmiliardo" }; + char *real ::literals () + const + { + const char *primi20[] = + {"", "uno", "due", "tre", "quattro", + "cinque", "sei", "sette", "otto", + "nove", "dieci", "undici", "dodici", + "tredici", "quattordici", "quindici", "sedici" + "diciassette", "diciotto", "diciannove"}; + const char *decine[] = + {"zero", "dieci", "venti", "trenta", "quaranta", + "cinquanta", "sessanta", "settanta", "ottanta", + "novanta", "cento"}; + const char *uni[] = + {"uno", "mille", "unmilione", "unmiliardo"}; - const char* potenze[] = { "", "mila", "milioni", "miliardi" }; + const char *potenze[] = + {"", "mila", "milioni", "miliardi"}; - __tmp_real = *this; - __tmp_real.round(0); - TString r(__tmp_real.string(0, 0)); - const bool negativo = r[0] == '-'; - if (negativo) r.ltrim(1); + __tmp_real = *this; + __tmp_real.round (0); + TString r (__tmp_real.string (0, 0)); + const bool negativo = r[0] == '-'; + if (negativo) + r.ltrim (1); - TFixed_string risultato(__string, 80); - risultato.cut(0); + TFixed_string risultato (__string, 80); + risultato.cut (0); - TString centinaia(16); + TString centinaia (16); - for (int migliaia = 0; ; migliaia++) - { - int v = r.len()-3 ; - if (v < -2) break; + for (int migliaia = 0;; migliaia++) + { + int v = r.len () - 3; + if (v < -2) + break; - if (v < 0) v = 0; - const int val = atoi(&r[v]); - r.cut(v); // Elimina ultimi 3 caratteri + if (v < 0) + v = 0; + const int val = atoi (&r[v]); + r.cut (v); // Elimina ultimi 3 caratteri - v = val; - if (v >= 100) - { - const int c = v/100; - if (c > 1) centinaia = primi20[c]; - else centinaia.cut(0); - v -= c*100; - centinaia << "cento"; - } - const int d = v/10; - if (d > 1) - { - centinaia << decine[d]; - v -= d*10; - } - if (v != 1) - { - centinaia << primi20[v] << potenze[migliaia]; - } else - if (val > 1) - { - if (d > 1) centinaia.cut(centinaia.len()-1); - centinaia << "un" << (migliaia ? potenze[migliaia] : "o"); - } else centinaia = uni[migliaia]; + v = val; + if (v >= 100) + { + const int c = v / 100; + if (c > 1) + centinaia = primi20[c]; + else + centinaia.cut (0); + v -= c * 100; + centinaia << "cento"; + } + const int d = v / 10; + if (d > 1) + { + centinaia << decine[d]; + v -= d * 10; + } + if (v != 1) + { + centinaia << primi20[v] << potenze[migliaia]; + } + else if (val > 1) + { + if (d > 1) + centinaia.cut (centinaia.len () - 1); + centinaia << "un" << (migliaia ? potenze[migliaia] : "o"); + } + else + centinaia = uni[migliaia]; - risultato.insert(centinaia, 0); - } - - if (negativo) risultato.insert("meno", 0); - return __string; -} + risultato.insert (centinaia, 0); + } + if (negativo) + risultato.insert ("meno", 0); + return __string; + } // Certified 75% -char* real::points(int dec) const +char *real :: +points (int dec) + const + { + const char *str = stringa (); + const int neg = (*str == '-') ? 1 : 0; + TFixed_string n ((char *) str, 24); + int i; + + int dot = n.find (','); + if (dot < 0) + dot = n.len (); + + if (dec > 0) + { + if (n[dot] == '\0') + n << ','; + const int d = strlen (str + dot + 1); // Decimals already + // there + + if (d <= dec) + for (i = d; i < dec; i++) + n << '0'; + else + n.cut (dot + dec + 1); + } + + for (i = dot - 3; i > neg; i -= 3) + n.insert (".", i); + + return __string; + } + +HIDDEN int +get_picture_decimals (const TString & picture) { - const char* str = stringa(); - const int neg = (*str == '-') ? 1 : 0; - TFixed_string n((char*)str, 24); - int i; - - int dot = n.find(','); - if (dot < 0) dot = n.len(); - - if (dec > 0) - { - if (n[dot] == '\0') n << ','; - const int d = strlen(str+dot+1); // Decimals already there - if (d <= dec) - for (i = d; i < dec; i++) n << '0'; - else - n.cut(dot+dec+1); - } - - for (i = dot-3; i > neg; i -= 3) - n.insert(".", i); - - return __string; + int decimali = 0; + const int virgola = picture.find (','); + if (virgola >= 0) + { + const int len = picture.len (); + for (int i = virgola + 1; i < len; i++) + if (strchr ("#@~", picture[i])) + decimali++; + } + return decimali; } +char *real :: +string (const char *picture) + const + { + if (*picture == '\0') + return string (); + if (*picture == '.') + return points (atoi (picture + 1)); + if (strcmp (picture, "LETTERE") == 0) + return literals (); + + TString v (string ()); + TString f (picture); + + const int voluti = get_picture_decimals (f); + const int virgola = v.find ('.'); + int decimali = (virgola >= 0) ? v.len () - virgola - 1 : 0; + + for (; voluti > decimali; decimali++) + v << '@'; + if (voluti < decimali) + v.cut (virgola + voluti + (voluti > 0)); + + int j = v.len () - 1; + for (int i = f.len () - 1; i >= 0 && j >= 0; i--) + { + char &z = f[i]; + if (strchr ("#@~", z)) + { + char c = v[j--]; + if (v[j] == '.') + j--; + if (z == '~') + c = ' '; + else if (c == '@') + c = (z == '@') ? '0' : ' '; + z = c; + } + } + for (; i >= 0; i--) + switch (f[i]) + { + case '#': + case '~': + case '.': + f[i] = ' '; + break; + case '@': + f[i] = '0'; + break; + default: + break; + } + return strcpy (__string, f); + } + +ostream & operator << (ostream & out, const real & a) -HIDDEN int get_picture_decimals(const TString& picture) { - int decimali = 0; - const int virgola = picture.find(','); - if (virgola >= 0) - { - const int len = picture.len(); - for (int i = virgola+1; i < len; i++) - if (strchr("#@~", picture[i])) decimali++; - } - return decimali; + return out << a.string (); } +istream & operator >> (istream & in, real & a) -char* real::string(const char* picture) const { - if (*picture == '\0') return string(); - if (*picture == '.') return points(atoi(picture+1)); - if (strcmp(picture, "LETTERE") == 0) return literals(); + in >> __string; + atod (a.ptr (), __string); + return in; +} - TString v(string()); - TString f(picture); +int real :: +precision () +{ + return dprec (ptr ()); +} - const int voluti = get_picture_decimals(f); - const int virgola = v.find('.'); - int decimali = (virgola >= 0) ? v.len()-virgola-1 : 0; +real & real ::round (int prec) +{ + if (prec < 0) + { + const double p = ::pow (10.0, -prec); + divdfd (ptr (), ptr (), p); + dround (ptr (), ptr (), 0); + muldfd (ptr (), ptr (), p); + } + else + dround (ptr (), ptr (), prec); + return *this; +} - for ( ;voluti > decimali; decimali++) v << '@'; - if (voluti < decimali) - v.cut(virgola + voluti + (voluti > 0)); +real & real ::ceil (int prec) +{ + double p = 1.0; + if (prec) + { + p = ::pow (10.0, -prec); + divdfd (ptr (), ptr (), p); + } - int j = v.len()-1; - for (int i = f.len()-1; i >= 0 && j >= 0; i--) - { - char& z = f[i]; - if (strchr("#@~", z)) - { - char c = v[j--]; - if (v[j] == '.') j--; - if (z == '~') c = ' '; else - if (c == '@') c = (z == '@') ? '0' : ' '; - z = c; + DEC integer; + dint (&integer, ptr ()); // Extract the integer part + + if (disne (ptr (), &integer)) // If different ... + + addid (ptr (), &integer, 1); // add 1 + + if (prec) + muldfd (ptr (), ptr (), p); + + return *this; +} + +real & real ::trunc (int prec) +{ + dtrunc (ptr (), ptr (), prec); + return *this; +} + +real operator + (const real & a, const real & b) + +{ + dadd (__tmp_real.ptr (), a.ptr (), b.ptr ()); + return __tmp_real; +} + +real operator + (double a, const real & b) + +{ + __tmp_real = a; + return __tmp_real += b; +} + +real operator + (const real & a, double b) + +{ + __tmp_real = a; + return __tmp_real += b; +} + +real operator - (const real & a, const real & b) + +{ + dsub (__tmp_real.ptr (), a.ptr (), b.ptr ()); + return __tmp_real; +} + +real operator - (double a, const real & b) + +{ + __tmp_real = a; + dsub (__tmp_real.ptr (), __tmp_real.ptr (), b.ptr ()); + return __tmp_real; +} + +real operator - (const real & a, double b) + +{ + __tmp_real = b; + return __tmp_real -= a; +} + +real operator *(const real & a, const real & b) + +{ + dmul (__tmp_real.ptr (), a.ptr (), b.ptr ()); + return __tmp_real; +} + +real operator *(double a, const real & b) + +{ + muldfd (__tmp_real.ptr (), b.ptr (), a); + return __tmp_real; +} + +real operator *(const real & a, double b) + +{ + muldfd (__tmp_real.ptr (), a.ptr (), b); + return __tmp_real; +} + +real operator / (const real & a, const real & b) + +{ + ddiv (__tmp_real.ptr (), a.ptr (), b.ptr ()); + return __tmp_real; +} + +real operator / (double a, const real & b) + +{ + __tmp_real = a; + ddiv (__tmp_real.ptr (), __tmp_real.ptr (), b.ptr ()); + return __tmp_real; +} + +real operator / (const real & a, double b) + +{ + __tmp_real = b; + ddiv (__tmp_real.ptr (), a.ptr (), __tmp_real.ptr ()); + return __tmp_real; +} + +bool operator > (const real & a, const real & b) +{ + return disgt (a.ptr (), b.ptr ()); +} + +bool operator > (double a, const real & b) +{ +// dftod(__tmp_real.ptr(), a); + // return disgt(__tmp_real.ptr(), b.ptr()); + const double n = dtodf (b.ptr ()); + return a > n; +} + +bool operator < (const real & a, const real & b) + +{ + return dislt (a.ptr (), b.ptr ()); +} + +bool operator < (double a, const real & b) + +{ +// dftod(__tmp_real.ptr(), a); + // return dislt(__tmp_real.ptr(), b.ptr()); + const double n = dtodf (b.ptr ()); + return a < n; +} + +bool operator >= (const real & a, const real & b) + +{ + return disge (a.ptr (), b.ptr ()); +} + +bool operator >= (double a, const real & b) + +{ +// dftod(__tmp_real.ptr(), a); + // return disge(__tmp_real.ptr(), b.ptr()); + const double n = dtodf (b.ptr ()); + return a >= n; +} + +bool operator <= (const real & a, const real & b) + +{ + return disle (a.ptr (), b.ptr ()); +} + +bool operator <= (double a, const real & b) + +{ +// dftod(__tmp_real.ptr(), a); + // return disle(__tmp_real.ptr(), b.ptr()); + const double n = dtodf (b.ptr ()); + return a <= n; +} + +bool operator == (const real & a, const real & b) +{ + return diseq (a.ptr (), b.ptr ()); } - } - for (; i >= 0; i--) - switch (f[i]) - { - case '#': - case '~': - case '.': f[i] = ' '; break; - case '@': f[i] = '0'; break; - default :break; - } - return strcpy(__string, f); -} + bool operator == (double a, const real & b) + { + const double n = dtodf (b.ptr ()); + return a == n; + } -ostream& operator <<(ostream& out, const real& a) + bool operator != (const real & a, const real & b) -{ - return out << a.string(); -} + { + return !diseq (a.ptr (), b.ptr ()); + } + bool operator != (double a, const real & b) -istream& operator >>(istream& in, real& a) + { + const double n = dtodf (b.ptr ()); + return a != n; + } -{ - in >> __string; - atod(a.ptr(), __string); - return in; -} + real operator % (const real & a, const long b) + { + dmodl (__tmp_real.ptr (), a.ptr (), b); + return __tmp_real; + } -int real::precision() -{ - return dprec(ptr()); -} + void swap (real & a, real & b) + { + SwapDecimal (a.ptr (), b.ptr ()); + } -real& real::round(int prec) -{ - if (prec < 0) - { - const double p = ::pow(10.0, -prec); - divdfd(ptr(), ptr(), p); - dround(ptr(), ptr(), 0); - muldfd(ptr(), ptr(), p); - } - else - dround(ptr(), ptr(), prec); - return *this; -} + real fnc_min (const real & a, const real & b) + { + dmin (__tmp_real.ptr (), a.ptr (), b.ptr ()); + return __tmp_real; + } -real& real::ceil(int prec) -{ - double p = 1.0; - if (prec) - { - p = ::pow(10.0, -prec); - divdfd(ptr(), ptr(), p); - } + real fnc_max (const real & a, const real & b) - DEC integer; dint(&integer, ptr()); // Extract the integer part - if (disne(ptr(), &integer)) // If different ... - addid(ptr(), &integer, 1); // add 1 + { + dmax (__tmp_real.ptr (), a.ptr (), b.ptr ()); + return __tmp_real; + } - if (prec) - muldfd(ptr(), ptr(), p); + real sqrt (const real & a) - return *this; -} + { + dsqrt (__tmp_real.ptr (), a.ptr ()); + return __tmp_real; + } + real sqr (const real & a) -real& real::trunc(int prec) -{ - dtrunc(ptr(), ptr(), prec); - return *this; -} + { + dmul (__tmp_real.ptr (), a.ptr (), a.ptr ()); + return __tmp_real; + } + real exp10 (const real & a) -real operator +(const real& a, const real& b) + { + dalog (__tmp_real.ptr (), a.ptr ()); + return __tmp_real; + } -{ - dadd(__tmp_real.ptr(), a.ptr(), b.ptr()); - return __tmp_real; -} + real pow (const real & a, const real & b) + { + dpow (__tmp_real.ptr (), a.ptr (), b.ptr ()); + return __tmp_real; + } -real operator +(double a, const real& b) + real exp (const real & a) -{ - __tmp_real = a; - return __tmp_real += b; -} + { + dexp (__tmp_real.ptr (), a.ptr ()); + return __tmp_real; + } + real log10 (const real & a) -real operator +(const real& a, double b) + { + dlog (__tmp_real.ptr (), a.ptr ()); + return __tmp_real; + } -{ - __tmp_real = a; - return __tmp_real += b; -} + real log (const real & a) + { + dln (__tmp_real.ptr (), a.ptr ()); + return __tmp_real; + } -real operator -(const real& a, const real& b) + real sin (const real & a) -{ - dsub(__tmp_real.ptr(), a.ptr(), b.ptr()); - return __tmp_real; -} + { + dsin (__tmp_real.ptr (), a.ptr ()); + return __tmp_real; + } + real cos (const real & a) -real operator -(double a, const real& b) + { + dcos (__tmp_real.ptr (), a.ptr ()); + return __tmp_real; + } -{ - __tmp_real = a; - dsub(__tmp_real.ptr(), __tmp_real.ptr(), b.ptr()); - return __tmp_real; -} + real tan (const real & a) + { + dtan (__tmp_real.ptr (), a.ptr ()); + return __tmp_real; + } -real operator -(const real& a, double b) - -{ - __tmp_real = b; - return __tmp_real -= a; -} - - -real operator *(const real& a, const real& b) - -{ - dmul(__tmp_real.ptr(), a.ptr(), b.ptr()); - return __tmp_real; -} - - -real operator *(double a, const real& b) - -{ - muldfd(__tmp_real.ptr(), b.ptr(), a); - return __tmp_real; -} - - -real operator *(const real& a, double b) - -{ - muldfd(__tmp_real.ptr(), a.ptr(), b); - return __tmp_real; -} - - -real operator /(const real& a, const real& b) - -{ - ddiv(__tmp_real.ptr(), a.ptr(), b.ptr()); - return __tmp_real; -} - - -real operator /(double a, const real& b) - -{ - __tmp_real = a; - ddiv(__tmp_real.ptr(), __tmp_real.ptr(), b.ptr()); - return __tmp_real; -} - - -real operator /(const real& a, double b) - -{ - __tmp_real = b; - ddiv(__tmp_real.ptr(), a.ptr(), __tmp_real.ptr()); - return __tmp_real; -} - - -bool operator >(const real& a, const real& b) -{ - return disgt(a.ptr(), b.ptr()); -} - - -bool operator >(double a, const real& b) -{ -// dftod(__tmp_real.ptr(), a); -// return disgt(__tmp_real.ptr(), b.ptr()); - const double n = dtodf(b.ptr()); - return a > n; -} - - -bool operator <(const real& a, const real& b) - -{ - return dislt(a.ptr(), b.ptr()); -} - - -bool operator <(double a, const real& b) - -{ -// dftod(__tmp_real.ptr(), a); -// return dislt(__tmp_real.ptr(), b.ptr()); - const double n = dtodf(b.ptr()); - return a < n; -} - - -bool operator >=(const real& a, const real& b) - -{ - return disge(a.ptr(), b.ptr()); -} - - -bool operator >=(double a, const real& b) - -{ -// dftod(__tmp_real.ptr(), a); -// return disge(__tmp_real.ptr(), b.ptr()); - const double n = dtodf(b.ptr()); - return a >= n; -} - - -bool operator <=(const real& a, const real& b) - -{ - return disle(a.ptr(), b.ptr()); -} - - -bool operator <=(double a, const real& b) - -{ -// dftod(__tmp_real.ptr(), a); -// return disle(__tmp_real.ptr(), b.ptr()); - const double n = dtodf(b.ptr()); - return a <= n; -} - - -bool operator ==(const real& a, const real& b) -{ - return diseq(a.ptr(), b.ptr()); -} - - -bool operator ==(double a, const real& b) -{ - const double n = dtodf(b.ptr()); - return a == n; -} - - -bool operator !=(const real& a, const real& b) - -{ - return !diseq(a.ptr(), b.ptr()); -} - - -bool operator !=(double a, const real& b) - -{ - const double n = dtodf(b.ptr()); - return a != n; -} - - -real operator %(const real& a, const long b) - -{ - dmodl(__tmp_real.ptr(), a.ptr(), b); - return __tmp_real; -} - - -void swap(real& a, real& b) - -{ - SwapDecimal(a.ptr(), b.ptr()); -} - - -real fnc_min(const real& a, const real& b) - -{ - dmin(__tmp_real.ptr(), a.ptr(), b.ptr()); - return __tmp_real; -} - - -real fnc_max(const real& a, const real& b) - -{ - dmax(__tmp_real.ptr(), a.ptr(), b.ptr()); - return __tmp_real; -} - - -real sqrt(const real& a) - -{ - dsqrt(__tmp_real.ptr(), a.ptr()); - return __tmp_real; -} - - -real sqr(const real& a) - -{ - dmul(__tmp_real.ptr(), a.ptr(), a.ptr()); - return __tmp_real; -} - - -real exp10(const real& a) - -{ - dalog(__tmp_real.ptr(), a.ptr()); - return __tmp_real; -} - - -real pow(const real& a, const real& b) - -{ - dpow(__tmp_real.ptr(), a.ptr(), b.ptr()); - return __tmp_real; -} - - -real exp(const real& a) - -{ - dexp(__tmp_real.ptr(), a.ptr()); - return __tmp_real; -} - -real log10(const real& a) - -{ - dlog(__tmp_real.ptr(), a.ptr()); - return __tmp_real; -} - - -real log(const real& a) - -{ - dln(__tmp_real.ptr(), a.ptr()); - return __tmp_real; -} - - -real sin(const real& a) - -{ - dsin(__tmp_real.ptr(), a.ptr()); - return __tmp_real; -} - - -real cos(const real& a) - -{ - dcos(__tmp_real.ptr(), a.ptr()); - return __tmp_real; -} - - -real tan(const real& a) - -{ - dtan(__tmp_real.ptr(), a.ptr()); - return __tmp_real; -} - - -real abs(const real& a) - -{ - dabs(__tmp_real.ptr(), a.ptr()); - return __tmp_real; -} + real abs (const real & a) + { + dabs (__tmp_real.ptr (), a.ptr ()); + return __tmp_real; + } /////////////////////////////////////////////////////////// // Distrib // Oggetto per dividere un real in varie sue percentuali // in modo che la loro somma dia sempre il real di partenza -/////////////////////////////////////////////////////////// +// ///////////////////////////////////////////////////////// - -void TDistrib::add(real slice) -{ - if (slice > real(1.0)) +void TDistrib ::add (real slice) + { + if (slice > real (1.0)) slice /= 100.0; - CHECK(!_ready,"TDistrib: les jeux sont faits"); - _slices.add(slice); -} - -real TDistrib::get() -{ - _ready = TRUE; - CHECK(_current < _slices.items(), "TDistrib: too many gets"); - real r = _tot*((real&)_slices[_current++]); - r.round(_decs); - if (r > _tot - _prog) { r = _tot-_prog; _prog = _tot; } - else _prog += r; - return r; -} - -void TDistrib::init(const real& r) -{ - _current = 0; _prog = 0; - _tot = r; _ready = FALSE; -} + CHECK (!_ready, "TDistrib: les jeux sont faits"); + _slices.add (slice); + } +real TDistrib ::get () + { + _ready = TRUE; + CHECK (_current < _slices.items (), "TDistrib: too many gets"); + real r = _tot * ((real &) _slices[_current++]); + r.round (_decs); + if (r > _tot - _prog) + { + r = _tot - _prog; _prog = _tot; + } + else + _prog += r; + return r; + } +void TDistrib ::init (const real & r) + { + _current = 0; _prog = 0; + _tot = r; _ready = FALSE; + } diff --git a/include/text.cpp b/include/text.cpp index 5eee132da..a0198ee41 100755 --- a/include/text.cpp +++ b/include/text.cpp @@ -337,7 +337,7 @@ append (const char *l) { TToken_string *tts = new TToken_string (50); tts->add (_lines - 1l); // line number - // + // tts->add (len); tts->add (len + (int) strlen (cp)); diff --git a/include/viswin.cpp b/include/viswin.cpp index 5b63c428a..f2acba1ad 100755 --- a/include/viswin.cpp +++ b/include/viswin.cpp @@ -982,7 +982,7 @@ handler (WINDOW win, EVENT * ep) release_mouse (); if (ep->v.mouse.button == 0) // left button: text selection/move - // point + // point { p = ep->v.mouse.where;