Aggiornato uso di TRelation::lfile
git-svn-id: svn://10.65.10.50/trunk@277 c028cbd2-c16b-5b4b-a496-9718f37d4682
This commit is contained in:
parent
ab754188c1
commit
d16636c484
1202
include/applicat.cpp
1202
include/applicat.cpp
File diff suppressed because it is too large
Load Diff
@ -1,129 +1,129 @@
|
||||
// fv 6/10/93
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <xvt.h>
|
||||
|
||||
#if XVT_OS == XVT_OS_SCOUNIX
|
||||
#include <sys/fcntl.h>
|
||||
#include <sys/wait.h>
|
||||
#endif
|
||||
|
||||
#if XVT_OS == XVT_OS_WIN
|
||||
#include <windows.h>
|
||||
#include <applicat.h>
|
||||
#endif
|
||||
|
||||
#if XVT_OS == XVT_OS_DOS
|
||||
#include <holdev.h>
|
||||
#endif
|
||||
|
||||
#include <execp.h>
|
||||
|
||||
|
||||
// char _path[120]; // app name
|
||||
// int _error; // last error
|
||||
// int _exitcode; // last exit code
|
||||
// int _count; // count of calls returning 0
|
||||
// int error() { return _error};
|
||||
// int exitcode() { return _exitcode};
|
||||
// int count() { return _count; };
|
||||
|
||||
int TExternal_app::run(bool async)
|
||||
{
|
||||
|
||||
_error = 0;
|
||||
_exitcode = 0;
|
||||
|
||||
// save cwd
|
||||
save_dir();
|
||||
|
||||
|
||||
#if XVT_OS == XVT_OS_DOS
|
||||
|
||||
// ems swap
|
||||
setems(1);
|
||||
// *** BLinker support; uncomment as needed
|
||||
// BLIUNHOOK();
|
||||
// *******************
|
||||
char* s = getenv("TMPDIR");
|
||||
if (s == NULL)
|
||||
_exitcode = holdev("\\tmp;",0,_path);
|
||||
else
|
||||
_exitcode = holdev(s,0,_path);
|
||||
// *** BLinker support; uncomment as needed
|
||||
// BLREINIT();
|
||||
// *******************
|
||||
if (!_exitcode)
|
||||
_exitcode = childret();
|
||||
else
|
||||
_exitcode = -_exitcode;
|
||||
xvt_escape(XVT_ESC_CH_REFRESH);
|
||||
|
||||
#elif XVT_OS == XVT_OS_WIN
|
||||
set_cursor(TASK_WIN, CURSOR_WAIT);
|
||||
_exitcode = WinExec((char*)_path, SW_SHOW);
|
||||
if (_exitcode >= 32)
|
||||
{
|
||||
if (!async) MainApp()->wait_for(_path);
|
||||
_exitcode = 0;
|
||||
}
|
||||
else
|
||||
error_box("Impossibile eseguire '%s':\nErrore %d", (const char*)_path, _exitcode);
|
||||
|
||||
set_cursor(TASK_WIN, CURSOR_ARROW);
|
||||
#else
|
||||
|
||||
switch (fork())
|
||||
{
|
||||
case -1:
|
||||
_error = errno;
|
||||
_exitcode = -1;
|
||||
break;
|
||||
case 0:
|
||||
const char* s = strdup(_path);
|
||||
char* p = strchr(s, ' ');
|
||||
if (p) *p = '\0';
|
||||
const char* pathn = strdup(s);
|
||||
const char* args[21];
|
||||
int i = 0;
|
||||
args[i++] = pathn;
|
||||
while ((i < 20) && (p))
|
||||
{
|
||||
s = p + 1;
|
||||
p = strchr(s, ' ');
|
||||
if (p) *p = '\0';
|
||||
args[i++] = strdup(s);
|
||||
}
|
||||
args[i] = NULL;
|
||||
for (i = 3; i < _NFILE; i++) fcntl(i,F_SETFD,1);
|
||||
// execvp(_path, NULL);
|
||||
execvp ( pathn , args );
|
||||
exit ( -1 );
|
||||
default:
|
||||
if(wait(&_exitcode) == -1)
|
||||
_exitcode = -1;
|
||||
else _exitcode = _exitcode >> 8;
|
||||
break;
|
||||
}
|
||||
_error = errno;
|
||||
xvt_escape(XVT_ESC_CH_REFRESH);
|
||||
|
||||
#endif
|
||||
|
||||
// restore cwd
|
||||
restore_dir();
|
||||
|
||||
// update counts
|
||||
if (_exitcode == 0)
|
||||
_count++;
|
||||
return _exitcode;
|
||||
}
|
||||
|
||||
TExternal_app::TExternal_app(const char* p)
|
||||
{
|
||||
_path = p;
|
||||
_count = 0;
|
||||
_error = 0;
|
||||
_exitcode = 0;
|
||||
}
|
||||
// fv 6/10/93
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <xvt.h>
|
||||
|
||||
#if XVT_OS == XVT_OS_SCOUNIX
|
||||
#include <sys/fcntl.h>
|
||||
#include <sys/wait.h>
|
||||
#endif
|
||||
|
||||
#if XVT_OS == XVT_OS_WIN
|
||||
#include <windows.h>
|
||||
#include <applicat.h>
|
||||
#endif
|
||||
|
||||
#if XVT_OS == XVT_OS_DOS
|
||||
#include <holdev.h>
|
||||
#endif
|
||||
|
||||
#include <execp.h>
|
||||
|
||||
|
||||
// char _path[120]; // app name
|
||||
// int _error; // last error
|
||||
// int _exitcode; // last exit code
|
||||
// int _count; // count of calls returning 0
|
||||
// int error() { return _error};
|
||||
// int exitcode() { return _exitcode};
|
||||
// int count() { return _count; };
|
||||
|
||||
int TExternal_app::run(bool async)
|
||||
{
|
||||
|
||||
_error = 0;
|
||||
_exitcode = 0;
|
||||
|
||||
// save cwd
|
||||
save_dir();
|
||||
|
||||
|
||||
#if XVT_OS == XVT_OS_DOS
|
||||
|
||||
// ems swap
|
||||
setems(1);
|
||||
// *** BLinker support; uncomment as needed
|
||||
// BLIUNHOOK();
|
||||
// *******************
|
||||
char* s = getenv("TMPDIR");
|
||||
if (s == NULL)
|
||||
_exitcode = holdev("\\tmp;",0,_path);
|
||||
else
|
||||
_exitcode = holdev(s,0,_path);
|
||||
// *** BLinker support; uncomment as needed
|
||||
// BLREINIT();
|
||||
// *******************
|
||||
if (!_exitcode)
|
||||
_exitcode = childret();
|
||||
else
|
||||
_exitcode = -_exitcode;
|
||||
xvt_escape(XVT_ESC_CH_REFRESH);
|
||||
|
||||
#elif XVT_OS == XVT_OS_WIN
|
||||
set_cursor(TASK_WIN, CURSOR_WAIT);
|
||||
_exitcode = WinExec((char*)_path, SW_SHOW);
|
||||
if (_exitcode >= 32)
|
||||
{
|
||||
if (!async) MainApp()->wait_for(_path);
|
||||
_exitcode = 0;
|
||||
}
|
||||
else
|
||||
error_box("Impossibile eseguire '%s':\nErrore %d", (const char*)_path, _exitcode);
|
||||
|
||||
set_cursor(TASK_WIN, CURSOR_ARROW);
|
||||
#else
|
||||
|
||||
switch (fork())
|
||||
{
|
||||
case -1:
|
||||
_error = errno;
|
||||
_exitcode = -1;
|
||||
break;
|
||||
case 0:
|
||||
const char* s = strdup(_path);
|
||||
char* p = strchr(s, ' ');
|
||||
if (p) *p = '\0';
|
||||
const char* pathn = strdup(s);
|
||||
const char* args[21];
|
||||
int i = 0;
|
||||
args[i++] = pathn;
|
||||
while ((i < 20) && (p))
|
||||
{
|
||||
s = p + 1;
|
||||
p = strchr(s, ' ');
|
||||
if (p) *p = '\0';
|
||||
args[i++] = strdup(s);
|
||||
}
|
||||
args[i] = NULL;
|
||||
for (i = 3; i < _NFILE; i++) fcntl(i,F_SETFD,1);
|
||||
// execvp(_path, NULL);
|
||||
execvp ( pathn , args );
|
||||
exit ( -1 );
|
||||
default:
|
||||
if(wait(&_exitcode) == -1)
|
||||
_exitcode = -1;
|
||||
else _exitcode = _exitcode >> 8;
|
||||
break;
|
||||
}
|
||||
_error = errno;
|
||||
xvt_escape(XVT_ESC_CH_REFRESH);
|
||||
|
||||
#endif
|
||||
|
||||
// restore cwd
|
||||
restore_dir();
|
||||
|
||||
// update counts
|
||||
if (_exitcode == 0)
|
||||
_count++;
|
||||
return _exitcode;
|
||||
}
|
||||
|
||||
TExternal_app::TExternal_app(const char* p)
|
||||
{
|
||||
_path = p;
|
||||
_count = 0;
|
||||
_error = 0;
|
||||
_exitcode = 0;
|
||||
}
|
||||
|
5775
include/maskfld.cpp
5775
include/maskfld.cpp
File diff suppressed because it is too large
Load Diff
@ -1 +1 @@
|
||||
#define VERSION 1.4
|
||||
#define VERSION 1.5
|
||||
|
2560
include/printapp.cpp
2560
include/printapp.cpp
File diff suppressed because it is too large
Load Diff
@ -1,471 +1,471 @@
|
||||
// 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
|
||||
|
||||
// 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;
|
||||
int _ncopies;
|
||||
bool _repeat_print;
|
||||
|
||||
// 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 find_link(const char* descr) const;
|
||||
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 tutti 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);
|
||||
|
||||
virtual word class_id() const { return CLASS_PRINT_APPLICATION; }
|
||||
|
||||
// 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); }
|
||||
|
||||
|
||||
void set_n_copies(int n) { _ncopies = n; }
|
||||
int get_n_copies() { return _ncopies; }
|
||||
void repeat_print() { _repeat_print = TRUE; }
|
||||
|
||||
TPrint_application();
|
||||
virtual ~TPrint_application();
|
||||
};
|
||||
|
||||
// buon divertimento
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
// 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
|
||||
|
||||
// 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;
|
||||
int _ncopies;
|
||||
bool _repeat_print;
|
||||
|
||||
// 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 find_link(const char* descr) const;
|
||||
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 tutti 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);
|
||||
|
||||
virtual word class_id() const { return CLASS_PRINT_APPLICATION; }
|
||||
|
||||
// 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); }
|
||||
|
||||
|
||||
void set_n_copies(int n) { _ncopies = n; }
|
||||
int get_n_copies() { return _ncopies; }
|
||||
void repeat_print() { _repeat_print = TRUE; }
|
||||
|
||||
TPrint_application();
|
||||
virtual ~TPrint_application();
|
||||
};
|
||||
|
||||
// buon divertimento
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
1738
include/relapp.cpp
1738
include/relapp.cpp
File diff suppressed because it is too large
Load Diff
188
include/relapp.h
188
include/relapp.h
@ -1,94 +1,94 @@
|
||||
#ifndef __RELAPP_H
|
||||
#define __RELAPP_H
|
||||
|
||||
#ifndef __APPLICAT_H
|
||||
#include <applicat.h>
|
||||
#endif
|
||||
|
||||
#ifndef __RELATION_H
|
||||
#include <relation.h>
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef __MASK_H
|
||||
#include <mask.h>
|
||||
#endif
|
||||
|
||||
class TKey_array;
|
||||
|
||||
class TRelation_application : public TApplication
|
||||
{
|
||||
TMask * _mask;
|
||||
TKey_array* _maskeys;
|
||||
long _first, _last;
|
||||
int _search_id;
|
||||
|
||||
TString _autoins_caller;
|
||||
bool _lnflag;
|
||||
TToken_string _fixed;
|
||||
|
||||
virtual bool create();
|
||||
virtual bool destroy();
|
||||
|
||||
bool filter();
|
||||
bool test_key(byte k, bool err);
|
||||
bool save(bool check_dirty);
|
||||
void enable_query();
|
||||
void set_toolbar(bool all);
|
||||
|
||||
int set_mode(int mode); // Seleziona il nuovo modo e ritorna il vecchio
|
||||
void set_limits(byte what = 0x3);
|
||||
void query_insert_mode() { query_mode(TRUE); }
|
||||
void insert_mode(); // Entra in modo inserimento
|
||||
virtual bool main_loop(); // Ciclo principale
|
||||
TMask_field* get_search_field() const;
|
||||
|
||||
protected:
|
||||
TLocalisamfile& file() const { return get_relation()->lfile(); }
|
||||
void set_fixed(); // Fissa i campi non modificabili
|
||||
bool search_mode(); // Attiva la maschera di ricerca
|
||||
void query_mode(bool pre_ins = FALSE); // Entra in modo ricerca
|
||||
bool modify_mode(); // Entra in modo modifica
|
||||
void setkey();
|
||||
bool lnflag() const { return _lnflag;}
|
||||
long first() const { return _first;}
|
||||
long last() const { return _first;}
|
||||
TMask& curr_mask() const { return *_mask; }
|
||||
const TString& autoins_caller() const { return _autoins_caller;}
|
||||
virtual bool menu(MENU_TAG m);
|
||||
|
||||
virtual bool user_create() pure;
|
||||
virtual bool user_destroy() pure;
|
||||
virtual TMask* get_mask(int mode) pure;
|
||||
virtual bool changing_mask(int mode) pure;
|
||||
virtual TRelation* get_relation() const pure;
|
||||
virtual int read(TMask& m);
|
||||
virtual int write(const TMask& m);
|
||||
virtual int rewrite(const TMask& m);
|
||||
virtual bool remove();
|
||||
virtual const char* get_next_key() { return ""; }
|
||||
virtual bool protected_record(TRectype&) { return FALSE; }
|
||||
virtual void init_query_mode(TMask&) { }
|
||||
virtual void init_query_insert_mode(TMask& m) { init_query_mode(m); }
|
||||
virtual void init_insert_mode(TMask&) { }
|
||||
virtual void init_modify_mode(TMask&) { }
|
||||
virtual void write_enable(const bool on = TRUE) { get_relation()->write_enable(-1, on); }
|
||||
void write_disable() { write_enable(FALSE); }
|
||||
|
||||
bool autonum(TMask* m, bool rec);
|
||||
void set_search_field(short id) { _search_id = id;}
|
||||
bool has_filtered_cursor() const { return filtered() || force_cursor_usage();}
|
||||
|
||||
public:
|
||||
TRelation_application();
|
||||
virtual ~TRelation_application();
|
||||
bool filtered() const { return _fixed.not_empty(); }
|
||||
void set_first(long first) { _first = first;}
|
||||
void set_last(long last) { _last = last;}
|
||||
bool find(byte key = 0);
|
||||
virtual bool force_cursor_usage() const { return FALSE;}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef __RELAPP_H
|
||||
#define __RELAPP_H
|
||||
|
||||
#ifndef __APPLICAT_H
|
||||
#include <applicat.h>
|
||||
#endif
|
||||
|
||||
#ifndef __RELATION_H
|
||||
#include <relation.h>
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef __MASK_H
|
||||
#include <mask.h>
|
||||
#endif
|
||||
|
||||
class TKey_array;
|
||||
|
||||
class TRelation_application : public TApplication
|
||||
{
|
||||
TMask * _mask;
|
||||
TKey_array* _maskeys;
|
||||
long _first, _last;
|
||||
int _search_id;
|
||||
|
||||
TString _autoins_caller;
|
||||
bool _lnflag;
|
||||
TToken_string _fixed;
|
||||
|
||||
virtual bool create();
|
||||
virtual bool destroy();
|
||||
|
||||
bool filter();
|
||||
bool test_key(byte k, bool err);
|
||||
bool save(bool check_dirty);
|
||||
void enable_query();
|
||||
void set_toolbar(bool all);
|
||||
|
||||
int set_mode(int mode); // Seleziona il nuovo modo e ritorna il vecchio
|
||||
void set_limits(byte what = 0x3);
|
||||
void query_insert_mode() { query_mode(TRUE); }
|
||||
void insert_mode(); // Entra in modo inserimento
|
||||
virtual bool main_loop(); // Ciclo principale
|
||||
TMask_field* get_search_field() const;
|
||||
|
||||
protected:
|
||||
TLocalisamfile& file() const { return get_relation()->lfile(); }
|
||||
void set_fixed(); // Fissa i campi non modificabili
|
||||
bool search_mode(); // Attiva la maschera di ricerca
|
||||
void query_mode(bool pre_ins = FALSE); // Entra in modo ricerca
|
||||
bool modify_mode(); // Entra in modo modifica
|
||||
void setkey();
|
||||
bool lnflag() const { return _lnflag;}
|
||||
long first() const { return _first;}
|
||||
long last() const { return _first;}
|
||||
TMask& curr_mask() const { return *_mask; }
|
||||
const TString& autoins_caller() const { return _autoins_caller;}
|
||||
virtual bool menu(MENU_TAG m);
|
||||
|
||||
virtual bool user_create() pure;
|
||||
virtual bool user_destroy() pure;
|
||||
virtual TMask* get_mask(int mode) pure;
|
||||
virtual bool changing_mask(int mode) pure;
|
||||
virtual TRelation* get_relation() const pure;
|
||||
virtual int read(TMask& m);
|
||||
virtual int write(const TMask& m);
|
||||
virtual int rewrite(const TMask& m);
|
||||
virtual bool remove();
|
||||
virtual const char* get_next_key() { return ""; }
|
||||
virtual bool protected_record(TRectype&) { return FALSE; }
|
||||
virtual void init_query_mode(TMask&) { }
|
||||
virtual void init_query_insert_mode(TMask& m) { init_query_mode(m); }
|
||||
virtual void init_insert_mode(TMask&) { }
|
||||
virtual void init_modify_mode(TMask&) { }
|
||||
virtual void write_enable(const bool on = TRUE) { get_relation()->write_enable(-1, on); }
|
||||
void write_disable() { write_enable(FALSE); }
|
||||
|
||||
bool autonum(TMask* m, bool rec);
|
||||
void set_search_field(short id) { _search_id = id;}
|
||||
bool has_filtered_cursor() const { return filtered() || force_cursor_usage();}
|
||||
|
||||
public:
|
||||
TRelation_application();
|
||||
virtual ~TRelation_application();
|
||||
bool filtered() const { return _fixed.not_empty(); }
|
||||
void set_first(long first) { _first = first;}
|
||||
void set_last(long last) { _last = last;}
|
||||
bool find(byte key = 0);
|
||||
virtual bool force_cursor_usage() const { return FALSE;}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
2652
include/relation.cpp
2652
include/relation.cpp
File diff suppressed because it is too large
Load Diff
@ -1,269 +1,269 @@
|
||||
/* $Id: relation.h,v 1.4 1994-09-21 11:16:32 guy Exp $ */
|
||||
// join.h
|
||||
// fv 12/8/93
|
||||
// join class for isam files
|
||||
|
||||
#ifndef __RELATION_H
|
||||
#define __RELATION_H
|
||||
|
||||
#ifndef __ARRAY_H
|
||||
#include <array.h>
|
||||
#endif
|
||||
|
||||
#ifndef __ISAM_H
|
||||
#include <isam.h>
|
||||
#endif
|
||||
|
||||
// @C
|
||||
|
||||
class TRelation : public TObject
|
||||
{
|
||||
friend class TRelationdef;
|
||||
|
||||
// class TRelation : public TLocalisamfile
|
||||
// @END
|
||||
|
||||
// @DPRIV
|
||||
TToken_string _status; // stato della relazione
|
||||
TArray _files; // file descriptors
|
||||
TArray _reldefs; // TRelationdef array
|
||||
int _errors;
|
||||
// @END
|
||||
|
||||
// @FPROT
|
||||
protected:
|
||||
virtual void print_on(ostream& out) const;
|
||||
|
||||
int log2ind(int logicnum) const;
|
||||
int alias2ind(byte alias) const;
|
||||
int name2ind(const char* name) const;
|
||||
|
||||
TRelationdef& reldef(int i) const { return (TRelationdef&)_reldefs[i]; }
|
||||
TLocalisamfile& file(int i = 0) const { return (TLocalisamfile&)_files[i]; }
|
||||
|
||||
// @LONGDES
|
||||
// position_rels fa tutto il lavoro: se non trova un record
|
||||
// adatto su un file, svuota il record corrente e non ritorna errore.
|
||||
// write etc. poi procedono normalmente
|
||||
// @END
|
||||
int position_rels(TIsamop op = _isequal, TReclock lockop = _nolock, TDate& atdate = (TDate&)botime, int first = 0);
|
||||
|
||||
friend class TCursor;
|
||||
|
||||
public:
|
||||
// @FPUB
|
||||
int update() { return position_rels(_isequal, _nolock);}
|
||||
void zero();
|
||||
virtual int next(TReclock lockop = _nolock) { return file().next(lockop) == NOERR ? position_rels(_isequal, lockop) : file().status(); }
|
||||
virtual int prev(TReclock lockop = _nolock) { return file().prev(lockop) == NOERR ? position_rels(_isequal, lockop) : file().status(); }
|
||||
virtual int next(TDate& atdate) { return file().next(atdate) == NOERR ? position_rels(_isequal, _nolock, atdate) : file().status(); }
|
||||
virtual int prev(TDate& atdate) { return file().prev(atdate) == NOERR ? position_rels(_isequal, _nolock, atdate) : file().status(); }
|
||||
virtual int first(TReclock lockop = _nolock) { return file().first(lockop) == NOERR ? position_rels(_isequal, lockop) : file().status(); }
|
||||
virtual int last(TReclock lockop = _nolock) { return file().last(lockop) == NOERR ? position_rels(_isequal, lockop) : file().status(); }
|
||||
virtual int skip(TRecnotype nrec, TReclock lockop = _nolock) { return file().skip(nrec, lockop) == NOERR ? position_rels(_isequal, lockop) : file().status(); }
|
||||
virtual int read(TIsamop op = _isgteq, TReclock lockop = _nolock, TDate& atdate = (TDate&)botime) { return file().read(op, lockop, atdate) == NOERR ? position_rels(_isequal, lockop, atdate) : file().status();}
|
||||
|
||||
TLocalisamfile& lfile(int logicnum = 0) const;
|
||||
TLocalisamfile& lfile(const char* name) const;
|
||||
void write_enable(int logicnum = -1, const bool on = TRUE) ;
|
||||
void write_enable(const char* name, const bool on = TRUE) ;
|
||||
void write_disable(int logicnum = -1) { write_enable(logicnum, FALSE); }
|
||||
void write_disable(const char* name) { write_enable(name, FALSE); }
|
||||
|
||||
TRectype& curr(int logicnum = 0) const { return lfile(logicnum).curr(); }
|
||||
// next_match for 0ne-to-many relations; positions logicnum (!= main)
|
||||
// on next matching record; returns TRUE or FALSE if no more matches; in
|
||||
// any case relation is kept consistent except when inconsistent in
|
||||
// first place
|
||||
bool next_match(int logicnum, const char* fieldlist = NULL, int nkey = 0);
|
||||
|
||||
// @DES add relation
|
||||
// @FPUB
|
||||
bool add(int logicnum, const char* relexprs, int key = 1,
|
||||
int linkto = 0, byte alias = 0, bool allow_lock = FALSE);
|
||||
bool add(const char* tabname, const char* relexprs, int key = 1,
|
||||
int linkto = 0, byte alias = 0, bool allow_lock = FALSE);
|
||||
|
||||
|
||||
// @DES write methods
|
||||
// @FPUB
|
||||
virtual int write (bool force = TRUE, TDate& atdate = (TDate&)botime);
|
||||
virtual int rewrite(bool force = TRUE, TDate& atdate = (TDate&)botime);
|
||||
virtual int remove (TDate& atdate = (TDate&)botime);
|
||||
|
||||
// @DES checking methods
|
||||
// @FPUB
|
||||
bool eof( int logicnum = 0) { return lfile(logicnum).eof(); }
|
||||
bool bof( int logicnum = 0) { return lfile(logicnum).bof(); }
|
||||
|
||||
// @N
|
||||
// status(), good() and bad() return the status of the relation when called
|
||||
// with no args, or the status of the file when called with
|
||||
// a logical number
|
||||
// @END
|
||||
|
||||
bool status(int logicnum = 0) { return lfile(logicnum).status(); }
|
||||
bool good( int logicnum = 0) { return lfile(logicnum).good(); }
|
||||
bool bad( int logicnum = 0) { return lfile(logicnum).bad(); }
|
||||
bool empty( int logicnum = 0) { return lfile(logicnum).empty(); }
|
||||
// @END
|
||||
|
||||
// @LONGDES
|
||||
// isconsistent() returns TRUE if every file in the relation is
|
||||
// OK, current record is non-empty, and relation is consistent.
|
||||
// If it's not and reset is TRUE, it tries to reset the relation
|
||||
// to a consistent state (based on main record) -- no further check
|
||||
// is done.
|
||||
// Also called internally by update and remove.
|
||||
// @END
|
||||
bool isconsistent(bool reset = FALSE);
|
||||
|
||||
// TRUE se c'e' un record ed e' il primo match (non si e' mai fatta
|
||||
// position_rels)
|
||||
bool is_first_match(int logicnum);
|
||||
|
||||
void save_status () ;
|
||||
void restore_status () ;
|
||||
|
||||
// @DES positioning operators. return status
|
||||
// @FPUB
|
||||
|
||||
TRecnotype operator +=(const TRecnotype npos) { return skip(npos); }
|
||||
TRecnotype operator -=(const TRecnotype npos) { return skip(-npos); }
|
||||
TRecnotype operator ++() { return next(); }
|
||||
TRecnotype operator --() { return prev(); }
|
||||
|
||||
TRelation(int logicnum, bool linkrecinst = TRUE);
|
||||
TRelation(const char* tabname, bool linkrecinst = TRUE);
|
||||
virtual ~TRelation();
|
||||
};
|
||||
|
||||
// @C
|
||||
// Classe TCursor : public TObject
|
||||
//
|
||||
// @END
|
||||
|
||||
class TExpression;
|
||||
|
||||
typedef bool (*FILTERFUNCTION)(const TRelation* r);
|
||||
|
||||
class TCursor : public TObject
|
||||
{
|
||||
// @DPRIV
|
||||
TRelation* _if;
|
||||
int _nkey;
|
||||
TRecnotype _pos; // Posizione corrente
|
||||
TRecnotype _totrec;
|
||||
TRecnotype _lastrec;
|
||||
TRecnotype _lastkrec;
|
||||
TFilename _filename;
|
||||
TString _filter; // Filtro
|
||||
TString _keyfrom; // chiave iniziale
|
||||
TString _keyto; // chiave finale
|
||||
TExpression* _fexpr; // Espressione relativo filtro
|
||||
bool _frozen;
|
||||
FILTERFUNCTION _filterfunction;
|
||||
TFilename _indexname;
|
||||
// @END
|
||||
|
||||
// @FPRIV
|
||||
virtual TRecnotype buildcursor(TRecnotype rp);
|
||||
int filtercursor(int pagecnt, TRecnotype* page);
|
||||
bool changed();
|
||||
|
||||
FILE* open_index(bool create = FALSE) const;
|
||||
TRecnotype update();
|
||||
|
||||
|
||||
protected:
|
||||
TRecnotype readrec();
|
||||
void filter(const char* filter, const TRectype* from = NULL,
|
||||
const TRectype* to = NULL);
|
||||
|
||||
public:
|
||||
// @FPUB
|
||||
TRecnotype operator =(const TRecnotype nr); // Assegnazione
|
||||
TCursor& operator +=(const TRecnotype nr); // Scorri avanti
|
||||
TCursor& operator -=(const TRecnotype nr); // Scorri indietro
|
||||
TCursor& operator ++(); // Avanti di un record
|
||||
TCursor& operator --(); // Indietro di un record
|
||||
TRecnotype pos() const { return _pos; }
|
||||
TRecnotype items();
|
||||
TRecnotype size() const { return file().eod(); }
|
||||
const TString& from() const { return _keyfrom; }
|
||||
const TString& to() const { return _keyto; }
|
||||
|
||||
TRectype& curr(int log = 0) const { return _if->curr(log); }
|
||||
TRectype& curr(const char * tab) const
|
||||
{ return _if->lfile(tab).curr(); }
|
||||
TRecnotype read(TIsamop op = _isgteq, TReclock lockop = _nolock, TDate& atdate = (TDate&)botime);
|
||||
virtual bool ok() const;
|
||||
|
||||
const char* filter() const { return _filter; }
|
||||
void freeze(bool on = TRUE) { _frozen = on; }
|
||||
bool frozen() const { return _frozen; }
|
||||
void setfilter(const char* filter_expr) { filter(filter_expr); }
|
||||
void setregion(const TRectype& from, const TRectype& to)
|
||||
{ filter(NULL,&from, &to); }
|
||||
|
||||
TRelation* relation() const { return _if; }
|
||||
TLocalisamfile& file(int lnum = 0) const { return _if->lfile(lnum); }
|
||||
TLocalisamfile& file(const char* name) const { return _if->lfile(name); }
|
||||
int repos() { return _if->position_rels(); }
|
||||
|
||||
void setkey() { file().setkey(_nkey); }
|
||||
void setkey(int nkey);
|
||||
int key() const { return _nkey; }
|
||||
|
||||
bool next_match(int lognum, const char* fl = NULL, int nk = 0);
|
||||
bool is_first_match(int ln);
|
||||
|
||||
void set_filterfunction(FILTERFUNCTION ff) { _filterfunction = ff; _lastrec = 0L;}
|
||||
bool has_filter() const { return _filter.not_empty() || _filterfunction; }
|
||||
|
||||
void save_status () { _if->save_status(); }
|
||||
void restore_status () { _if->restore_status(); }
|
||||
|
||||
TCursor(TRelation* f, const char* filter = "", int key = 1, TRectype* from = NULL, TRectype* to = NULL);
|
||||
virtual ~TCursor();
|
||||
};
|
||||
|
||||
|
||||
// @C
|
||||
// Classe TFieldref : public TObject
|
||||
// @END
|
||||
|
||||
class TFieldref : public TObject
|
||||
{
|
||||
// @DPRIV
|
||||
short _fileid; // Numero del file
|
||||
TString16 _id; // Nome tabella o stringa col numero del file
|
||||
TString16 _name; // Nome del campo
|
||||
int _from, _to; // Substring
|
||||
|
||||
protected:
|
||||
virtual void print_on(ostream& out) const;
|
||||
|
||||
public:
|
||||
// @FPUB
|
||||
TFieldref();
|
||||
TFieldref(const TString&, short defid);
|
||||
|
||||
TFieldref& operator =(const TString& s); // Operatore di assegnazione
|
||||
|
||||
virtual bool ok() const { return _name.not_empty(); } // Vero se il numero del file e' valido
|
||||
|
||||
int file() const { return _fileid; } // ritorna il file
|
||||
const char* name() const { return (const char*) _name; } // ritorna il nome del campo
|
||||
int from() const { return _from; }
|
||||
int to() const { return _to; }
|
||||
int len(TRectype &rec) const;
|
||||
const char* read(const TRelation* = NULL) const;
|
||||
const char* read(const TRectype&) const;
|
||||
void write(const char* val, TRelation* = NULL) const;
|
||||
void write(const char* val, TRectype& rec) const;
|
||||
};
|
||||
// Converte una stringa in numero logico o numero tabella
|
||||
int name2log(const char* name);
|
||||
#endif
|
||||
// ** EOF relation.h
|
||||
/* $Id: relation.h,v 1.5 1994-09-22 07:48:07 guy Exp $ */
|
||||
// join.h
|
||||
// fv 12/8/93
|
||||
// join class for isam files
|
||||
|
||||
#ifndef __RELATION_H
|
||||
#define __RELATION_H
|
||||
|
||||
#ifndef __ARRAY_H
|
||||
#include <array.h>
|
||||
#endif
|
||||
|
||||
#ifndef __ISAM_H
|
||||
#include <isam.h>
|
||||
#endif
|
||||
|
||||
// @C
|
||||
|
||||
class TRelation : public TObject
|
||||
{
|
||||
friend class TRelationdef;
|
||||
|
||||
// class TRelation : public TLocalisamfile
|
||||
// @END
|
||||
|
||||
// @DPRIV
|
||||
TToken_string _status; // stato della relazione
|
||||
TArray _files; // file descriptors
|
||||
TArray _reldefs; // TRelationdef array
|
||||
int _errors;
|
||||
// @END
|
||||
|
||||
// @FPROT
|
||||
protected:
|
||||
virtual void print_on(ostream& out) const;
|
||||
|
||||
int log2ind(int logicnum) const;
|
||||
int alias2ind(byte alias) const;
|
||||
int name2ind(const char* name) const;
|
||||
|
||||
TRelationdef& reldef(int i) const { return (TRelationdef&)_reldefs[i]; }
|
||||
TLocalisamfile& file(int i = 0) const { return (TLocalisamfile&)_files[i]; }
|
||||
|
||||
// @LONGDES
|
||||
// position_rels fa tutto il lavoro: se non trova un record
|
||||
// adatto su un file, svuota il record corrente e non ritorna errore.
|
||||
// write etc. poi procedono normalmente
|
||||
// @END
|
||||
int position_rels(TIsamop op = _isequal, TReclock lockop = _nolock, TDate& atdate = (TDate&)botime, int first = 0);
|
||||
|
||||
friend class TCursor;
|
||||
|
||||
public:
|
||||
// @FPUB
|
||||
int update() { return position_rels(_isequal, _nolock);}
|
||||
void zero();
|
||||
virtual int next(TReclock lockop = _nolock) { return file().next(lockop) == NOERR ? position_rels(_isequal, lockop) : file().status(); }
|
||||
virtual int prev(TReclock lockop = _nolock) { return file().prev(lockop) == NOERR ? position_rels(_isequal, lockop) : file().status(); }
|
||||
virtual int next(TDate& atdate) { return file().next(atdate) == NOERR ? position_rels(_isequal, _nolock, atdate) : file().status(); }
|
||||
virtual int prev(TDate& atdate) { return file().prev(atdate) == NOERR ? position_rels(_isequal, _nolock, atdate) : file().status(); }
|
||||
virtual int first(TReclock lockop = _nolock) { return file().first(lockop) == NOERR ? position_rels(_isequal, lockop) : file().status(); }
|
||||
virtual int last(TReclock lockop = _nolock) { return file().last(lockop) == NOERR ? position_rels(_isequal, lockop) : file().status(); }
|
||||
virtual int skip(TRecnotype nrec, TReclock lockop = _nolock) { return file().skip(nrec, lockop) == NOERR ? position_rels(_isequal, lockop) : file().status(); }
|
||||
virtual int read(TIsamop op = _isgteq, TReclock lockop = _nolock, TDate& atdate = (TDate&)botime) { return file().read(op, lockop, atdate) == NOERR ? position_rels(_isequal, lockop, atdate) : file().status();}
|
||||
|
||||
TLocalisamfile& lfile(int logicnum = 0) const;
|
||||
TLocalisamfile& lfile(const char* name) const;
|
||||
void write_enable(int logicnum = -1, const bool on = TRUE) ;
|
||||
void write_enable(const char* name, const bool on = TRUE) ;
|
||||
void write_disable(int logicnum = -1) { write_enable(logicnum, FALSE); }
|
||||
void write_disable(const char* name) { write_enable(name, FALSE); }
|
||||
|
||||
TRectype& curr(int logicnum = 0) const { return lfile(logicnum).curr(); }
|
||||
// next_match for 0ne-to-many relations; positions logicnum (!= main)
|
||||
// on next matching record; returns TRUE or FALSE if no more matches; in
|
||||
// any case relation is kept consistent except when inconsistent in
|
||||
// first place
|
||||
bool next_match(int logicnum, const char* fieldlist = NULL, int nkey = 0);
|
||||
|
||||
// @DES add relation
|
||||
// @FPUB
|
||||
bool add(int logicnum, const char* relexprs, int key = 1,
|
||||
int linkto = 0, byte alias = 0, bool allow_lock = FALSE);
|
||||
bool add(const char* tabname, const char* relexprs, int key = 1,
|
||||
int linkto = 0, byte alias = 0, bool allow_lock = FALSE);
|
||||
|
||||
|
||||
// @DES write methods
|
||||
// @FPUB
|
||||
virtual int write (bool force = TRUE, TDate& atdate = (TDate&)botime);
|
||||
virtual int rewrite(bool force = TRUE, TDate& atdate = (TDate&)botime);
|
||||
virtual int remove (TDate& atdate = (TDate&)botime);
|
||||
|
||||
// @DES checking methods
|
||||
// @FPUB
|
||||
bool eof( int logicnum = 0) { return lfile(logicnum).eof(); }
|
||||
bool bof( int logicnum = 0) { return lfile(logicnum).bof(); }
|
||||
|
||||
// @N
|
||||
// status(), good() and bad() return the status of the relation when called
|
||||
// with no args, or the status of the file when called with
|
||||
// a logical number
|
||||
// @END
|
||||
|
||||
bool status(int logicnum = 0) { return lfile(logicnum).status(); }
|
||||
bool good( int logicnum = 0) { return lfile(logicnum).good(); }
|
||||
bool bad( int logicnum = 0) { return lfile(logicnum).bad(); }
|
||||
bool empty( int logicnum = 0) { return lfile(logicnum).empty(); }
|
||||
// @END
|
||||
|
||||
// @LONGDES
|
||||
// isconsistent() returns TRUE if every file in the relation is
|
||||
// OK, current record is non-empty, and relation is consistent.
|
||||
// If it's not and reset is TRUE, it tries to reset the relation
|
||||
// to a consistent state (based on main record) -- no further check
|
||||
// is done.
|
||||
// Also called internally by update and remove.
|
||||
// @END
|
||||
bool isconsistent(bool reset = FALSE);
|
||||
|
||||
// TRUE se c'e' un record ed e' il primo match (non si e' mai fatta
|
||||
// position_rels)
|
||||
bool is_first_match(int logicnum);
|
||||
|
||||
void save_status () ;
|
||||
void restore_status () ;
|
||||
|
||||
// @DES positioning operators. return status
|
||||
// @FPUB
|
||||
|
||||
TRecnotype operator +=(const TRecnotype npos) { return skip(npos); }
|
||||
TRecnotype operator -=(const TRecnotype npos) { return skip(-npos); }
|
||||
TRecnotype operator ++() { return next(); }
|
||||
TRecnotype operator --() { return prev(); }
|
||||
|
||||
TRelation(int logicnum, bool linkrecinst = TRUE);
|
||||
TRelation(const char* tabname, bool linkrecinst = TRUE);
|
||||
virtual ~TRelation();
|
||||
};
|
||||
|
||||
// @C
|
||||
// Classe TCursor : public TObject
|
||||
//
|
||||
// @END
|
||||
|
||||
class TExpression;
|
||||
|
||||
typedef bool (*FILTERFUNCTION)(const TRelation* r);
|
||||
|
||||
class TCursor : public TObject
|
||||
{
|
||||
// @DPRIV
|
||||
TRelation* _if;
|
||||
int _nkey;
|
||||
TRecnotype _pos; // Posizione corrente
|
||||
TRecnotype _totrec;
|
||||
TRecnotype _lastrec;
|
||||
TRecnotype _lastkrec;
|
||||
TFilename _filename;
|
||||
TString _filter; // Filtro
|
||||
TString _keyfrom; // chiave iniziale
|
||||
TString _keyto; // chiave finale
|
||||
TExpression* _fexpr; // Espressione relativo filtro
|
||||
bool _frozen;
|
||||
FILTERFUNCTION _filterfunction;
|
||||
TFilename _indexname;
|
||||
// @END
|
||||
|
||||
// @FPRIV
|
||||
virtual TRecnotype buildcursor(TRecnotype rp);
|
||||
int filtercursor(int pagecnt, TRecnotype* page);
|
||||
bool changed();
|
||||
|
||||
FILE* open_index(bool create = FALSE) const;
|
||||
TRecnotype update();
|
||||
|
||||
|
||||
protected:
|
||||
TRecnotype readrec();
|
||||
void filter(const char* filter, const TRectype* from = NULL,
|
||||
const TRectype* to = NULL);
|
||||
|
||||
public:
|
||||
// @FPUB
|
||||
TRecnotype operator =(const TRecnotype nr); // Assegnazione
|
||||
TCursor& operator +=(const TRecnotype nr); // Scorri avanti
|
||||
TCursor& operator -=(const TRecnotype nr); // Scorri indietro
|
||||
TCursor& operator ++(); // Avanti di un record
|
||||
TCursor& operator --(); // Indietro di un record
|
||||
TRecnotype pos() const { return _pos; }
|
||||
TRecnotype items();
|
||||
TRecnotype size() const { return file().eod(); }
|
||||
const TString& from() const { return _keyfrom; }
|
||||
const TString& to() const { return _keyto; }
|
||||
|
||||
TRectype& curr(int log = 0) const { return _if->curr(log); }
|
||||
TRectype& curr(const char * tab) const
|
||||
{ return _if->lfile(tab).curr(); }
|
||||
TRecnotype read(TIsamop op = _isgteq, TReclock lockop = _nolock, TDate& atdate = (TDate&)botime);
|
||||
virtual bool ok() const;
|
||||
|
||||
const char* filter() const { return _filter; }
|
||||
void freeze(bool on = TRUE) { _frozen = on; }
|
||||
bool frozen() const { return _frozen; }
|
||||
void setfilter(const char* filter_expr) { filter(filter_expr); }
|
||||
void setregion(const TRectype& from, const TRectype& to)
|
||||
{ filter(NULL,&from, &to); }
|
||||
|
||||
TRelation* relation() const { return _if; }
|
||||
TLocalisamfile& file(int lnum = 0) const { return _if->lfile(lnum); }
|
||||
TLocalisamfile& file(const char* name) const { return _if->lfile(name); }
|
||||
int repos() { return _if->position_rels(); }
|
||||
|
||||
void setkey() { file().setkey(_nkey); }
|
||||
void setkey(int nkey);
|
||||
int key() const { return _nkey; }
|
||||
|
||||
bool next_match(int lognum, const char* fl = NULL, int nk = 0);
|
||||
bool is_first_match(int ln);
|
||||
|
||||
void set_filterfunction(FILTERFUNCTION ff) { _filterfunction = ff; _lastrec = 0L;}
|
||||
bool has_filter() const { return _filter.not_empty() || _filterfunction; }
|
||||
|
||||
void save_status () { _if->save_status(); }
|
||||
void restore_status () { _if->restore_status(); }
|
||||
|
||||
TCursor(TRelation* f, const char* filter = "", int key = 1, TRectype* from = NULL, TRectype* to = NULL);
|
||||
virtual ~TCursor();
|
||||
};
|
||||
|
||||
|
||||
// @C
|
||||
// Classe TFieldref : public TObject
|
||||
// @END
|
||||
|
||||
class TFieldref : public TObject
|
||||
{
|
||||
// @DPRIV
|
||||
short _fileid; // Numero del file
|
||||
TString16 _id; // Nome tabella o stringa col numero del file
|
||||
TString16 _name; // Nome del campo
|
||||
int _from, _to; // Substring
|
||||
|
||||
protected:
|
||||
virtual void print_on(ostream& out) const;
|
||||
|
||||
public:
|
||||
// @FPUB
|
||||
TFieldref();
|
||||
TFieldref(const TString&, short defid);
|
||||
|
||||
TFieldref& operator =(const TString& s); // Operatore di assegnazione
|
||||
|
||||
virtual bool ok() const { return _name.not_empty(); } // Vero se il numero del file e' valido
|
||||
|
||||
int file() const { return _fileid; } // ritorna il file
|
||||
const char* name() const { return (const char*) _name; } // ritorna il nome del campo
|
||||
int from() const { return _from; }
|
||||
int to() const { return _to; }
|
||||
int len(TRectype &rec) const;
|
||||
const char* read(const TRelation* = NULL) const;
|
||||
const char* read(const TRectype&) const;
|
||||
void write(const char* val, TRelation* = NULL) const;
|
||||
void write(const char* val, TRectype& rec) const;
|
||||
};
|
||||
// Converte una stringa in numero logico o numero tabella
|
||||
int name2log(const char* name);
|
||||
#endif
|
||||
// ** EOF relation.h
|
||||
|
1506
include/sheet.cpp
1506
include/sheet.cpp
File diff suppressed because it is too large
Load Diff
3776
include/viswin.cpp
3776
include/viswin.cpp
File diff suppressed because it is too large
Load Diff
286
include/viswin.h
286
include/viswin.h
@ -1,143 +1,143 @@
|
||||
/* This is really -*-c++-*- */
|
||||
#ifndef __VISWIN_H
|
||||
#define __VISWIN_H
|
||||
|
||||
#ifndef __ARRAY_H
|
||||
#include <array.h>
|
||||
#endif
|
||||
|
||||
#ifndef __WINDOW_H
|
||||
#include <window.h>
|
||||
#endif
|
||||
|
||||
#ifndef __STRINGS_H
|
||||
#include <strings.h>
|
||||
#endif
|
||||
|
||||
#ifndef __TEXTFILE_H
|
||||
#include <text.h>
|
||||
#endif
|
||||
|
||||
class TViswin : public TScroll_window
|
||||
{
|
||||
enum { MAXBUT = 4, MAXLEN = 256, BUFFERSIZE = 256, MAXPIC=4};
|
||||
enum scroll { none, up, down, left, right };
|
||||
|
||||
TFilename _filename; // name of visfile
|
||||
bool _islink; // "link" button present
|
||||
bool _isedit; // "edit" button present
|
||||
bool _isprint; // "print" button present
|
||||
bool _iscross; // crossbars being drawn
|
||||
bool _selecting; // selection in progress
|
||||
bool _isselection; // selection active
|
||||
bool _isbar; // X-bar drawn instead of cursor at point
|
||||
bool _scrolling; // scrolling in progress
|
||||
bool _need_update; // full update required
|
||||
bool _istimer; // timer successivo attivo?
|
||||
bool _isopen; // new lines may arrive
|
||||
bool _selflag;
|
||||
bool _sel_displayed;
|
||||
bool _link_displayed;
|
||||
bool _cross_displayed;
|
||||
bool _point_displayed;
|
||||
long _timer; // timer per evitare autorepeat tasti
|
||||
long _wtimer; // wait timer before close()
|
||||
scroll _need_scroll; // scrolling required?
|
||||
bool _wasneeded; // flag for smart painting
|
||||
WINDOW _button[MAXBUT]; // button array
|
||||
int _curbut; // button which currently has focus
|
||||
int _buttons; // button count
|
||||
WINDOW _link_button;
|
||||
|
||||
long _textrows; // righe di testo
|
||||
long _textcolumns; // indovina indovinello
|
||||
|
||||
TTextfile _txt; // text being displayed
|
||||
long _firstline; // 1rst text line being displayed
|
||||
long _lastline; // last text line being displayed
|
||||
|
||||
int _formlen; // length of a page
|
||||
|
||||
TPoint _point; // current point position
|
||||
PNT _cross; // current crossbar point
|
||||
TPoint _sel_start; // start of selection (column, line of FILE)
|
||||
TPoint _sel_end; // end of selection (ibidem)
|
||||
|
||||
TArray* _links; // admitted links
|
||||
TArray* _hotspots; // hotspots
|
||||
|
||||
bool need_paint_sel(bool smart = TRUE);
|
||||
PICTURE _picture[MAXPIC]; // pictures
|
||||
PICTURE _modpic;
|
||||
bool _multiple;
|
||||
TString80 _linktxt;
|
||||
int _linkID;
|
||||
TToken_string _multiple_link;
|
||||
|
||||
TArray* _bg;
|
||||
bool _isbackground;
|
||||
bool _frozen;
|
||||
|
||||
protected:
|
||||
|
||||
virtual bool on_key (KEY);
|
||||
virtual void open();
|
||||
|
||||
void shift_screen(scroll);
|
||||
void paint_screen();
|
||||
void draw_crossbars();
|
||||
|
||||
void paint_header();
|
||||
void paint_point(bool erase = FALSE);
|
||||
void paint_row(long r);
|
||||
void paint_column(long r, bool end);
|
||||
void paint_selection();
|
||||
void paint_waitbar(bool xor = TRUE);
|
||||
void paint_background(long, int);
|
||||
bool call_editor();
|
||||
bool in_text(const TPoint& p) const;
|
||||
WINDOW add_button(short id, const char* caption);
|
||||
void repos_buttons();
|
||||
void adjust_selection(TPoint& p1, TPoint& p2);
|
||||
void display_selection();
|
||||
void erase_selection();
|
||||
void display_crossbar();
|
||||
void erase_crossbar();
|
||||
void display_point();
|
||||
void erase_point();
|
||||
bool check_link(TPoint* where = NULL);
|
||||
bool adjust_box(long& x1, long& x2, long y);
|
||||
void paint_link(long, long, long);
|
||||
void erase_link(long, long, long);
|
||||
void display_link(long, long, long, const char*);
|
||||
void freeze() { _frozen = TRUE; }
|
||||
void exec_link();
|
||||
|
||||
protected:
|
||||
|
||||
virtual void update();
|
||||
virtual void handler(WINDOW win, EVENT* ep);
|
||||
|
||||
public:
|
||||
|
||||
// gestione "collegamenti": vengono passati il testo completo,
|
||||
// il punto di inizio selezione e quello di fine selezione; se
|
||||
// non c'e' selezione non viene chiamata affatto (il bottone non fa nulla)
|
||||
// Se serve, si faccia stop_run() qui dentro
|
||||
virtual void process_link(TTextfile& txt, TPoint start, TPoint end) { }
|
||||
void close_print();
|
||||
bool frozen() { return _frozen; }
|
||||
void abort_print();
|
||||
|
||||
void add_line(const char* l);
|
||||
|
||||
TViswin (const char* fname = NULL,
|
||||
const char* title = NULL,
|
||||
bool editbutton = TRUE,
|
||||
bool printbutton = TRUE,
|
||||
bool linkbutton = TRUE);
|
||||
|
||||
virtual ~TViswin ();
|
||||
};
|
||||
|
||||
#endif
|
||||
/* This is really -*-c++-*- */
|
||||
#ifndef __VISWIN_H
|
||||
#define __VISWIN_H
|
||||
|
||||
#ifndef __ARRAY_H
|
||||
#include <array.h>
|
||||
#endif
|
||||
|
||||
#ifndef __WINDOW_H
|
||||
#include <window.h>
|
||||
#endif
|
||||
|
||||
#ifndef __STRINGS_H
|
||||
#include <strings.h>
|
||||
#endif
|
||||
|
||||
#ifndef __TEXTFILE_H
|
||||
#include <text.h>
|
||||
#endif
|
||||
|
||||
class TViswin : public TScroll_window
|
||||
{
|
||||
enum { MAXBUT = 4, MAXLEN = 256, BUFFERSIZE = 256, MAXPIC=4};
|
||||
enum scroll { none, up, down, left, right };
|
||||
|
||||
TFilename _filename; // name of visfile
|
||||
bool _islink; // "link" button present
|
||||
bool _isedit; // "edit" button present
|
||||
bool _isprint; // "print" button present
|
||||
bool _iscross; // crossbars being drawn
|
||||
bool _selecting; // selection in progress
|
||||
bool _isselection; // selection active
|
||||
bool _isbar; // X-bar drawn instead of cursor at point
|
||||
bool _scrolling; // scrolling in progress
|
||||
bool _need_update; // full update required
|
||||
bool _istimer; // timer successivo attivo?
|
||||
bool _isopen; // new lines may arrive
|
||||
bool _selflag;
|
||||
bool _sel_displayed;
|
||||
bool _link_displayed;
|
||||
bool _cross_displayed;
|
||||
bool _point_displayed;
|
||||
long _timer; // timer per evitare autorepeat tasti
|
||||
long _wtimer; // wait timer before close()
|
||||
scroll _need_scroll; // scrolling required?
|
||||
bool _wasneeded; // flag for smart painting
|
||||
WINDOW _button[MAXBUT]; // button array
|
||||
int _curbut; // button which currently has focus
|
||||
int _buttons; // button count
|
||||
WINDOW _link_button;
|
||||
|
||||
long _textrows; // righe di testo
|
||||
long _textcolumns; // indovina indovinello
|
||||
|
||||
TTextfile _txt; // text being displayed
|
||||
long _firstline; // 1rst text line being displayed
|
||||
long _lastline; // last text line being displayed
|
||||
|
||||
int _formlen; // length of a page
|
||||
|
||||
TPoint _point; // current point position
|
||||
PNT _cross; // current crossbar point
|
||||
TPoint _sel_start; // start of selection (column, line of FILE)
|
||||
TPoint _sel_end; // end of selection (ibidem)
|
||||
|
||||
TArray* _links; // admitted links
|
||||
TArray* _hotspots; // hotspots
|
||||
|
||||
bool need_paint_sel(bool smart = TRUE);
|
||||
PICTURE _picture[MAXPIC]; // pictures
|
||||
PICTURE _modpic;
|
||||
bool _multiple;
|
||||
TString80 _linktxt;
|
||||
int _linkID;
|
||||
TToken_string _multiple_link;
|
||||
|
||||
TArray* _bg;
|
||||
bool _isbackground;
|
||||
bool _frozen;
|
||||
|
||||
protected:
|
||||
|
||||
virtual bool on_key (KEY);
|
||||
virtual void open();
|
||||
|
||||
void shift_screen(scroll);
|
||||
void paint_screen();
|
||||
void draw_crossbars();
|
||||
|
||||
void paint_header();
|
||||
void paint_point(bool erase = FALSE);
|
||||
void paint_row(long r);
|
||||
void paint_column(long r, bool end);
|
||||
void paint_selection();
|
||||
void paint_waitbar(bool xor = TRUE);
|
||||
void paint_background(long, int);
|
||||
bool call_editor();
|
||||
bool in_text(const TPoint& p) const;
|
||||
WINDOW add_button(short id, const char* caption);
|
||||
void repos_buttons();
|
||||
void adjust_selection(TPoint& p1, TPoint& p2);
|
||||
void display_selection();
|
||||
void erase_selection();
|
||||
void display_crossbar();
|
||||
void erase_crossbar();
|
||||
void display_point();
|
||||
void erase_point();
|
||||
bool check_link(TPoint* where = NULL);
|
||||
bool adjust_box(long& x1, long& x2, long y);
|
||||
void paint_link(long, long, long);
|
||||
void erase_link(long, long, long);
|
||||
void display_link(long, long, long, const char*);
|
||||
void freeze() { _frozen = TRUE; }
|
||||
void exec_link();
|
||||
|
||||
protected:
|
||||
|
||||
virtual void update();
|
||||
virtual void handler(WINDOW win, EVENT* ep);
|
||||
|
||||
public:
|
||||
|
||||
// gestione "collegamenti": vengono passati il testo completo,
|
||||
// il punto di inizio selezione e quello di fine selezione; se
|
||||
// non c'e' selezione non viene chiamata affatto (il bottone non fa nulla)
|
||||
// Se serve, si faccia stop_run() qui dentro
|
||||
virtual void process_link(TTextfile& txt, TPoint start, TPoint end) { }
|
||||
void close_print();
|
||||
bool frozen() { return _frozen; }
|
||||
void abort_print();
|
||||
|
||||
void add_line(const char* l);
|
||||
|
||||
TViswin (const char* fname = NULL,
|
||||
const char* title = NULL,
|
||||
bool editbutton = TRUE,
|
||||
bool printbutton = TRUE,
|
||||
bool linkbutton = TRUE);
|
||||
|
||||
virtual ~TViswin ();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user