469 lines
18 KiB
C++
Executable File
469 lines
18 KiB
C++
Executable File
// trattasi di -*-c++-*-
|
|
#ifndef __PRINTAPP_H
|
|
#define __PRINTAPP_H
|
|
|
|
#ifndef __APPLICATION_H
|
|
#include <applicat.h>
|
|
#endif
|
|
|
|
#ifndef __PRINTER_H
|
|
#include <printer.h>
|
|
#endif
|
|
|
|
#ifndef __RELATION_H
|
|
#include <relation.h>
|
|
#endif
|
|
|
|
#ifndef __STRINGS_H
|
|
#include <strings.h>
|
|
#endif
|
|
|
|
// compatibility
|
|
#define TPrintapp TPrint_application
|
|
|
|
|
|
enum print_action { REPEAT_PAGE, NEXT_PAGE };
|
|
|
|
// user functions to pass field informations to setrow()
|
|
// no class or nice C++ interface since varargs is nasty
|
|
|
|
// FLD(Num.logico, Nome campo [, da [, a]])
|
|
const char* FLD(int lognum, const char* f, int from = -1, int to = -1);
|
|
// FLD(Num. logico, Nome campo numerico, Picture string)
|
|
const char* FLD(int lognum, const char* f, const char* picture);
|
|
// FLD(Nome tabella, Nome campo numerico, Picture string)
|
|
const char* FLD(const char* tabname, const char* f, const char* picture);
|
|
// FLD(Num.logico, Nome campo [, da [, a]])
|
|
const char* FLD(const char* tabname, const char* f, int from = -1, int to = -1);
|
|
|
|
struct link_item {
|
|
int _logicnum;
|
|
link_item* _son;
|
|
link_item* _brother;
|
|
int _cnt;
|
|
|
|
link_item(int l)
|
|
{ _logicnum = l; _son = NULL; _brother = NULL; _cnt = 0; }
|
|
};
|
|
|
|
class TProgind;
|
|
|
|
|
|
class TPrint_application : public TApplication
|
|
{
|
|
TArray _rows; // rows descriptor
|
|
TArray _cursors; // cursor array
|
|
TCursor* _cur; // current cursor
|
|
TArray _transtab; // field translation table
|
|
TArray _header; // header lines
|
|
TArray _footer; // footer lines
|
|
int _currow; // current print row
|
|
TPrintstyle _curstyle; // current print style
|
|
bool _auto_ff; // automatic form feed after each page
|
|
const char* _wmess; // wait message for progind
|
|
bool _wbar; // bar y/n for progind
|
|
bool _wcancel; // cancel button enabled
|
|
int _wthr; // minimum # of items to show print progind
|
|
const char* _confpr; // config filename for printer
|
|
char _fillchar; // fill character for empty fields
|
|
link_item* _pr_tree; // functions for autom. printing of relations
|
|
int _maxrow; // reference to maxrow
|
|
int _cur_file;
|
|
bool _print_defined;
|
|
bool _force_progind;
|
|
bool _force_setpage;
|
|
bool _print_zero;
|
|
TProgind* _prind;
|
|
const char* _picture;
|
|
MENU_TAG _last_choice;
|
|
|
|
// set the printer
|
|
void set_printer() { printer().set(); }
|
|
// print a single record; does not advance cursor
|
|
// returns failure or success
|
|
bool print_one(int file);
|
|
// to be documented but very fig
|
|
bool print_tree(link_item* head);
|
|
|
|
static void _pp_header(TPrinter& pr);
|
|
static void _pp_footer(TPrinter& pr);
|
|
static void _pp_link(int id, const char* s);
|
|
|
|
link_item* _look_print_node(link_item* head, int logicnum);
|
|
void _reset_tree(link_item* head);
|
|
virtual bool create();
|
|
virtual bool destroy();
|
|
|
|
|
|
protected:
|
|
|
|
// ****************************************************
|
|
// ISTRUZIONI PER l'USO
|
|
// ****************************************************
|
|
//
|
|
// La Printapp, saggiamente, consente di operare su uno
|
|
// o piu' cursori stampando automaticamente anche files
|
|
// collegati. La sequenza delle operazioni e' la seguente:
|
|
//
|
|
// 1) Derivare una classe da TPrint_application
|
|
// 2) Implementare user_create() e user_destroy();
|
|
// Nella user_create() si creino i
|
|
// necessari cursori, e li si dia in pasto a Printapp
|
|
// usando add_cursor(). Si puo' fare add_cursor(new TCursor(...))
|
|
// dato che il cursore viene distrutto automaticamente.
|
|
// 3) Per ciascun file del cursore che si desidera porre
|
|
// nell'albero di stampa, si faccia add_file(logicnum [,from]);
|
|
// [from] sara' il file a cui e' collegato nella relazione.
|
|
// add_file VA FATTA anche per il file principale, se no
|
|
// non stampera' nulla;
|
|
// *********************************************************
|
|
// FUNZIONI VIRTUALI OBBLIGATORIE
|
|
// *********************************************************
|
|
// 4) Si definiscono le necessarie funzioni virtuali: e'
|
|
// sicuramente necessaria la set_page(file) nella quale
|
|
// si metteranno (sotto if o switch) le istruzioni
|
|
// set_row (vedi sotto) corrispondenti alla pagina
|
|
// logica relativa a ciascun record di ogni file da stampare.
|
|
// Va definita anche set_print() in cui si presentera' ;a
|
|
// maschera di scelta se necessaria o una box yes_no;
|
|
// Ritornando TRUE da set_print la stampa viene eseguita
|
|
// automaticamente (in genere ritorna FALSE se l'utente
|
|
// annulla la stampa con ESC.)
|
|
//
|
|
// Alla set_page, come alle pre_ e post_ process, viene
|
|
// passato 0 se il cursore attuale e' nullo (vedi sotto).
|
|
// *********************************************************
|
|
// FUNZIONI VIRTUALI FACOLTATIVE
|
|
// *********************************************************
|
|
// 5) Le varie funzioni pre_ e post_ process _page e _print
|
|
// vengono chiamate prima e dopo la stampa di ogni record
|
|
// o gruppo di record relativo alla relazione immessa;
|
|
// ad esempio, postprocess_print() viene chiamata per il
|
|
// file principale una volta dopo l'intera stampa; per
|
|
// un file collegato nella relazione, e' chiamata tante
|
|
// volte quanti gruppi di almeno un record esistono per
|
|
// record del file genitore. Qui si possono modificare
|
|
// righe, calcolare totali etc. A queste funzioni
|
|
// viene sempre passato il file (logicnum) in corso di stampa e
|
|
// un contatore che indica quante volte la stampa e' stata
|
|
// ripetuta. le pre_ ritornano TRUE o FALSE, nell'ultimo
|
|
// caso interrompono la stampa; le post_ ritornano
|
|
// NEXT_PAGE (comportamento normale) o REPEAT_PAGE
|
|
// (indovina cosa fa).
|
|
// 6) set_print() viene chiamata dalla voce Selezione,
|
|
// unica del secondo menu. E' il posto dove mettere
|
|
// una buona maschera di selezione di cosa stampare.
|
|
// Alla fine, si esegua enable_print_menu() per
|
|
// abilitare la voce Stampa, inizialmente inattiva.
|
|
// 7) cancel_hook() permette di intercettare la
|
|
// cancellazione della stampa; ritornando TRUE
|
|
// la stampa viene effettivamente cancellata
|
|
// Tutti i parametri relativi al progress indicator
|
|
// vengono settati da funzioni apposite (vedi oltre)
|
|
// ****************************************************
|
|
// Molte altre minchiatine (form feed automatici, header,
|
|
// footer etc) sono spiegate nel seguito
|
|
// ****************************************************
|
|
|
|
virtual void user_create() {}
|
|
virtual void user_destroy() {}
|
|
|
|
// set print, bound to menu :Selezione:Stampa
|
|
// chiamata automaticamente dopo user_create()
|
|
virtual bool set_print(int i = 1) { return FALSE; }
|
|
|
|
// set_row functions MUST be called here in a switch
|
|
// for each particular file being printed
|
|
virtual void set_page(int file, int cnt) {}
|
|
|
|
// called before processing each page
|
|
// used to set print strings from tables or files
|
|
// not included in relation
|
|
// returning FALSE cancels page printing
|
|
// counter is the current print page number
|
|
virtual bool preprocess_page(int file, int counter)
|
|
{ return TRUE; }
|
|
|
|
// same before each print request
|
|
// e.g. to initialize counters
|
|
// returning FALSE cancels print request or subtree
|
|
virtual bool preprocess_print(int file, int counter)
|
|
{ return TRUE; }
|
|
|
|
// postprocessing; returning REPEAT_PAGE reprints the
|
|
// whole page (after all sons are printed) or print
|
|
// counter is the current page or print number
|
|
virtual print_action postprocess_page(int file, int counter)
|
|
{ return NEXT_PAGE; }
|
|
virtual print_action postprocess_print(int file, int counter)
|
|
{ return NEXT_PAGE; }
|
|
// executed after all print job is completed
|
|
virtual void postclose_print() {}
|
|
|
|
// called when LINK button is pressed with active selection in
|
|
// preview window
|
|
virtual void process_link(int id, const char* text) {}
|
|
|
|
|
|
// called when user cancels print; returning TRUE
|
|
// actually stops printing; not called if no cancel
|
|
virtual bool cancel_hook() {return TRUE;}
|
|
|
|
// bound to TApplication print menu
|
|
// redefined ONLY for very special purposes
|
|
virtual void print();
|
|
|
|
// bound to <select> menu and automatically called after
|
|
// user_create()
|
|
void do_print(int n);
|
|
|
|
public:
|
|
|
|
// --------------------------------------------------------------
|
|
// COME SETTARE LE RIGHE DI STAMPA
|
|
// --------------------------------------------------------------
|
|
// setrow() si usa come una printf per settare le righe di stampa
|
|
// che vengono stampate da print()
|
|
// I codici per gli argomenti variabili sono di 3 tipi:
|
|
// @ si usa per stampare campi di database o informazioni di controllo
|
|
// posizione carrello e font
|
|
// ACHTUNG: i codici di formato sono diversi da quelli di printf e
|
|
// sono elencati sotto. Per i campi di database occorre che il codice
|
|
// sia accoppiato ad una delle funzioni FLD() passata come argomento;
|
|
// questa provoca la stampa di campi della relazione corrente,
|
|
// posizionata come e' stato deciso nell'inizializzazione
|
|
// % si usa esattamente come in una printf con un plus: se il codice di
|
|
// formato e' maiuscolo (es. S per stringa, D per intero) viene
|
|
// ignorato il carattere di riempimento eventualmente specificato
|
|
// con set_fillchar. Cio' vale anche per i codici @ (vedi)
|
|
// E' possibile usare due codici aggiuntivi: r(R) e t(T). A questi
|
|
// va fatto seguire un PUNTATORE a real o a TString. Il formato
|
|
// viene interpretato con le stesse regole di %t in dsprintf per real
|
|
// (come %d o %f) e di %s per TString. Il puntatore NON
|
|
// viene memorizzato; per questo occorre il codice # (sotto).
|
|
// # si usa come % (stessi codici di printf) ma memorizza gli argomenti
|
|
// per riferimento: ovvero, ogni volta che la riga viene stampata
|
|
// viene stampato il contenuto in quel momento (che si puo' cambiare
|
|
// in una delle pre- o post- process). Cio' implica che:
|
|
// 1) gli argomenti vanno passati per RIFERIMENTO (set_row(1,"#5d",&i))
|
|
// 2) i puntatori devono rimanere validi e costanti tra la set_row e
|
|
// la fine della stampa
|
|
// Quindi, attenzione a %s con TString ridimensionate; si possono
|
|
// usare solo se predimensionate alla dimensione massima, ma e' meglio
|
|
// usare char* o il codice apposito. I codici #r e #t prendono puntatori a
|
|
// real e a TString, memorizzandoli. Non ci sono problemi con la resize.
|
|
// Comunque, il modo corretto di adoperare il codice # e'
|
|
// usarlo solo per stampare MEMBRI della classe derivata da TPrint_application
|
|
// ----------------------------------------------
|
|
// field codes (match one of FLD() functions)
|
|
// @@ -> @
|
|
// @[n[,{l|c|r}]s -> STRING: n = pad, lcr = alignment
|
|
// @{[n[.d=0]]|[n[,{l|c|r}]]p}n
|
|
// -> NUMBER: n = digits, d = decimals
|
|
// p = picture string (first matching arg)
|
|
// @[l]d -> DATE: l = full year
|
|
// @f -> BOOL: prints si/no
|
|
// @[n,{l|c|r}]t -> Translated field (must set translation)
|
|
//
|
|
// Tutti questi codici possono essere usati anche maiuscoli, il che inibisce
|
|
// l'uso del carattere di riempimento (set_fillchar) per uno specifico campo.
|
|
// ---------------------------------------------
|
|
// Per tutti i codici che riguardano la stampa di real (@n, %r, #r)
|
|
// se non vengono date ulteriori specifiche di formato viene usata
|
|
// una picture che e' "" per default, ma puo' essere modificata con
|
|
// set_real_picture(). Anche questo e' assai carino.
|
|
// Normalmente un real uguale a zero viene stampato come stringa vuota
|
|
// a meno che non si specifichi set_print_zero([TRUE]).
|
|
// ---------------------------------------------
|
|
// codici posizionamento e movimento carrello
|
|
// @<n>g vai a posizione n
|
|
// @<n>j salta di n posizioni (in orizzontale)
|
|
// codici stile
|
|
// @b bold
|
|
// @i italic
|
|
// @u underlined
|
|
// @r reset to normal
|
|
// ---------------------------------------------------
|
|
// CODICI COLORE PER VISUALIZZAZIONE E COLLEGAMENTO
|
|
// ---------------------------------------------------
|
|
// Se si vuole che in visualizzazione il testo sia colorato
|
|
// si usa il codice $[]; tra le quadre si scrive il colore
|
|
// di foreground, opzionalmente seguito da una virgola e dal
|
|
// colore di background (bianco per default). I colori si
|
|
// specificano con un singolo carattere come segue:
|
|
// n nero
|
|
// g verde
|
|
// b blu
|
|
// c cyan
|
|
// y giallo
|
|
// v magenta
|
|
// m colore background maschere (azzurrotto)
|
|
// d grigio scuro
|
|
// l grigio chiaro
|
|
// k grigio normale
|
|
// ------------------------------------------------------
|
|
// Se si fa enable_link(..) con un certo colore, tutto
|
|
// cio; che e' scritto in quel colore diventa selezionabile
|
|
// e alla sua selezione (premendo 'Collega') si puo' associare
|
|
// un'azione in process_link. A quest'ultima viene passata
|
|
// l'ID ritornata da enable_link() e il testo selezionato alla
|
|
// pressione di Collega. Vedere ba6 e stampare l'elenco (con
|
|
// Includi ditte abilitato) per un esempio.
|
|
// --------------------------------------------------------
|
|
|
|
void reset_row(int r);
|
|
|
|
// chiamare reset_print() durante la stampa forza la
|
|
// rilettura di set_page() alla prossima volta
|
|
void reset_print();
|
|
|
|
void set_row(int r, const char* fmt, ...);
|
|
|
|
// ---------------------------------------------
|
|
// set translation values for field
|
|
// called once for each translation: example
|
|
// set_translation(12,"STATOCIV","1","Celibe")
|
|
// provoca la stampa automatica di stringhe al
|
|
// posto di determinati valori dei campi se e' dato
|
|
// il codice @t
|
|
// Il posto giusto per chiamarla: user_create()
|
|
// ---------------------------------------------
|
|
void set_translation(int lognum, const char* field,
|
|
const char* from, const char* to);
|
|
|
|
|
|
|
|
|
|
// --------------------------------------------------------
|
|
// hypertext interface for viswin
|
|
// --------------------------------------------------------
|
|
// Quando si vogliono abilitare determinati colori come
|
|
// indicatori di legame ipertestuale, si faccia enable_link
|
|
// nella create. L' ID ritornato viene passato a process_link
|
|
// assieme al testo selezionato
|
|
int enable_link (const char* descr, char fg, char bg = 'w');
|
|
void disable_link(char fg, char bg = 'w');
|
|
void disable_links() { printer().links().destroy(); }
|
|
// se si setta multiple a TRUE anziche' la descrizione del testo selezionato
|
|
// viene passata a enable_link una tokenstring con tutte i 'bottoni' dello
|
|
// stesso colore presenti sulla riga
|
|
void set_multiple_link(bool on);
|
|
|
|
|
|
// BACKGROUND PAINTING! Chefigata! poi vi spiego....
|
|
void set_background(const char* bgdesc = NULL);
|
|
|
|
|
|
// ---------------------------------------------
|
|
// set/select cursor
|
|
// ---------------------------------------------
|
|
// selects i-th cursor
|
|
// inutile se c'e' un cursore solo
|
|
void select_cursor(int i);
|
|
|
|
// return i-th cursor without making it current
|
|
TCursor* get_cursor(int i);
|
|
// returns maximum row defined
|
|
int get_maxrow() { return _maxrow; }
|
|
|
|
// adds cursor to class; return identifier
|
|
// cursor* can be NULL: no file is used but
|
|
// print_one is called and iterations are performed
|
|
// by pre_ and post_ process
|
|
int add_cursor(TCursor* c);
|
|
|
|
// retrieve current cursor
|
|
TCursor* current_cursor() { return _cur; }
|
|
|
|
// ---------------------------------------------
|
|
// set_auto_ff(TRUE) fa si' che dopo ogni pagina logica (relativa ad
|
|
// un record) si stampi un form feed. (anche se il cursore e' nullo)
|
|
void set_auto_ff( bool b = TRUE)
|
|
{ _auto_ff = b; }
|
|
|
|
// il carattere specificato con set_fillchar (default ' ') viene
|
|
// usato per riempire davanti e dietro i campi in cui si e' specificata
|
|
// una dimensione maggiore della lunghezza effettiva del contenuto,
|
|
// (a meno che non si sia usato un codice di formato maiuscolo)
|
|
void set_fillchar(char c)
|
|
{ _fillchar = c; }
|
|
|
|
// riempie di righe vuote la pagina corrente fino alla dimensione
|
|
// della pagina
|
|
void fill_page(int from = -1);
|
|
|
|
// di solito basta e avanza quella di default
|
|
virtual bool menu(MENU_TAG m);
|
|
|
|
// print menu is enabled when set_print returns TRUE
|
|
void enable_print_menu();
|
|
void disable_print_menu();
|
|
void enable_setprint_menu();
|
|
void disable_setprint_menu();
|
|
|
|
// header/footer (printf, not set_row analogues)
|
|
// only understand @-codes for setting font attributes,
|
|
// date and page number
|
|
// plus every printf %-code
|
|
|
|
// con queste si possono ridefinire header e footer al
|
|
// verificarsi di condizioni durante la stampa
|
|
virtual void preprocess_header() {}
|
|
virtual void preprocess_footer() {}
|
|
|
|
void set_header(int row, const char* fmt, ...);
|
|
void set_footer(int row, const char* fmt, ...);
|
|
void reset_header();
|
|
void reset_footer();
|
|
|
|
// vedi sopra per capire
|
|
void reset_files() { _reset_tree(_pr_tree); _pr_tree = NULL; }
|
|
void add_file(int file, int from = 0);
|
|
void add_file(const char* tab, int from = 0);
|
|
|
|
// set default picture for reals
|
|
void set_real_picture(const char* p) { _picture = p; }
|
|
void set_print_zero(bool b = TRUE) { _print_zero = b; }
|
|
|
|
// progress indicator control
|
|
void set_wait_message(const char* m)
|
|
{ _wmess = m; }
|
|
void set_wait_bar(bool m)
|
|
// default yes
|
|
{ _wbar = m; }
|
|
void set_wait_cancel(bool m)
|
|
// default yes
|
|
{ _wcancel = m; }
|
|
void set_wait_threshold(int m)
|
|
// minimum number of print items to show progress indicator;
|
|
// default 2
|
|
{ _wthr = m; }
|
|
|
|
// questa forza la progind anche se si stampa su video
|
|
void force_progind(bool b = TRUE)
|
|
{ _force_progind = b; }
|
|
|
|
// questa forza la rilettura delle setrow in set_page ad ogni
|
|
// record stampato, in modo che i dati siano
|
|
// sempre quelli del record corrente anche se si usano codici %
|
|
// s'intende che rallenta un po' la stampa
|
|
void force_setpage(bool b = TRUE)
|
|
{ _force_setpage = b; }
|
|
|
|
void set_config_file(const char* s)
|
|
{ _confpr = s; }
|
|
word get_page_number()
|
|
{ return printer().getcurrentpage(); }
|
|
void set_page_number(word n)
|
|
{ printer().setcurrentpage(n); }
|
|
|
|
TPrint_application();
|
|
virtual ~TPrint_application();
|
|
};
|
|
|
|
// buon divertimento
|
|
|
|
|
|
#endif
|
|
|