From 00cd69e1f6d863d7789094f61574e0d7fbde032e Mon Sep 17 00:00:00 2001
From: guy <guy@c028cbd2-c16b-5b4b-a496-9718f37d4682>
Date: Mon, 9 Jan 1995 16:51:21 +0000
Subject: [PATCH] Aggiunti campi alternativi nei JOIN delle relazioni

git-svn-id: svn://10.65.10.50/trunk@839 c028cbd2-c16b-5b4b-a496-9718f37d4682
---
 include/form.cpp     | 68 ++++++++++++++++++++-------------
 include/form.h       |  5 +++
 include/relation.cpp | 89 +++++++++++++++++++++++++++++---------------
 include/relation.h   |  8 ++--
 include/strings.cpp  |  3 +-
 5 files changed, 112 insertions(+), 61 deletions(-)

diff --git a/include/form.cpp b/include/form.cpp
index 6a6e27298..e807603e5 100755
--- a/include/form.cpp
+++ b/include/form.cpp
@@ -268,8 +268,9 @@ void TForm_item::enable(bool on)
 void TForm_item::string_at(int x, int y, const char* s)
 {
   if (hidden()) return;
-
-  TPrintrow& row = _section->row(y-1);   // Seleziona riga di stampa
+  
+  _section->offset(x, y);
+  TPrintrow& row = _section->row(y-1);         // Seleziona riga di stampa
 
   if (_width > 0 && strlen(s) > (word)_width)  // Tronca testo se necessario
   {
@@ -277,7 +278,7 @@ void TForm_item::string_at(int x, int y, const char* s)
     __tmp_string[width()] = '\0';
     s = __tmp_string;
   }
-  row.put(s, x-1);                       // Stampa testo
+  row.put(s, x-1);                             // Stampa testo
 }
 
 
