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