@@ -297,7 +298,7 @@ void TForm_item::send_message(const TString& cmd, TForm_item& des) const
 {
   if (cmd == "ADD" || cmd == "SUM" || cmd == "INC")
   {
-    const real n((cmd[0] != 'I') ? get() : "1.0");
+    const real n((cmd[0] == 'I') ? "1.0" : get());
     real r(des.get());
     r += n;
     des.set(r.string());
@@ -535,19 +536,24 @@ const char* TForm_string::get() const
 
 bool TForm_string::read()
 {
-  if (enabled() && _field.items())
-  {
-    const char* s = "";
-    for (int i = 0; i < _field.items(); i++)
-    {
-      s = field(i).read(section()->form()->relation());
-      if (*s) break;
-    }
-    set(s);
-    return TRUE;
-  }
+  bool ok = TRUE;
 
-  return FALSE;
+  if (enabled())
+  {                    
+    if (_field.items())
+    {
+      const char* s = "";
+      const TRelation* r = section()->form()->relation(); 
+      for (int i = 0; i < _field.items(); i++)
+      {
+        s = field(i).read(r);
+        if (*s) break;
+      }
+      set(s);
+    }  
+  } else ok = FALSE;
+
+  return ok;
 }
 
 void TForm_string::put_paragraph(const char* s)
@@ -567,10 +573,9 @@ void TForm_string::put_paragraph(const char* s)
 
 bool TForm_string::update()
 {
-  TForm_item::update();
-  
   if (read())
   {
+    TForm_item::update();
     if (_picture.not_empty())
     {
       TString80 p;
@@ -595,7 +600,7 @@ protected:
   virtual bool parse_head(TScanner& scanner);
   virtual bool update();
   
-  int decimals() const { return height(); }
+  int decimals() const { return _height; }
 
 public:
   TForm_number(TPrint_section* section) : TForm_string(section) {}
@@ -613,14 +618,14 @@ bool TForm_number::parse_head(TScanner& scanner)
 
 bool TForm_number::update()
 {
-  TForm_item::update();
   if (read())
   {              
+    TForm_item::update();
     const char* s = get();
     real n(s);
     n.round(decimals());
     s = n.string(picture());
-    put_paragraph(s);
+    string_at(-1, _y, s);
   }
   return TRUE;
 }
@@ -650,11 +655,8 @@ TForm_date::TForm_date(TPrint_section* section)
 bool TForm_date::read()
 {                        
   bool ok = TForm_string::read();
-  if ((!ok || !get()[0]) && automagic()) 
-  {
+  if (ok && !get()[0] && automagic()) 
     set(main_app().printer().getdate());
-    ok = TRUE;
-  }  
   return ok;
 }
 
@@ -857,6 +859,12 @@ TPrintrow& TPrint_section::row(int num)
   return *pr;
 }
 
+void TPrint_section::offset(int& x, int& y) const
+{
+  if (x >= 0) x += _x;
+  if (y >= 0) y += _y;
+}
+
 
 TForm_item* TPrint_section::parse_item(const TString& s)
 {
@@ -885,6 +893,8 @@ TForm_item* TPrint_section::parse_item(TScanner& scanner)
 bool TPrint_section::parse(TScanner& scanner)
 {
   _height = scanner.integer();
+  _x = scanner.integer();
+  _y = scanner.integer();
 
   while (scanner.popkey() != "EN")
   {
@@ -930,6 +940,8 @@ bool TPrint_section::edit(const char* title)
   m.set_caption(title);
   
   m.set(F_HEIGHT, _height);
+  m.set(F_X, _x);
+  m.set(F_Y, _y);
   
   if (m.run() == K_ESC)
     return FALSE;
@@ -937,7 +949,11 @@ bool TPrint_section::edit(const char* title)
   bool dirty = m.dirty() != 0; 
   
   if (dirty)
+  {
     _height = m.get_int(F_HEIGHT);
+    _x = m.get_int(F_X);
+    _y = m.get_int(F_Y);
+  }
   
   TArray_sheet a(-1, -1, 0, 0, title, "Tipo@8|Riga|Col.|Gr.|Descrizione@40", 0xE);
 
@@ -1002,7 +1018,7 @@ bool TPrint_section::edit(const char* title)
 
 void TPrint_section::print_on(ostream& out) const
 {
-  out << ' ' << _height << endl;
+  out << ' ' << _height << ' ' << _x << ' ' << _y << endl;
   for(word i = 0; i < fields(); i++)
     out << field(i);
 }
diff --git a/include/form.h b/include/form.h
index e7d4ba10b..1f59e7b1e 100755
--- a/include/form.h
+++ b/include/form.h
@@ -28,6 +28,7 @@ class TPrint_section : public TArray
   static TMask* _msk;
 
   word _height;         // Altezza della sezione
+  int _x, _y;           // Offset di stampa   
 
   TForm* _form;         // Form cui appartiene alla sezione
   TArray _item;         // Lista dei campi da stampare
@@ -46,6 +47,10 @@ public:
   TForm_item& field(int n) const { return (TForm_item&)_item[n]; }
   word fields() const { return _item.items(); }
   word height() const { return _height; }
+  int offset_x() const { return _x; }
+  int offset_y() const { return _y; }
+  void offset(int& x, int& y) const;
+  
   virtual bool ok() const { return height() > 0 || fields() > 0; }
   
   void reset();
diff --git a/include/relation.cpp b/include/relation.cpp
index bf0488243..53d3adf26 100755
--- a/include/relation.cpp
+++ b/include/relation.cpp
@@ -1,4 +1,4 @@
-//      $Id: relation.cpp,v 1.29 1995-01-03 15:06:36 guy Exp $
+//      $Id: relation.cpp,v 1.30 1995-01-09 16:51:18 guy Exp $
 // relation.cpp
 // fv 12/8/93
 // relation class for isam files
@@ -36,10 +36,11 @@ class TRelationdef : public TObject
   const TRelation* _rel;          // Relazione padre
   int        _num;                // Posizione file
   int        _numto;              // Posizione padre
-  byte       _alias;              // Alias
+  int        _alias;              // Alias
   byte       _key;                // Chiave
   TArray     _fields;             // Campi di join
   TArray     _exprs;              // Condizioni di uguaglianza
+  TArray     _altexprs;           // Condizioni di uguaglianza alternative
   TBit_array _forced;
   bool       _first_match  : 1;   // primo match (ed esiste)
   bool       _allow_lock   : 1;   // ?????
@@ -53,13 +54,14 @@ public:
   // @FPUB
   int num() const { return _num; }
   int link() const { return _numto; }
-  byte alias() const { return _alias; }
+  int alias() const { return _alias; }
   bool write_enable() const { return _write_enable; }
   void write_enable(bool we) { _write_enable = we; }
   TRectype& load_rec(TRectype& r, const TBaseisamfile& from) const;
+  const char* evaluate_expr(int j, const TLocalisamfile& to);
 
   TRelationdef(const TRelation* rel, int file, byte key,
-               int linkto, const char* relexprs, byte alias,
+               int linkto, const char* relexprs, int alias,
                bool allow_lock, bool write_enable = FALSE);
   virtual ~TRelationdef() {}
 };
@@ -67,7 +69,7 @@ public:
 
 
 TRelationdef::TRelationdef(const TRelation* rel, int idx_file, byte key, 
-                           int idx_to, const char* relexprs, byte alias,
+                           int idx_to, const char* relexprs, int alias,
                            bool allow_lock, bool write_enable)
 : _num(idx_file), _key(key), _numto(idx_to),
   _rel(rel), _fields(4), _exprs(4), _alias(alias),
@@ -105,11 +107,17 @@ TRelationdef::TRelationdef(const TRelation* rel, int idx_file, byte key,
       eq++;
     }
     
-    //    const TString80 xx(s);        
-    //    _fields.add(new TFieldref(xx,0));
-    _fields.add(new TFieldref(s,0));                                   
+    _fields.add(new TFieldref(s, 0));                                   
     
-    _exprs.add(new TExpression(r.mid(eq+1), _strexpr));
+    s = r.mid(eq+1);
+    const int par = s.find('(');
+    if (par > 0)
+    {
+      _exprs.add(new TExpression(s.left(par), _strexpr), i);
+      _altexprs.add(new TExpression(s.sub(par+1, s.len()-1), _strexpr), i);
+    }
+    else 
+      _exprs.add(new TExpression(s, _strexpr), i);
   }
 }
 
@@ -135,12 +143,16 @@ void TRelationdef::print_on(ostream& out) const
 
   if (_key > 1) out << " KEY " << (int)_key;
 
-  if (_alias > 0) out << " ALIAS " << (int)_alias;
+  if (_alias > 0) out << " ALIAS " << _alias;
 
   for (int i = 0; i < _fields.items(); i++)
   {
     if (i == 0) out << " INTO";
-    out << ' ' << _fields[i] << '=' << _exprs[i];
+    out << ' ' << _fields[i] << '=';
+    if (_forced[i]) out << '=';
+    out << _exprs[i];
+    if (_altexprs.objptr(i))
+      out << '(' << _altexprs[i] << ')';
   }
 }
 
@@ -172,11 +184,34 @@ void TRelationdef::print_on(TToken_string& out) const
   for (int i = 0; i < _fields.items(); i++)
   {          
     if (i) out << ' ';
-    out << _fields[i] << '=' << _exprs[i];
+    out << _fields[i] << '='; 
+    if (_forced[i]) out << '=';
+    out << _exprs[i];
+    if (_altexprs.objptr(i))
+      out << '(' << _altexprs[i] << ')';
   }
 }
 
 
+const char* TRelationdef::evaluate_expr(int j, const TLocalisamfile& to)
+{             
+  TExpression& expr = (TExpression&)_exprs[j];
+  for (int k = 0; k < expr.numvar(); k++)
+    expr.setvar(k, to.get(expr.varname(k)));
+  
+  const char* val = expr;
+  
+  if (*val == '\0' && _altexprs.objptr(j))
+  {
+    TExpression& altexpr = (TExpression&)_altexprs[j];
+    for (int k = 0; k < expr.numvar(); k++)
+      altexpr.setvar(k, to.get(altexpr.varname(k)));
+    val = altexpr;
+  }
+
+  return val;
+}  
+
 ///////////////////////////////////////////////////////////
 // TRelation
 ///////////////////////////////////////////////////////////
@@ -271,7 +306,7 @@ int TRelation::log2ind(int log) const
   // NOTFOUND if not present
   // sets error status
 
-  if (log < 0) return alias2ind(byte(-log));
+  if (log < 0) return alias2ind(-log);
   
   const int num = _files.items();
   if (log > 0)
@@ -282,7 +317,7 @@ int TRelation::log2ind(int log) const
   return num ? 0 : NOTFOUND;
 }
 
-int TRelation::alias2ind(byte alias) const
+int TRelation::alias2ind(int alias) const
 {
   if (alias < 1) return 0;
   
@@ -341,7 +376,7 @@ void TRelation::write_enable(const char* name, const bool on)
 }
 
 bool TRelation::add(int logicnum, const char* relexprs, int key,
-                    int linkto, byte alias, bool allow_lock)
+                    int linkto, int alias, bool allow_lock)
 {
   const int idxto = log2ind(linkto);
   if (idxto == NOTFOUND)
@@ -361,7 +396,7 @@ bool TRelation::add(int logicnum, const char* relexprs, int key,
 }
 
 bool TRelation::add(const char* tabname, const char* relexprs, int key,
-                    int linkto, byte alias, bool allow_lock)
+                    int linkto, int alias, bool allow_lock)
   
 {
   // look for <to> file
@@ -429,20 +464,18 @@ int TRelation::position_rels(TIsamop op, TReclock lockop,
     {
       for (int j = 0 ; j < rd._fields.items(); j++) // for each field
       {
-        TExpression& expr = (TExpression&)rd._exprs[j];
-
-        // setvar for every variable
-        for (int k = 0; k < expr.numvar(); k++)
-          expr.setvar(k, to.get(expr.varname(k)));
-
-        // eval expression and put result in field
-
+        /*      
+           TExpression& expr = (TExpression&)rd._exprs[j];
+           for (int k = 0; k < expr.numvar(); k++)
+           expr.setvar(k, to.get(expr.varname(k)));
+           */     
+        const char* expr = rd.evaluate_expr(j, to);
         TFieldref& s = (TFieldref&) rd._fields[j];
         s.write(expr, from.curr());
       } // for each field
     }
 
-    // read record: if not found, empty current record
+    // read record: if not found, zero current record
     TRectype rec(from.curr());
     from.read(op, lck, atdate);
     if (from.bad())
@@ -458,11 +491,7 @@ int TRelation::position_rels(TIsamop op, TReclock lockop,
           {
             TFieldref& fl = (TFieldref&)rd._fields[kk];
             const TString f_fr(fl.read(from.curr()));
-
-            TExpression& expr = (TExpression&)rd._exprs[kk];
-            for (int k = 0; k < expr.numvar(); k++)
-              expr.setvar(k, to.get(expr.varname(k)));
-            eq = (f_fr == (const char*)expr);
+            eq = (f_fr == rd.evaluate_expr(kk, to));
           }
         }
         if (eq) from.setstatus(NOERR);
diff --git a/include/relation.h b/include/relation.h
index 06f854f8e..c83b70edf 100755
--- a/include/relation.h
+++ b/include/relation.h
@@ -1,4 +1,4 @@
-/*      $Id: relation.h,v 1.9 1994-12-20 15:11:23 guy Exp $      */
+/*      $Id: relation.h,v 1.10 1995-01-09 16:51:20 guy Exp $      */
 // join.h
 // fv 12/8/93
 // join class for isam files
@@ -31,7 +31,7 @@ protected:
   virtual void print_on(ostream& out) const;
 
   int log2ind(int logicnum) const;
-  int alias2ind(byte alias) const;
+  int alias2ind(int alias) const;
   int name2ind(const char* name) const;
 
   TRelationdef& reldef(int i) const { return (TRelationdef&)_reldefs[i]; }
@@ -76,9 +76,9 @@ public:
   // @DES add relation
   // @FPUB
   bool add(int logicnum, const char* relexprs, int key = 1,
-           int linkto = 0, byte alias = 0, bool allow_lock = FALSE);
+           int linkto = 0, int 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);
+           int linkto = 0, int alias = 0, bool allow_lock = FALSE);
 
 
   // @DES write methods
diff --git a/include/strings.cpp b/include/strings.cpp
index 7bc50648f..4e1f29b67 100755
--- a/include/strings.cpp
+++ b/include/strings.cpp
@@ -401,12 +401,13 @@ TString& TString::picture(const char* pic, const char* s)
 
   set(pic);
 
-  int l = strlen(s)-1;  // Prossimo carattere da sostituire a #
+  int l = strlen(s)-1;  // Prossimo carattere da sostituire a # o @
 
   for (int i = len()-1; i >= 0; i--)
   {
     const char k = pic[i];
     if (k == '#') _str[i] = (l >= 0) ? s[l--] : ' ';
+    else if (k == '@') _str[i] = (l >= 0) ? s[l--] : '0';
     else if (k == '~') { _str[i] = ' '; l--; }
   }