Patch level : 2.1 nopatch
Files correlati : Ricompilazione Demo : [ ] Commento : Ristrutturzione delle calssi TVariant e TAlex in modo da renderle completamente indipendenti dalle stampe e dai recordset git-svn-id: svn://10.65.10.50/trunk@12181 c028cbd2-c16b-5b4b-a496-9718f37d4682
This commit is contained in:
		
							parent
							
								
									f72c70c29b
								
							
						
					
					
						commit
						dcd927717e
					
				
							
								
								
									
										116
									
								
								include/alex.cpp
									
									
									
									
									
								
							
							
						
						
									
										116
									
								
								include/alex.cpp
									
									
									
									
									
								
							| @ -1,85 +1,17 @@ | ||||
| #include <ctype.h> | ||||
| #include <stdlib.h> | ||||
| 
 | ||||
| #include <alex.h> | ||||
| #include <automask.h> | ||||
| #include <colors.h> | ||||
| #include <defmask.h> | ||||
| #include <dongle.h> | ||||
| #include <prefix.h> | ||||
| #include <recarray.h> | ||||
| #include <reprint.h> | ||||
| #include <statbar.h> | ||||
| #include <urldefid.h> | ||||
| #include <utility.h> | ||||
| 
 | ||||
| TVariant& TVariant_stack::peek(int depth) | ||||
| { | ||||
|   const int sp = _sp-depth-1; | ||||
|   return sp >= 0 ? (TVariant&)_var[sp] : (TVariant &)NULL_VARIANT; | ||||
| } | ||||
| 
 | ||||
| bool TVariant_stack::drop() | ||||
| { | ||||
|   if (_sp > 0) | ||||
|   { | ||||
|     _sp--; | ||||
|     return true; | ||||
|   } | ||||
|   return false; | ||||
| } | ||||
| 
 | ||||
| TVariant& TVariant_stack::pop() | ||||
| { | ||||
|   TVariant& var = peek(0); | ||||
|   drop(); | ||||
|   return var; | ||||
| } | ||||
| 
 | ||||
| void TVariant_stack::roll(int depth) | ||||
| { | ||||
|   const int sp = _sp-depth-1; | ||||
|   if (sp >= 0) | ||||
|   { | ||||
|     TObject* var = _var.remove(sp, true); | ||||
|     _var.insert(var, _sp-1); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| void TVariant_stack::push(const TVariant& var) | ||||
| { | ||||
|   if (_var.objptr(_sp) == NULL) | ||||
|     _var.add(var, _sp); | ||||
|   else | ||||
|     (TVariant&)_var[_sp] = var; | ||||
|   _sp++; | ||||
| } | ||||
| 
 | ||||
| void TVariant_stack::push(long n) | ||||
| { | ||||
|   const TVariant var(n); | ||||
|   push(var); | ||||
| } | ||||
| 
 | ||||
| void TVariant_stack::push(const real& n) | ||||
| { | ||||
|   const TVariant var(n); | ||||
|   push(var); | ||||
| } | ||||
| 
 | ||||
| void TVariant_stack::push(const char* str) | ||||
| { | ||||
|   const TVariant var(str); | ||||
|   push(var); | ||||
| } | ||||
| 
 | ||||
| void TVariant_stack::reset() | ||||
| { | ||||
|   _sp = 0; | ||||
| } | ||||
| 
 | ||||
| bool TVariant_stack::overflow() const | ||||
| { | ||||
|   return _sp > 2048; | ||||
| } | ||||
| 
 | ||||
| ///////////////////////////////////////////////////////////
 | ||||
| // TAVM_op
 | ||||
| ///////////////////////////////////////////////////////////
 | ||||
| @ -391,15 +323,17 @@ TField_window* TAVM_stack_field::create_window(int x, int y, int dx, int dy, WIN | ||||
| 
 | ||||
| class TAVM_monitor : public TAutomask | ||||
| { | ||||
|   TAVM_list_window *_lw; | ||||
|   TAVM_stack_window *_sw, *_rw; | ||||
| 
 | ||||
| protected: | ||||
|   TMask_field* parse_field(TScanner& scanner); | ||||
|   virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly); | ||||
|   virtual bool on_key(KEY k); | ||||
| 
 | ||||
| public: | ||||
|   TAVM_list_window& monitor() { return (TAVM_list_window&)((TAVM_list_field&)field(101)).win(); } | ||||
|   TAVM_stack_window& stacker() { return (TAVM_stack_window&)((TAVM_list_field&)field(102)).win(); } | ||||
|   TAVM_stack_window& rstacker() { return (TAVM_stack_window&)((TAVM_list_field&)field(103)).win(); } | ||||
|   TAVM_list_window& monitor() const { return *_lw; } | ||||
|   TAVM_stack_window& stacker() const { return *_sw; } | ||||
|   TAVM_stack_window& rstacker() const { return *_rw; } | ||||
|   TAVM_monitor(); | ||||
| }; | ||||
| 
 | ||||
| @ -421,18 +355,25 @@ bool TAVM_monitor::on_key(KEY k) | ||||
|   return TAutomask::on_key(k); | ||||
| } | ||||
| 
 | ||||
| TMask_field* TAVM_monitor::parse_field(TScanner& scanner) | ||||
| TAVM_monitor::TAVM_monitor() : TAutomask("Monitor", 1, 50, 20) | ||||
| { | ||||
|   if (scanner.token().starts_with("LI")) | ||||
|     return new TAVM_list_field(this); | ||||
|   if (scanner.token().starts_with("ST")) | ||||
|     return new TAVM_stack_field(this); | ||||
|   return TAutomask::parse_field(scanner); | ||||
| } | ||||
|   TWindowed_field* wf = new TAVM_list_field(this); | ||||
|   wf->create(101, 0, 0, 24, -3); add_field(wf); | ||||
|   _lw = (TAVM_list_window*)&wf->win(); | ||||
| 
 | ||||
|   TWindowed_field* sf = new TAVM_stack_field(this); | ||||
|   sf->create(102, 27, 0, -3, 10); add_field(sf); | ||||
|   _sw = (TAVM_stack_window*)&sf->win(); | ||||
| 
 | ||||
|   TWindowed_field* rf = new TAVM_stack_field(this); | ||||
|   rf->create(103, 27, 11, -3, -3); add_field(rf); | ||||
|   _rw = (TAVM_stack_window*)&rf->win(); | ||||
| 
 | ||||
|   add_button(DLG_NEXTREC, 0, "", -14, -1, 10, 2, "", 124).set_exit_key(K_F11); | ||||
|   add_button(DLG_LASTREC, 0, "", -24, -1, 10, 2, "", 1671).set_exit_key(K_F10); | ||||
|   add_button(DLG_ELABORA, 0, "", -34, -1, 10, 2, "", BMP_LASTREC).set_exit_key(K_F5); | ||||
|   add_button(DLG_QUIT,    0, "", -44, -1, 10, 2).set_exit_key(K_QUIT); | ||||
| 
 | ||||
| TAVM_monitor::TAVM_monitor() | ||||
| { | ||||
|   read_mask("ba8300m", 0, -1);  | ||||
|   set_handlers(); | ||||
| } | ||||
| 
 | ||||
| @ -1040,6 +981,7 @@ bool TAVM::execute(const TBytecode& cmdline) | ||||
| { | ||||
|   const TBytecode* old_bc = _bc; | ||||
|   const int old_ip = _ip; | ||||
|   bool aborted = false; | ||||
|    | ||||
|   _stack.reset(); | ||||
|   _rstack.reset(); | ||||
| @ -1100,7 +1042,7 @@ bool TAVM::execute(const TBytecode& cmdline) | ||||
|           op.set_auto_break(true); | ||||
|         } | ||||
|         break; | ||||
|       case K_QUIT: abort_printing(); | ||||
|       case K_QUIT: aborted = true; | ||||
|       case K_F5  : _mon.close_modal(); break; | ||||
|       default: break; | ||||
|       }   | ||||
| @ -1118,7 +1060,7 @@ bool TAVM::execute(const TBytecode& cmdline) | ||||
|   _bc = old_bc; | ||||
|   _ip = old_ip; | ||||
|    | ||||
|   return true; | ||||
|   return !aborted; | ||||
| } | ||||
| 
 | ||||
| void TAVM::do_restart(bool cold) | ||||
|  | ||||
| @ -1,32 +1,10 @@ | ||||
| #ifndef __ALEX_H | ||||
| #define __ALEX_H | ||||
| 
 | ||||
| #ifndef __RECORDSET_H | ||||
| #include <recset.h> | ||||
| #ifndef __VARIANT_H | ||||
| #include <variant.h> | ||||
| #endif | ||||
| 
 | ||||
| class TVariant_stack : public TObject | ||||
| { | ||||
|   TArray _var; | ||||
|   int _sp; | ||||
| 
 | ||||
| public: | ||||
|   int items() const { return _sp; } | ||||
|   bool drop(); | ||||
|   TVariant& pop(); | ||||
|   TVariant& peek(int depth = 0); | ||||
|   void roll(int depth); | ||||
| 
 | ||||
|   void push(const TVariant& var); | ||||
|   void push(long n); | ||||
|   void push(const real& n); | ||||
|   void push(const char* str); | ||||
|   void reset(); | ||||
|   bool overflow() const; | ||||
| 
 | ||||
|   TVariant_stack() : _sp(0) { } | ||||
| }; | ||||
| 
 | ||||
| // Generic bytecode for any language
 | ||||
| 
 | ||||
| class TBytecode : public TArray | ||||
|  | ||||
| @ -165,7 +165,12 @@ void TAutomask::set_handlers() | ||||
| 
 | ||||
| 
 | ||||
| TAutomask::TAutomask(const char* name, int num) | ||||
|              : TMask(name, num) | ||||
|          : TMask(name, num) | ||||
| { | ||||
|   set_handlers(); | ||||
| } | ||||
| 
 | ||||
| TAutomask::TAutomask(const char* title, int pages, int cols, int rows, int xpos, int ypos) | ||||
|          : TMask(title, pages, cols, rows, xpos, ypos) | ||||
| { | ||||
| } | ||||
|  | ||||
| @ -28,6 +28,7 @@ public: | ||||
| 
 | ||||
|   TAutomask() { } | ||||
|   TAutomask(const char* name, int num = 0); | ||||
|   TAutomask(const char* title, int pages, int cols, int rows, int xpos = -1, int ypos = -1); | ||||
|   virtual ~TAutomask() { } | ||||
| }; | ||||
| 
 | ||||
|  | ||||
| @ -3,7 +3,11 @@ | ||||
| #include <checks.h> | ||||
| #include <keys.h> | ||||
| 
 | ||||
| #ifdef WIN32 | ||||
| #define buildmsg() char msg[256];va_list argptr;va_start(argptr,fmt);_vsnprintf(msg,sizeof(msg),fmt,argptr);va_end(argptr) | ||||
| #else | ||||
| #define buildmsg() char msg[256];va_list argptr;va_start(argptr,fmt);vsprintf(msg,fmt,argptr);va_end(argptr) | ||||
| #endif | ||||
| 
 | ||||
| // @doc EXTERNAL
 | ||||
| 
 | ||||
|  | ||||
| @ -4954,12 +4954,17 @@ TField_window* TWindowed_field::create_window(int x, int y, int dx, int dy, WIND | ||||
|   return new TField_window(x, y, dx, dy, parent, this); | ||||
| } | ||||
| 
 | ||||
| void TWindowed_field::create(short id, int x, int y, int dx, int dy, WINDOW parent) | ||||
| { | ||||
|   if (parent == NULL_WIN) | ||||
|     parent = mask().win(); | ||||
|   _dlg = id; | ||||
|   _win = create_window(x, y, dx, dy, parent); | ||||
| } | ||||
| 
 | ||||
| void TWindowed_field::create(WINDOW parent) | ||||
| {         | ||||
|   _dlg = _ctl_data._dlg; | ||||
|   _win = create_window(_ctl_data._x, _ctl_data._y,  | ||||
|                        _ctl_data._width, _ctl_data._height,  | ||||
|                        parent); | ||||
|   create(_ctl_data._dlg, _ctl_data._x, _ctl_data._y, _ctl_data._width, _ctl_data._height, parent); | ||||
| } | ||||
| 
 | ||||
| TWindowed_field::~TWindowed_field()  | ||||
|  | ||||
| @ -1578,7 +1578,6 @@ protected:  // TMask_field | ||||
| protected: | ||||
|   virtual TField_window* create_window(int x, int y, int dx, int dy,  | ||||
|                                        WINDOW parent) pure; | ||||
| 
 | ||||
| public:     // TMask_field
 | ||||
|   virtual short dlg() const; | ||||
|   virtual WINDOW parent() const { return win().parent(); } | ||||
| @ -1589,8 +1588,10 @@ public:     // TMask_field | ||||
| 
 | ||||
| public: | ||||
|   TField_window& win() const { CHECK(_win, "NULL Window in field"); return *_win; } | ||||
|    | ||||
| 
 | ||||
|   TWindowed_field(TMask* m) : TOperable_field(m), _dlg(0), _win(NULL) { } | ||||
|   void create(short id, int x, int y, int dx, int dy, WINDOW parent = NULL_WIN); | ||||
| 
 | ||||
|   virtual ~TWindowed_field(); | ||||
| }; | ||||
| 
 | ||||
|  | ||||
| @ -10,252 +10,6 @@ | ||||
| 
 | ||||
| #include <statbar.h> | ||||
| 
 | ||||
| ///////////////////////////////////////////////////////////
 | ||||
| // TVariant
 | ||||
| ///////////////////////////////////////////////////////////
 | ||||
| 
 | ||||
| const TVariant NULL_VARIANT; | ||||
| 
 | ||||
| void TVariant::set_null() | ||||
| { | ||||
|   if (_ptr != NULL) | ||||
|   { | ||||
|     if (_type != _nullfld && _type != _longfld) | ||||
|       delete (char *) _ptr; | ||||
|     _ptr = NULL; | ||||
|   } | ||||
|   _type = _nullfld; | ||||
| } | ||||
| 
 | ||||
| void TVariant::set(const char* str) | ||||
| { | ||||
|   if (str != NULL) | ||||
|   { | ||||
|     if (_type == _alfafld) | ||||
|       *((TString*)_ptr) = str; | ||||
|     else | ||||
|     { | ||||
|       set_null(); | ||||
|       _type = _alfafld; | ||||
|       _ptr = new TString(str); | ||||
|     } | ||||
|   } | ||||
|   else | ||||
|     set_null(); | ||||
| } | ||||
| 
 | ||||
| void TVariant::set(const real& r) | ||||
| { | ||||
|   if (_type == _realfld) | ||||
|     *((real*)_ptr) = r; | ||||
|   else | ||||
|   { | ||||
|     set_null(); | ||||
|     _type = _realfld; | ||||
|     _ptr = new real(r); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| void TVariant::set(const TDate& d) | ||||
| { | ||||
|   if (_type == _datefld) | ||||
|     *((TDate*)_ptr) = d; | ||||
|   else | ||||
|   { | ||||
|     set_null(); | ||||
|     _type = _datefld; | ||||
|     _ptr = new TDate(d); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| void TVariant::set(const long n) | ||||
| { | ||||
|   if (_type != _longfld) | ||||
|     set_null(); | ||||
|   _type = _longfld; | ||||
|   _ptr = (void*)n; | ||||
| } | ||||
| 
 | ||||
| bool TVariant::is_zero() const | ||||
| { | ||||
|   switch (_type) | ||||
|   { | ||||
|   case _datefld: return !as_date().ok(); | ||||
|   case _longfld: return _ptr == NULL; | ||||
|   case _realfld: return as_real().is_zero(); | ||||
|   case _alfafld: return real::is_null(as_string()); | ||||
|   default: break; | ||||
|   } | ||||
|   return true; | ||||
| } | ||||
| 
 | ||||
| bool TVariant::is_empty() const | ||||
| { | ||||
|  if (_type == _alfafld) | ||||
|    return as_string().empty(); | ||||
|  return is_zero(); | ||||
| } | ||||
| 
 | ||||
| TDate TVariant::as_date() const | ||||
| { | ||||
|   if (_type == _datefld) | ||||
|     return *(TDate*)_ptr; | ||||
|   if (_type == _intfld || _type == _realfld) | ||||
|     return TDate(as_int()); | ||||
|   return TDate(as_string()); | ||||
| } | ||||
| 
 | ||||
| long TVariant::as_int() const | ||||
| { | ||||
|   long n = 0; | ||||
|   switch(_type) | ||||
|   { | ||||
|   case _datefld: n = as_date().date2ansi(); break; | ||||
|   case _longfld: n = (long)_ptr; break; | ||||
|   case _realfld: n = as_real().integer(); break; | ||||
|   case _alfafld: n = atoi(as_string()); break; | ||||
|   default : break; | ||||
|   } | ||||
|   return n; | ||||
| } | ||||
| 
 | ||||
| bool TVariant::as_bool() const | ||||
| { | ||||
|   bool ok = false; | ||||
|   if (_type == _alfafld) | ||||
|     ok = strchr("1XY", as_string()[0]) != NULL; | ||||
|   else | ||||
|     ok = as_int() != 0; | ||||
|   return ok; | ||||
| } | ||||
| 
 | ||||
| COLOR TVariant::as_color() const | ||||
| { | ||||
|   const unsigned long rgb = as_int(); | ||||
|   unsigned char r = XVT_COLOR_GET_RED(rgb); | ||||
|   unsigned char g = XVT_COLOR_GET_GREEN(rgb); | ||||
|   unsigned char b = XVT_COLOR_GET_BLUE(rgb); | ||||
|   return MAKE_COLOR(r, g, b); | ||||
| } | ||||
| 
 | ||||
| real TVariant::as_real() const | ||||
| { | ||||
|   if (_type == _realfld) | ||||
|     return *(real*)_ptr; | ||||
|   switch(_type) | ||||
|   { | ||||
|   case _alfafld: return real(as_string()); break; | ||||
|   case _longfld: return real(as_int()); break; | ||||
|   default : break; | ||||
|   } | ||||
|   return ZERO; | ||||
| } | ||||
| 
 | ||||
| bool TVariant::as_string(TString& tmp) const | ||||
| { | ||||
|   tmp.cut(0); | ||||
|   switch(_type) | ||||
|   { | ||||
|   case _alfafld: tmp = *(TString*)_ptr; break; | ||||
|   case _datefld: tmp = as_date().string(); break; | ||||
|   case _longfld: tmp << as_int(); break; | ||||
|   case _realfld: tmp = as_real().string(); break; | ||||
|   default: break; | ||||
|   } | ||||
|   return !is_null(); | ||||
| } | ||||
| 
 | ||||
| const TString& TVariant::as_string() const | ||||
| { | ||||
|   if (_type == _alfafld) | ||||
|     return *(TString*)_ptr; | ||||
|   TString& tmp = get_tmp_string(); | ||||
|   as_string(tmp); | ||||
|   return tmp; | ||||
| } | ||||
| 
 | ||||
| void TVariant::convert_to(TFieldtypes ft) | ||||
| { | ||||
|   if (_type != ft) | ||||
|   { | ||||
|     switch (ft) | ||||
|     { | ||||
|     case _alfafld: set(as_string()); break; | ||||
|     case _datefld: set(as_date()); break; | ||||
|     case _longfld: set(as_int()); break; | ||||
|     case _realfld: set(as_real()); break; | ||||
|     default      : set_null(); break; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| void TVariant::copy(const TVariant& var) | ||||
| { | ||||
|   switch (var._type) | ||||
|   { | ||||
|   case _datefld: set(var.as_date()); break; | ||||
|   case _longfld: set(var.as_int()); break; | ||||
|   case _realfld: set(var.as_real()); break; | ||||
|   case _alfafld: set(var.as_string()); break; | ||||
|   default : set_null(); break; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| int TVariant::compare(const TSortable& s) const | ||||
| { | ||||
|   const TVariant& var = (const TVariant&)s; | ||||
|   int cmp = 0; | ||||
|   switch (_type) | ||||
|   { | ||||
|   case _datefld: cmp = as_date() - var.as_date(); break; | ||||
|   case _longfld: cmp = as_int() - var.as_int(); break; | ||||
|   case _realfld:  | ||||
|     { | ||||
|       const real n = as_real() - var.as_real(); | ||||
|       cmp = n.sign();  | ||||
|     } | ||||
|     break; | ||||
|   case _alfafld: cmp = as_string().compare(var.as_string()); break; | ||||
|   default : cmp = var.is_null() ? 0 : -1; | ||||
|   } | ||||
|   return cmp; | ||||
| } | ||||
| 
 | ||||
| TVariant& TVariant::add(const TVariant& var) | ||||
| { | ||||
|   switch (_type) | ||||
|   { | ||||
|   case _datefld: set(as_date() + var.as_int()); break; | ||||
|   case _longfld: set(as_int() + var.as_int()); break; | ||||
|   case _alfafld: *(TString*)_ptr << var.as_string(); break; | ||||
|   case _realfld: *(real*)_ptr += var.as_real(); break; | ||||
|   default: copy(var); break; | ||||
|   } | ||||
|   return *this; | ||||
| } | ||||
| 
 | ||||
| TVariant& TVariant::sub(const TVariant& var) | ||||
| { | ||||
|   switch (_type) | ||||
|   { | ||||
|   case _datefld: set(as_date() - var.as_int()); break; | ||||
|   case _longfld: | ||||
|     if (var.type() == _longfld) | ||||
|     { | ||||
|       set(as_int() - var.as_int()); | ||||
|       break; | ||||
|     } | ||||
|     // Fall down
 | ||||
|   default: | ||||
|     { | ||||
|       real n = as_real(); | ||||
|       n -= var.as_real(); | ||||
|       set(n); | ||||
|     } | ||||
|     break; | ||||
|   } | ||||
|   return *this; | ||||
| } | ||||
| 
 | ||||
| ///////////////////////////////////////////////////////////
 | ||||
| // TTable name converter
 | ||||
|  | ||||
| @ -9,6 +9,10 @@ | ||||
| #include <sheet.h> | ||||
| #endif | ||||
| 
 | ||||
| #ifndef __VARIANT_H | ||||
| #include <variant.h> | ||||
| #endif | ||||
| 
 | ||||
| struct TRecordset_column_info : public TObject | ||||
| { | ||||
|   TString _name;   // Table.Column
 | ||||
| @ -16,64 +20,6 @@ struct TRecordset_column_info : public TObject | ||||
|   TFieldtypes _type; | ||||
| }; | ||||
| 
 | ||||
| ///////////////////////////////////////////////////////////
 | ||||
| // TVariant
 | ||||
| ///////////////////////////////////////////////////////////
 | ||||
| 
 | ||||
| class TVariant : public TSortable | ||||
| { | ||||
|   TFieldtypes _type; | ||||
|   void* _ptr; | ||||
| 
 | ||||
| protected: | ||||
|   virtual TObject* dup() const { return new TVariant(*this); } | ||||
|   void copy(const TVariant& var); | ||||
| 
 | ||||
| public: | ||||
|   TFieldtypes type() const { return _type; } // Internal use only
 | ||||
|   bool is_string() const { return _type == _alfafld; } | ||||
|   bool is_empty() const; | ||||
|   bool is_null() const { return _type == _nullfld; } | ||||
|   bool is_zero() const; | ||||
|   void set_null(); | ||||
|    | ||||
|   void set(const char* str); | ||||
|   void set(const real& r); | ||||
|   void set(const long n); | ||||
|   void set(const TDate& d); | ||||
| 
 | ||||
|   TVariant& operator=(const TVariant& var) { copy(var); return *this; } | ||||
|   TVariant& operator=(const char* str) { set(str); return *this; } | ||||
|   TVariant& operator=(const real& r) { set(r); return *this; } | ||||
|   TVariant& operator=(const long n) { set(n); return *this; } | ||||
|   TVariant& operator=(const TDate& d) { set(d); return *this; } | ||||
| 
 | ||||
|   const TString& as_string() const; | ||||
|   bool as_string(TString& str) const; | ||||
|   real as_real() const; | ||||
|   long as_int() const; | ||||
|   TDate as_date() const; | ||||
|   bool as_bool() const; | ||||
|   COLOR as_color() const; | ||||
| 
 | ||||
|   void convert_to(TFieldtypes ft); | ||||
| 
 | ||||
|   virtual int compare(const TSortable& s) const; | ||||
|   TVariant& add(const TVariant& var); | ||||
|   TVariant& sub(const TVariant& var); | ||||
| 
 | ||||
|   TVariant() : _type(_nullfld), _ptr(NULL) { } | ||||
|   TVariant(const char* str) : _type(_alfafld), _ptr(new TString(str)) { } | ||||
|   TVariant(const real& num) : _type(_realfld), _ptr(new real(num)) { }; | ||||
|   TVariant(const TDate& d) : _type(_datefld), _ptr(new TDate(d)) { }; | ||||
|   TVariant(long num) : _type(_longfld), _ptr((void*)num) { }; | ||||
|   TVariant(bool ok) : _type(_longfld), _ptr((void*)ok) { }; | ||||
|   TVariant(const TVariant& var) : _type(_nullfld), _ptr(NULL) { copy(var); } | ||||
|   virtual ~TVariant() { set_null(); } | ||||
| }; | ||||
| 
 | ||||
| extern const TVariant NULL_VARIANT; | ||||
| 
 | ||||
| ///////////////////////////////////////////////////////////
 | ||||
| // TRecordset
 | ||||
| ///////////////////////////////////////////////////////////
 | ||||
|  | ||||
| @ -274,146 +274,6 @@ TReport_image_cache::TReport_image_cache() : TCache(7) | ||||
| { | ||||
| } | ||||
| 
 | ||||
| ///////////////////////////////////////////////////////////
 | ||||
| // Utility
 | ||||
| ///////////////////////////////////////////////////////////
 | ||||
| 
 | ||||
| bool advanced_set_draw_tools(TWindow& win, int border, COLOR fore, COLOR back) | ||||
| { | ||||
|   const bool has_pen = border > 0; | ||||
|   const bool has_brush = (back & 0xFFFFFF) != (COLOR_WHITE & 0xFFFFFF); | ||||
|   const bool visible = has_pen || has_brush; | ||||
|   if (visible) | ||||
|   { | ||||
|     if (has_pen) | ||||
|       win.set_pen(fore, border, PAT_SOLID); | ||||
|     else | ||||
|       win.hide_pen(); | ||||
|     if (has_brush) | ||||
|       win.set_brush(back, PAT_SOLID); | ||||
|     else | ||||
|       win.hide_brush(); | ||||
|   } | ||||
|   return visible; | ||||
| } | ||||
| 
 | ||||
| void advanced_draw_rect(TWindow& win, const RCT& r, int border, COLOR fore, COLOR back) | ||||
| { | ||||
|   if (advanced_set_draw_tools(win, border, fore, back)) | ||||
|     xvt_dwin_draw_rect(win.win(), (RCT*)&r); | ||||
| } | ||||
| 
 | ||||
| void advanced_draw_justified_text(TWindow& win, const char* text, short x, short y, short dx) | ||||
| { | ||||
|   TString txt(text); txt.rtrim(); | ||||
|   int spaces = 0; | ||||
|   for (int s = 0; txt[s]; s++) | ||||
|     if (isspace(txt[s])) spaces++; | ||||
|   const int tw = xvt_dwin_get_text_width(win.win(), txt, -1); | ||||
|   if (tw < dx && spaces > 0) | ||||
|   { | ||||
|     txt << ' '; // Aggiunge spazio finale
 | ||||
|     const double kspc = double(dx - tw) / spaces; | ||||
|     int start = 0; | ||||
|     double kx = x; | ||||
|     for (int i = 0; txt[i]; i++) | ||||
|     { | ||||
|       if (isspace(txt[i])) | ||||
|       { | ||||
|         const bool last_word = txt[i+1] == '\0'; | ||||
|         const TString& parola = txt.sub(start, i + (last_word ? 0 : 1)); | ||||
|         const int lw = xvt_dwin_get_text_width(win.win(), parola, -1); | ||||
|         if (last_word) // ultima parola
 | ||||
|           kx = x+dx-lw; | ||||
|         xvt_dwin_draw_text(win.win(), int(kx+0.5), y, parola, -1); | ||||
|         kx += lw + kspc; | ||||
|         start = i+1; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|   else | ||||
|     xvt_dwin_draw_text(win.win(), x, y, text, -1); | ||||
| } | ||||
| 
 | ||||
| void advanced_draw_text(TWindow& win, const char* text, const RCT& r,  | ||||
|                         char halign, char valign) | ||||
| { | ||||
|   const short dx = r.right-r.left; | ||||
|   const short dy = r.bottom-r.top; | ||||
|   short x = r.left; | ||||
|   short y = r.bottom; | ||||
|    | ||||
|   if (halign != 'L') | ||||
|   { | ||||
|     const int tw = xvt_dwin_get_text_width(win.win(), text, -1); | ||||
|     switch (halign) | ||||
|     { | ||||
|     case 'C': x += (dx - tw)/2; break; | ||||
|     case 'R': x = r.right-tw; break; | ||||
|     default : break; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   // Text Height
 | ||||
|   int leading, ascent, descent; | ||||
|   xvt_dwin_get_font_metrics(win.win(), &leading, &ascent, &descent); | ||||
|   switch (valign) | ||||
|   { | ||||
|   case 'C': y -= (dy - ascent)/2; break; | ||||
|   case 'T': y = r.top + leading + ascent; break; | ||||
|   default : y -= descent; break; | ||||
|   } | ||||
|    | ||||
|   if (halign == 'J') | ||||
|     advanced_draw_justified_text(win, text, x, y, dx); | ||||
|   else | ||||
|     xvt_dwin_draw_text(win.win(), x, y, text, -1); | ||||
| } | ||||
| 
 | ||||
| void advanced_draw_paragraph(TWindow& win, TString& para, const RCT& rct,  | ||||
|                              char halign, char valign) | ||||
| { | ||||
|   const bool acapo = para.find('\n') >= 0; | ||||
| 
 | ||||
|   int leading, ascent, descent; | ||||
|   xvt_dwin_get_font_metrics(win.win(), &leading, &ascent, &descent); | ||||
|   const int ky = leading + ascent + descent; | ||||
| 
 | ||||
|   const int rct_height = rct.bottom - rct.top; | ||||
|   int rows = (rct_height+ky/2) / ky; | ||||
| 
 | ||||
|   if (acapo || rows > 1) // Devo scrivere piu' righe?
 | ||||
|   { | ||||
|     const int kx = xvt_dwin_get_text_width(win.win(), "ABCDEFGH", 8) / 8;  | ||||
|     const unsigned columns = (rct.right - rct.left) / kx; | ||||
| 
 | ||||
|     TParagraph_string str(para, columns); | ||||
|     if (str.items() < rows) | ||||
|       rows = str.items(); | ||||
| 
 | ||||
|     int ybase = rct.top; | ||||
|     switch (valign) | ||||
|     { | ||||
|     case 'C': ybase += (rct_height - rows*ky) / 2; break; | ||||
|     case 'B': ybase += rct_height - rows*ky; break; | ||||
|     default : break; | ||||
|     } | ||||
|      | ||||
|     for (int row = 0; row < rows; row++) | ||||
|     { | ||||
|       RCT rctline = rct; | ||||
|       rctline.top = ybase + ky*row; | ||||
|       rctline.bottom = rctline.top + ky; | ||||
|       const char* line = str.get(); | ||||
|       if (halign == 'J' && (row == rows-1 || strlen(line) < columns/2)) | ||||
|         halign = 'L'; | ||||
|       advanced_draw_text(win, line, rctline, halign, 'T');  | ||||
|     } | ||||
|   } | ||||
|   else | ||||
|     advanced_draw_text(win, para, rct, halign, valign);  | ||||
| } | ||||
| 
 | ||||
| static void set_num_attr(TXmlItem& item, const char* attr, long num, short def = 0) | ||||
| { | ||||
|   if (num != def) | ||||
| @ -569,6 +429,14 @@ TPoint TReport_section::compute_size() const | ||||
|     return TPoint(0,0); | ||||
| 
 | ||||
|   TPoint s = _size; | ||||
| 
 | ||||
|   // Lo sfondo occupa sempre tutta la pagina
 | ||||
|   if (type() == 'B' && level() == 0) | ||||
|   { | ||||
|     s.x = s.y = 19600; | ||||
|     return s; | ||||
|   } | ||||
| 
 | ||||
|   if (_size.x <= 0 || _size.y <= 0)  // Calcolo automatico necessario
 | ||||
|   { | ||||
|     for (int i = 0; i < items(); i++) | ||||
| @ -588,6 +456,7 @@ TPoint TReport_section::compute_size() const | ||||
|     if ((s.y % 100) != 0) // Arrotonda alla riga successiva
 | ||||
|       s.y = (s.y / 100 + 1) * 100; | ||||
|   } | ||||
| 
 | ||||
|   return s; | ||||
| } | ||||
| 
 | ||||
| @ -622,18 +491,45 @@ bool TReport_section::execute_prescript() | ||||
|       report().set_curr_field(NULL); | ||||
|     ok = _prescript.execute(report()); | ||||
|   } | ||||
|   for (int i = 0; i < items(); i++) | ||||
|   for (int i = 0; ok && i < items(); i++) | ||||
|   { | ||||
|     TReport_field& f = field(i); | ||||
|     f.execute_prescript(); | ||||
|     ok = f.execute_prescript(); | ||||
|   } | ||||
|   return ok; | ||||
| } | ||||
| 
 | ||||
| bool TReport_section::print_tools(TBook& book) const | ||||
| { | ||||
|   const bool has_pen = border() > 0; | ||||
|   const bool has_brush = pattern() >= PAT_SOLID && back_color() != COLOR_WHITE; | ||||
|   const bool visible = has_pen || has_brush; | ||||
|   if (visible) | ||||
|   { | ||||
|     book.set_pen(fore_color(), border()-1); | ||||
|     book.set_brush(back_color(), pattern()); | ||||
|   } | ||||
|   return visible; | ||||
| } | ||||
| 
 | ||||
| void TReport_section::print(TBook& book) const | ||||
| { | ||||
|   if (shown() && active()) | ||||
|   { | ||||
|     if (print_tools(book)) | ||||
|     { | ||||
|       TRectangle rct; compute_rect(rct); | ||||
|       if (_size.x <= 0)  | ||||
|         rct.set_width(book.logical_page_width()); | ||||
|       if (type() == 'B' && level() <= 0) | ||||
|         rct.set_height(book.logical_page_height()); | ||||
| 
 | ||||
|       if (radius() > 0) | ||||
|         book.draw_round_rectangle(rct, radius()); | ||||
|       else | ||||
|         book.draw_rectangle(rct); | ||||
|     } | ||||
| 
 | ||||
|     for (int i = 0; i < items(); i++) | ||||
|     { | ||||
|       const TReport_field& f = field(i); | ||||
| @ -671,6 +567,18 @@ void TReport_section::save(TXmlItem& root) const | ||||
|   set_num_attr(item, "y", pos().y); | ||||
|   set_num_attr(item, "width", width()); | ||||
|   set_num_attr(item, "height", height()); | ||||
| 
 | ||||
|   set_col_attr(item, "bg_color", back_color(), COLOR_WHITE); | ||||
|   set_col_attr(item, "fg_color", fore_color(), COLOR_BLACK); | ||||
|   if (border() > 0) | ||||
|   { | ||||
|     item.SetAttr("border", border()); | ||||
|     if (radius() > 0) | ||||
|       item.SetAttr("radius", radius()); | ||||
|   } | ||||
|   if (pattern() != PAT_HOLLOW) | ||||
|     item.SetAttr("pattern", pattern()); | ||||
| 
 | ||||
|   item.SetAttr("hidden", _hidden); | ||||
|   item.SetAttr("deactivated", _deactivated); | ||||
|   item.SetAttr("hidden_if_needed", hidden_if_needed()); | ||||
| @ -699,6 +607,13 @@ void TReport_section::load(const TXmlItem& sec) | ||||
|   _pos.y = get_num_attr(sec, "y"); | ||||
|   set_width(get_num_attr(sec, "width")); | ||||
|   set_height(get_num_attr(sec, "height")); | ||||
| 
 | ||||
|   set_border(sec.GetIntAttr("border")); | ||||
|   set_pattern((PAT_STYLE)sec.GetIntAttr("pattern", PAT_HOLLOW)); | ||||
|   set_radius(sec.GetIntAttr("radius")); | ||||
|   set_back_color(get_col_attr(sec, "bg_color", COLOR_WHITE)); | ||||
|   set_fore_color(get_col_attr(sec, "fg_color", COLOR_BLACK)); | ||||
| 
 | ||||
|   force_page_break(sec.GetBoolAttr("pagebreak")); | ||||
|   keep_with_next(sec.GetBoolAttr("keep_with_next")); | ||||
|   hide_if_needed(sec.GetBoolAttr("hidden_if_needed")); | ||||
| @ -751,7 +666,9 @@ void TReport_section::load(const TXmlItem& sec) | ||||
| TReport_section::TReport_section(TReport& r, char t, int l)  | ||||
|                : _report(r), _type(t), _level(l), _pos(0,0), | ||||
|                  _size(0,0), _page_break(false), _hidden_if_needed(false), | ||||
|                  _repeat(false), _hidden(false), _deactivated(false), _font(NULL) | ||||
|                  _repeat(false), _hidden(false), _deactivated(false), _font(NULL), | ||||
|                  _bgcolor(COLOR_WHITE), _fgcolor(COLOR_BLACK), _pattern(PAT_HOLLOW),  | ||||
|                  _border(0), _radius(0) | ||||
| 
 | ||||
|                   | ||||
| 
 | ||||
| @ -949,10 +866,23 @@ TReport_script::~TReport_script() | ||||
| 
 | ||||
| struct TReport_array_item : public TObject | ||||
| { | ||||
| protected: | ||||
|   virtual TObject* dup() const; | ||||
| 
 | ||||
| public: | ||||
|   TString _code, _value; | ||||
|   TReport_script _script; | ||||
| }; | ||||
| 
 | ||||
| TObject* TReport_array_item::dup() const | ||||
| { | ||||
|   TReport_array_item* i = new TReport_array_item; | ||||
|   i->_code = _code; | ||||
|   i->_value = _value; | ||||
|   i->_script = _script; | ||||
|   return i; | ||||
| } | ||||
| 
 | ||||
| ///////////////////////////////////////////////////////////
 | ||||
| // TReport_field
 | ||||
| ///////////////////////////////////////////////////////////
 | ||||
| @ -1067,18 +997,19 @@ void TReport_field::copy(const TReport_field& rf) | ||||
|   _rct = rf._rct; | ||||
|   set_dynamic_height(rf.dynamic_height()); | ||||
|   _fgcolor = rf._fgcolor; _bgcolor = rf._bgcolor; | ||||
|   _border = rf._border; | ||||
|   _border = rf._border; _radius = rf._radius; _pattern = rf._pattern; | ||||
|   _halign = rf._halign; _valign = rf._valign; | ||||
|   _picture = rf._picture; _field = rf._field; | ||||
|   _hidden = rf.hidden(); | ||||
|   _deactivated = rf.deactivated(); | ||||
|   _hide_zeroes = rf._hide_zeroes; | ||||
|   _selected = false; | ||||
|   _field = rf._field; _alt_field = rf._alt_field; | ||||
|   _prescript = rf._prescript; | ||||
|   _postscript = rf._postscript; | ||||
|   _list = rf._list; | ||||
|    | ||||
|   set_font(rf.font()); | ||||
|   _selected = false; | ||||
| } | ||||
| 
 | ||||
| const char* TReport_field::type_name() const | ||||
| @ -1226,9 +1157,14 @@ TReport_array_item* TReport_field::get_array_item() const | ||||
|   return NULL; | ||||
| } | ||||
| 
 | ||||
| bool TReport_field::zeroes_hidden() const  | ||||
| {  | ||||
|   return _hide_zeroes && strchr("DNVP", _type) != NULL;  | ||||
| } | ||||
| 
 | ||||
| const TString& TReport_field::formatted_text() const | ||||
| { | ||||
|   if (_hide_zeroes && _var.is_zero()) | ||||
|   if (zeroes_hidden() && _var.is_zero()) | ||||
|     return EMPTY_STRING; | ||||
| 
 | ||||
|   switch (type()) | ||||
| @ -1306,12 +1242,12 @@ const TString& TReport_field::formatted_text() const | ||||
| bool TReport_field::print_tools(TBook& book) const | ||||
| { | ||||
|   const bool has_pen = border() > 0; | ||||
|   const bool has_brush = (back_color() & 0xFFFFFF) != (COLOR_WHITE & 0xFFFFFF); | ||||
|   const bool has_brush = pattern() >= PAT_SOLID; | ||||
|   const bool visible = has_pen || has_brush; | ||||
|   if (visible) | ||||
|   { | ||||
|     book.set_pen(fore_color(), border()-1); | ||||
|     book.set_brush(back_color(), has_brush ? PAT_SOLID : PAT_HOLLOW); | ||||
|     book.set_brush(back_color(), pattern()); | ||||
|   } | ||||
|   return visible; | ||||
| } | ||||
| @ -1319,7 +1255,12 @@ bool TReport_field::print_tools(TBook& book) const | ||||
| void TReport_field::print_rect(TBook& book) const | ||||
| { | ||||
|   if (print_tools(book)) | ||||
|     book.draw_rectangle(get_draw_rect()); | ||||
|   { | ||||
|     if (radius() > 0) | ||||
|       book.draw_round_rectangle(get_draw_rect(), radius()); | ||||
|     else | ||||
|       book.draw_rectangle(get_draw_rect()); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| void TReport_field::print(TBook& book) const | ||||
| @ -1428,7 +1369,7 @@ void TReport_field::save(TXmlItem& root) const | ||||
|   fld.SetAttr("dynamic_height", dynamic_height()); | ||||
|   fld.SetAttr("hidden", _hidden); | ||||
|   fld.SetAttr("deactivated", _deactivated); | ||||
|   fld.SetAttr("hide_zero", _hide_zeroes); | ||||
|   fld.SetAttr("hide_zero", zeroes_hidden()); | ||||
|   set_col_attr(fld, "bg_color", back_color(), COLOR_WHITE); | ||||
|   set_col_attr(fld, "fg_color", fore_color(), COLOR_BLACK); | ||||
|   if (has_font()) | ||||
| @ -1449,7 +1390,14 @@ void TReport_field::save(TXmlItem& root) const | ||||
|   case 'C': fld.SetAttr("valign", "center"); break; | ||||
|   default : break; | ||||
|   }; | ||||
|   fld.SetAttr("border", border()); | ||||
|   if (border() > 0) | ||||
|   { | ||||
|     fld.SetAttr("border", border()); | ||||
|     if (radius() > 0) | ||||
|       fld.SetAttr("radius", radius()); | ||||
|   } | ||||
|   if (pattern() != PAT_SOLID) | ||||
|     fld.SetAttr("pattern", pattern()); | ||||
|   fld.SetAttr("text", picture()); | ||||
|   fld.SetAttr("codval", codval()); | ||||
|   fld.SetAttr("link", link()); | ||||
| @ -1491,6 +1439,8 @@ bool TReport_field::load(const TXmlItem& fld) | ||||
|   activate(!fld.GetBoolAttr("deactivated")); | ||||
|   hide_zeroes(fld.GetBoolAttr("hide_zero")); | ||||
|   set_border(fld.GetIntAttr("border")); | ||||
|   set_pattern((PAT_STYLE)fld.GetIntAttr("pattern", PAT_SOLID)); | ||||
|   set_radius(fld.GetIntAttr("radius")); | ||||
|   set_back_color(get_col_attr(fld, "bg_color", COLOR_WHITE)); | ||||
|   set_fore_color(get_col_attr(fld, "fg_color", COLOR_BLACK)); | ||||
|   set_horizontal_alignment(get_chr_attr(fld, "align", 'L')); | ||||
| @ -1578,7 +1528,7 @@ int TReport_field::compare(const TSortable& s) const | ||||
| 
 | ||||
| TReport_field::TReport_field(TReport_section* sec)  | ||||
|              : _section(sec), _id(0), _type('T'), _rct(0,0,1000,100), | ||||
|                _fgcolor(COLOR_BLACK), _bgcolor(COLOR_WHITE), | ||||
|                _fgcolor(COLOR_BLACK), _bgcolor(COLOR_WHITE), _radius(0), _pattern(PAT_SOLID), | ||||
|                _border(0), _halign('L'), _valign('T'),_dynamic_height(false), _font(NULL), | ||||
|                _hidden(false), _deactivated(false), _hide_zeroes(false), _selected(false)              | ||||
| { } | ||||
| @ -1721,7 +1671,7 @@ int TReport::parse_field(const char* code, char& type, int& level, int& id) cons | ||||
|   return strchr(code, '@') != NULL ? 4 : 3; | ||||
| } | ||||
| 
 | ||||
| TReport_field* TReport::field(const TString& code) | ||||
| TReport_field* TReport::field(const char* code) | ||||
| { | ||||
|   char type = ' '; | ||||
|   int level = -1, id = 0; | ||||
| @ -1984,26 +1934,25 @@ bool TReport::get_report_field(const TString& name, TVariant& var) const | ||||
|     else | ||||
|       str++; | ||||
|   } | ||||
|   const TFixed_string n(str);  | ||||
|    | ||||
|   TReport_field* fld = ((TReport*)this)->field(str); | ||||
|   if (fld != NULL) | ||||
|   { | ||||
|     var = fld->get(); | ||||
|     return true; | ||||
|   } | ||||
| 
 | ||||
|   if (n == "PAGE") | ||||
|   if (xvt_str_compare_ignoring_case(str, "PAGE") == 0) | ||||
|   { | ||||
|     var = _rep_page; | ||||
|     return true; | ||||
|   } else | ||||
|   if (n == "BOOK.PAGE") | ||||
|   if (xvt_str_compare_ignoring_case(str, "BOOKPAGE") == 0) | ||||
|   { | ||||
|     var = _book_page; | ||||
|     return true; | ||||
|   } | ||||
| 
 | ||||
|   TReport_field* fld = ((TReport*)this)->field(n); | ||||
|   if (fld != NULL) | ||||
|   { | ||||
|     var = fld->get(); | ||||
|     return true; | ||||
|   } | ||||
| 
 | ||||
|   return found; | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -149,6 +149,9 @@ class TReport_section : public TArray | ||||
|   TString _condition, _groupby; | ||||
|   bool _page_break, _hidden_if_needed, _keep_with_next, _repeat; | ||||
|   bool _hidden, _deactivated; | ||||
|   COLOR _fgcolor, _bgcolor; | ||||
|   int _border, _radius; | ||||
|   PAT_STYLE _pattern; | ||||
|   TReport_script _prescript, _postscript; | ||||
| 
 | ||||
|   TReport_font* _font; | ||||
| @ -156,6 +159,7 @@ class TReport_section : public TArray | ||||
| protected: | ||||
|   virtual const char* class_name() const { return "ReportSection"; } | ||||
|   TReport_section* father_section() const; | ||||
|   bool print_tools(TBook& book) const; | ||||
| 
 | ||||
| public: | ||||
|   virtual int add(TObject* obj); | ||||
| @ -178,6 +182,18 @@ public: | ||||
|   bool compute_rect(TRectangle& rct) const; | ||||
|   const TPoint& pos() const { return _pos; } | ||||
|   void set_pos(const TPoint& p) { _pos = p; } | ||||
| 
 | ||||
|   void set_fore_color(COLOR c) { _fgcolor = c; } | ||||
|   COLOR fore_color() const { return _fgcolor; } | ||||
|   void set_back_color(COLOR c) { _bgcolor = c; } | ||||
|   COLOR back_color() const { return _bgcolor; } | ||||
|   void set_border(int b) { _border = b; } | ||||
|   short border() const { return _border; } | ||||
|   void set_pattern(PAT_STYLE p) { _pattern = p; } | ||||
|   PAT_STYLE pattern() const { return _pattern; } | ||||
|   void set_radius(int r) { _radius = r; } | ||||
|   short radius() const { return _radius; } | ||||
|    | ||||
|   bool page_break() const { return _page_break; } | ||||
|   void force_page_break(bool pb) { _page_break = pb; } | ||||
|   void set_repeat_on_page(bool r) { _repeat = r; } | ||||
| @ -233,7 +249,8 @@ class TReport_field : public TSortable | ||||
|   char _type;   // Text, String, Numeric, Price, Valuta, Date, Line, Rectangle, Image
 | ||||
|   TRectangle _rct; // In centesimi
 | ||||
|   COLOR _fgcolor, _bgcolor; | ||||
|   short _border; | ||||
|   int _border, _radius; | ||||
|   PAT_STYLE _pattern; | ||||
|   char _halign, _valign; | ||||
|   bool _dynamic_height; | ||||
|   TBit_array _groups; | ||||
| @ -314,7 +331,7 @@ public: | ||||
|   bool active() const { return !deactivated(); } | ||||
|   void activate(bool on) { _deactivated = !on; } | ||||
|   void deactivate() { activate(false); } | ||||
|   bool zeroes_hidden() const { return _hide_zeroes; } | ||||
|   bool zeroes_hidden() const; | ||||
|   void hide_zeroes(bool hz) { _hide_zeroes = hz; } | ||||
| 
 | ||||
|   bool draw_hidden() const { return _draw_hidden; } | ||||
| @ -339,8 +356,14 @@ public: | ||||
|   void set_back_color(COLOR c) { _bgcolor = c; } | ||||
|   COLOR back_color() const { return _bgcolor; } | ||||
|   COLOR link_color() const; | ||||
|   void set_border(short b) { _border = b; } | ||||
|    | ||||
|   void set_border(int b) { _border = b; } | ||||
|   short border() const { return _border; } | ||||
|   void set_pattern(PAT_STYLE p) { _pattern = p; } | ||||
|   PAT_STYLE pattern() const { return _pattern; } | ||||
|   void set_radius(int r) { _radius = r; } | ||||
|   short radius() const { return _radius; } | ||||
| 
 | ||||
|   void set_horizontal_alignment(char a) { _halign = a; } | ||||
|   char horizontal_alignment() const { return _halign; } | ||||
|   void set_vertical_alignment(char a) { _valign = a; } | ||||
| @ -355,10 +378,6 @@ public: | ||||
|   bool selected() const { return _selected; } | ||||
|   void offset(const TPoint& pt); | ||||
| 
 | ||||
| //  virtual void draw_rect(TWindow& win) const;
 | ||||
| //  virtual void draw_text(TWindow& win, const char* text, TReport_draw_mode mode) const;
 | ||||
| //  virtual void draw(TWindow& win, TReport_draw_mode mode) const;
 | ||||
| 
 | ||||
|   virtual bool print_tools(TBook& book) const; | ||||
|   virtual void print_rect(TBook& book) const; | ||||
|   virtual void print(TBook& book) const; | ||||
| @ -484,18 +503,11 @@ public: | ||||
|   TReport_field* curr_field() const { return _curr_field; } | ||||
| 
 | ||||
|   int parse_field(const char* code, char& type, int& level, int& id) const; | ||||
|   TReport_field* field(const TString& code); | ||||
|   TReport_field* field(const char* code); | ||||
|   | ||||
|   void destroy(); | ||||
|   TReport(); | ||||
|   virtual ~TReport(); | ||||
| }; | ||||
| 
 | ||||
| bool advanced_set_draw_tools(TWindow& win, int border, COLOR fore, COLOR back); | ||||
| void advanced_draw_rect(TWindow& win, const RCT& r, int border, COLOR fore, COLOR back); | ||||
| void advanced_draw_text(TWindow& win, const char* text, const RCT& r,  | ||||
|                         char halign, char valign); | ||||
| void advanced_draw_paragraph(TWindow& win, TString& text, const RCT& r,  | ||||
|                              char halign, char valign); | ||||
| 
 | ||||
| #endif | ||||
|  | ||||
| @ -11,6 +11,151 @@ | ||||
| 
 | ||||
| static bool _print_aborted = false; | ||||
| 
 | ||||
| ///////////////////////////////////////////////////////////
 | ||||
| // Utility
 | ||||
| ///////////////////////////////////////////////////////////
 | ||||
| 
 | ||||
| bool advanced_set_draw_tools(TWindow& win, PAT_STYLE pat, int border, COLOR fore, COLOR back) | ||||
| { | ||||
|   const bool has_pen = border > 0; | ||||
|   const bool has_brush = pat > PAT_HOLLOW && back != COLOR_WHITE; | ||||
|   const bool visible = has_pen || has_brush; | ||||
|   if (visible) | ||||
|   { | ||||
|     if (has_pen) | ||||
|       win.set_pen(fore, border, PAT_SOLID); | ||||
|     else | ||||
|       win.hide_pen(); | ||||
|     if (has_brush) | ||||
|       win.set_brush(back, pat); | ||||
|     else | ||||
|       win.hide_brush(); | ||||
|   } | ||||
|   return visible; | ||||
| } | ||||
| 
 | ||||
| void advanced_draw_rect(TWindow& win, const RCT& r, PAT_STYLE pat, int border, COLOR fore, COLOR back, int radius) | ||||
| { | ||||
|   if (advanced_set_draw_tools(win, pat, border, fore, back)) | ||||
|   { | ||||
|     if (radius > 0) | ||||
|       xvt_dwin_draw_roundrect(win.win(), &r, radius, radius); | ||||
|     else | ||||
|       xvt_dwin_draw_rect(win.win(), (RCT*)&r); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| void advanced_draw_justified_text(TWindow& win, const char* text, short x, short y, short dx) | ||||
| { | ||||
|   TString txt(text); txt.rtrim(); | ||||
|   int spaces = 0; | ||||
|   for (int s = 0; txt[s]; s++) | ||||
|     if (isspace(txt[s])) spaces++; | ||||
|   const int tw = xvt_dwin_get_text_width(win.win(), txt, -1); | ||||
|   if (tw < dx && spaces > 0) | ||||
|   { | ||||
|     txt << ' '; // Aggiunge spazio finale
 | ||||
|     const double kspc = double(dx - tw) / spaces; | ||||
|     int start = 0; | ||||
|     double kx = x; | ||||
|     for (int i = 0; txt[i]; i++) | ||||
|     { | ||||
|       if (isspace(txt[i])) | ||||
|       { | ||||
|         const bool last_word = txt[i+1] == '\0'; | ||||
|         const TString& parola = txt.sub(start, i + (last_word ? 0 : 1)); | ||||
|         const int lw = xvt_dwin_get_text_width(win.win(), parola, -1); | ||||
|         if (last_word) // ultima parola
 | ||||
|           kx = x+dx-lw; | ||||
|         xvt_dwin_draw_text(win.win(), int(kx+0.5), y, parola, -1); | ||||
|         kx += lw + kspc; | ||||
|         start = i+1; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|   else | ||||
|     xvt_dwin_draw_text(win.win(), x, y, text, -1); | ||||
| } | ||||
| 
 | ||||
| void advanced_draw_text(TWindow& win, const char* text, const RCT& r,  | ||||
|                         char halign, char valign) | ||||
| { | ||||
|   const short dx = r.right-r.left; | ||||
|   const short dy = r.bottom-r.top; | ||||
|   short x = r.left; | ||||
|   short y = r.bottom; | ||||
|    | ||||
|   if (halign != 'L') | ||||
|   { | ||||
|     const int tw = xvt_dwin_get_text_width(win.win(), text, -1); | ||||
|     switch (halign) | ||||
|     { | ||||
|     case 'C': x += (dx - tw)/2; break; | ||||
|     case 'R': x = r.right-tw; break; | ||||
|     default : break; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   // Text Height
 | ||||
|   int leading, ascent, descent; | ||||
|   xvt_dwin_get_font_metrics(win.win(), &leading, &ascent, &descent); | ||||
|   switch (valign) | ||||
|   { | ||||
|   case 'C': y -= (dy - ascent)/2; break; | ||||
|   case 'T': y = r.top + leading + ascent; break; | ||||
|   default : y -= descent; break; | ||||
|   } | ||||
|    | ||||
|   if (halign == 'J') | ||||
|     advanced_draw_justified_text(win, text, x, y, dx); | ||||
|   else | ||||
|     xvt_dwin_draw_text(win.win(), x, y, text, -1); | ||||
| } | ||||
| 
 | ||||
| void advanced_draw_paragraph(TWindow& win, TString& para, const RCT& rct,  | ||||
|                              char halign, char valign) | ||||
| { | ||||
|   const bool acapo = para.find('\n') >= 0; | ||||
| 
 | ||||
|   int leading, ascent, descent; | ||||
|   xvt_dwin_get_font_metrics(win.win(), &leading, &ascent, &descent); | ||||
|   const int ky = leading + ascent + descent; | ||||
| 
 | ||||
|   const int rct_height = rct.bottom - rct.top; | ||||
|   int rows = (rct_height+ky/2) / ky; | ||||
| 
 | ||||
|   if (acapo || rows > 1) // Devo scrivere piu' righe?
 | ||||
|   { | ||||
|     const int kx = xvt_dwin_get_text_width(win.win(), "ABCDEFGH", 8) / 8;  | ||||
|     const unsigned columns = (rct.right - rct.left) / kx; | ||||
| 
 | ||||
|     TParagraph_string str(para, columns); | ||||
|     if (str.items() < rows) | ||||
|       rows = str.items(); | ||||
| 
 | ||||
|     int ybase = rct.top; | ||||
|     switch (valign) | ||||
|     { | ||||
|     case 'C': ybase += (rct_height - rows*ky) / 2; break; | ||||
|     case 'B': ybase += rct_height - rows*ky; break; | ||||
|     default : break; | ||||
|     } | ||||
|      | ||||
|     for (int row = 0; row < rows; row++) | ||||
|     { | ||||
|       RCT rctline = rct; | ||||
|       rctline.top = ybase + ky*row; | ||||
|       rctline.bottom = rctline.top + ky; | ||||
|       const char* line = str.get(); | ||||
|       if (halign == 'J' && (row == rows-1 || strlen(line) < columns/2)) | ||||
|         halign = 'L'; | ||||
|       advanced_draw_text(win, line, rctline, halign, 'T');  | ||||
|     } | ||||
|   } | ||||
|   else | ||||
|     advanced_draw_text(win, para, rct, halign, valign);  | ||||
| } | ||||
| 
 | ||||
| ///////////////////////////////////////////////////////////
 | ||||
| // TReport_link
 | ||||
| ///////////////////////////////////////////////////////////
 | ||||
| @ -146,7 +291,7 @@ void TPrint_preview_window::update() | ||||
|   if (pag.v < rct.bottom) rct.bottom = pag.v; | ||||
|   hide_pen(); | ||||
|   set_brush(COLOR_WHITE); | ||||
|   xvt_dwin_draw_rect(win(), &rct); | ||||
|   xvt_dwin_draw_rect(win(), &rct); // Disegna foglio bianco
 | ||||
| 
 | ||||
|   if (_grid) | ||||
|   { | ||||
| @ -243,9 +388,9 @@ void TPrint_preview_window::handler(WINDOW win, EVENT* ep) | ||||
|   { | ||||
|   case E_MOUSE_MOVE: | ||||
|     if (find_link(ep->v.mouse.where) != NULL) | ||||
|       xvt_win_set_cursor(win, CURSOR_CROSS); | ||||
|       xvt_win_set_cursor(win, 8004);          // Ditino
 | ||||
|     else | ||||
|       xvt_win_set_cursor(win, CURSOR_ARROW); | ||||
|       xvt_win_set_cursor(win, CURSOR_ARROW);  // Freccia
 | ||||
|     break; | ||||
|   case E_MOUSE_DOWN: | ||||
|     if (ep->v.mouse.button == 0) | ||||
| @ -279,8 +424,8 @@ void TPrint_preview_window::handler(WINDOW win, EVENT* ep) | ||||
|         processed = _page < _book->pages();  | ||||
|         if (processed) _page = _book->pages();  | ||||
|         break; | ||||
|       case POPUP_ZOOMIN : if (_zoom < 300) { _zoom += 25; update_scroll_range(); } break; | ||||
|       case POPUP_ZOOMOUT: if (_zoom >  50) { _zoom -= 25; update_scroll_range(); } break; | ||||
|       case POPUP_ZOOMIN : if (_zoom < 300) { _zoom += 10; update_scroll_range(); } break; | ||||
|       case POPUP_ZOOMOUT: if (_zoom >  50) { _zoom -= 10; update_scroll_range(); } break; | ||||
|       case POPUP_GRID   : _grid = !_grid; break; | ||||
|       default:processed = false; break; | ||||
|       } | ||||
| @ -680,6 +825,12 @@ void TBook::draw_rectangle(const TRectangle& r) | ||||
|   *_out << "<rectangle/>" << endl; | ||||
| } | ||||
| 
 | ||||
| void TBook::draw_round_rectangle(const TRectangle& r, int radius) | ||||
| { | ||||
|   define_frame(r); | ||||
|   *_out << "<rounded_rectangle radius=" << radius << " />" << endl; | ||||
| } | ||||
| 
 | ||||
| void TBook::draw_ellipse(const TRectangle& r) | ||||
| { | ||||
|   define_frame(r); | ||||
| @ -808,18 +959,19 @@ bool TBook::print_page(TWindow& win, size_t page) | ||||
| 
 | ||||
|           if (!stringona.blank() && rct.right > rct.left) // Possono esserci campi chiave nascosti
 | ||||
|           { | ||||
|             WINDOW w = win.win(); | ||||
|             DRAW_CTOOLS dct; | ||||
|             xvt_dwin_get_draw_ctools(win.win(), &dct); | ||||
|             xvt_dwin_get_draw_ctools(w, &dct); | ||||
| 
 | ||||
|             XVT_FNTID oldfont = xvt_dwin_get_font(win.win()); | ||||
|             XVT_FNTID oldfont = xvt_dwin_get_font(w); | ||||
|             XVT_FNTID newfont = xvt_font_create(); | ||||
|             xvt_font_copy(newfont, oldfont, XVT_FA_ALL); | ||||
|             xvt_font_set_style(newfont, xvt_font_get_style(oldfont) | XVT_FS_UNDERLINE); | ||||
|             xvt_dwin_set_font(win.win(), newfont); | ||||
|             xvt_dwin_set_font(w, newfont); | ||||
|             win.set_color(COLOR_BLUE, dct.back_color); | ||||
|             advanced_draw_text(win, stringona, rct, _horizontal_alignment, _vertical_alignment); | ||||
|             win.set_color(dct.fore_color, dct.back_color); | ||||
|             xvt_dwin_set_font(win.win(), oldfont);          | ||||
|             xvt_dwin_set_font(w, oldfont);          | ||||
|           } | ||||
|         } | ||||
|       } | ||||
| @ -830,7 +982,7 @@ bool TBook::print_page(TWindow& win, size_t page) | ||||
|       COLOR col = COLOR_BLACK;  | ||||
|       PAT_STYLE pat = PAT_SOLID; | ||||
|       sscanf(str, "<brush color=%u pattern=%u />", &col, &pat); | ||||
|       if (pat == PAT_HOLLOW) | ||||
|       if (pat <= PAT_HOLLOW || col == COLOR_WHITE) | ||||
|         win.hide_brush(); | ||||
|       else | ||||
|         win.set_brush(col, pat); | ||||
| @ -897,6 +1049,14 @@ bool TBook::print_page(TWindow& win, size_t page) | ||||
|       xvt_dwin_draw_rect(win.win(), &rct); | ||||
|       continue; | ||||
|     } | ||||
|     if (str.starts_with("<rounded_rectangle")) | ||||
|     { | ||||
|       const int radius = get_xml_int(str, "radius", 0); | ||||
|       const TRectangle rr(0,0,radius,radius); | ||||
|       RCT re; win.log2dev(rr, re); | ||||
|       xvt_dwin_draw_roundrect(win.win(), &rct, re.right-re.left, re.bottom-re.top); | ||||
|       continue; | ||||
|     } | ||||
|     if (str == "<text>") | ||||
|     { | ||||
|       TString stringona; | ||||
| @ -1323,7 +1483,12 @@ long TReport_book::print_section(TReport_section& rs) | ||||
|       return 0; | ||||
|   } | ||||
| 
 | ||||
|   rs.execute_prescript(); | ||||
|   if (!rs.execute_prescript()) | ||||
|   { | ||||
|     _print_aborted = true; | ||||
|     return 0; | ||||
|   } | ||||
| 
 | ||||
|   const long height = rs.compute_size().y; // Compute size after the initilization script!
 | ||||
| 
 | ||||
|   if (height > 0) // Has some visible fields
 | ||||
| @ -1350,7 +1515,8 @@ long TReport_book::print_section(TReport_section& rs) | ||||
|       _page_break_allowed = true; | ||||
|   } | ||||
| 
 | ||||
|   rs.execute_postscript(); | ||||
|   if (!rs.execute_postscript()) | ||||
|     _print_aborted = true; | ||||
| 
 | ||||
|   return height; | ||||
| } | ||||
| @ -1588,11 +1754,3 @@ TReport_book::TReport_book(const char* name) | ||||
| { | ||||
| } | ||||
| 
 | ||||
| ///////////////////////////////////////////////////////////
 | ||||
| // Remote control interface
 | ||||
| ///////////////////////////////////////////////////////////
 | ||||
| 
 | ||||
| void abort_printing() | ||||
| { _print_aborted = true; } | ||||
| 
 | ||||
| 
 | ||||
|  | ||||
| @ -41,6 +41,7 @@ public: | ||||
|   void set_text_color(COLOR fore, COLOR back = COLOR_WHITE, bool opaque = false); | ||||
|   void set_text_align(char halign ='L', char valign = 'T'); | ||||
|   void draw_rectangle(const TRectangle& rect); | ||||
|   void draw_round_rectangle(const TRectangle& rect, int radius); | ||||
|   void draw_ellipse(const TRectangle& rect); | ||||
|   void draw_line(const TRectangle& rect); | ||||
|   void draw_image(const TRectangle& rect, const char* filename); | ||||
| @ -53,6 +54,8 @@ public: | ||||
|   size_t pages() const { return _pages; } | ||||
|   virtual int lpi() const { return 6; } | ||||
|   virtual int cpi() const { return 10; } | ||||
|   virtual int logical_page_width() const { return page_size().x * cpi() / page_res().x * 100; } | ||||
|   virtual int logical_page_height() const { return page_size().y * lpi() / page_res().y * 100; } | ||||
|    | ||||
|   virtual bool print_page(TWindow& win, size_t page); | ||||
|   virtual bool on_link(const TReport_link&) { return false; } | ||||
| @ -94,11 +97,18 @@ public: | ||||
|    | ||||
|   virtual int lpi() const; | ||||
|   virtual int cpi() const; | ||||
|   virtual int logical_page_width() const { return _logical_page_width; } | ||||
|   virtual int logical_page_height() const { return _logical_page_height; } | ||||
|   virtual bool print(size_t pagefrom = 0, size_t pageto = 0, size_t copies = 0); | ||||
| 
 | ||||
|   TReport_book(const char* name = NULL); | ||||
| }; | ||||
| 
 | ||||
| void abort_printing(); | ||||
| bool advanced_set_draw_tools(TWindow& win, PAT_STYLE pat, int border, COLOR fore, COLOR back); | ||||
| void advanced_draw_rect(TWindow& win, const RCT& r, PAT_STYLE pat, int border, COLOR fore, COLOR back, int radius); | ||||
| void advanced_draw_text(TWindow& win, const char* text, const RCT& r,  | ||||
|                         char halign, char valign); | ||||
| void advanced_draw_paragraph(TWindow& win, TString& text, const RCT& r,  | ||||
|                              char halign, char valign); | ||||
| 
 | ||||
| #endif | ||||
|  | ||||
							
								
								
									
										323
									
								
								include/variant.cpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										323
									
								
								include/variant.cpp
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,323 @@ | ||||
| #include <xvt.h> | ||||
| #include <variant.h> | ||||
| 
 | ||||
| ///////////////////////////////////////////////////////////
 | ||||
| // TVariant
 | ||||
| ///////////////////////////////////////////////////////////
 | ||||
| 
 | ||||
| const TVariant NULL_VARIANT; | ||||
| 
 | ||||
| void TVariant::set_null() | ||||
| { | ||||
|   if (_ptr != NULL) | ||||
|   { | ||||
|     if (_type != _nullfld && _type != _longfld) | ||||
|       delete (char *) _ptr; | ||||
|     _ptr = NULL; | ||||
|   } | ||||
|   _type = _nullfld; | ||||
| } | ||||
| 
 | ||||
| void TVariant::set(const char* str) | ||||
| { | ||||
|   if (str != NULL) | ||||
|   { | ||||
|     if (_type == _alfafld) | ||||
|       *((TString*)_ptr) = str; | ||||
|     else | ||||
|     { | ||||
|       set_null(); | ||||
|       _type = _alfafld; | ||||
|       _ptr = new TString(str); | ||||
|     } | ||||
|   } | ||||
|   else | ||||
|     set_null(); | ||||
| } | ||||
| 
 | ||||
| void TVariant::set(const real& r) | ||||
| { | ||||
|   if (_type == _realfld) | ||||
|     *((real*)_ptr) = r; | ||||
|   else | ||||
|   { | ||||
|     set_null(); | ||||
|     _type = _realfld; | ||||
|     _ptr = new real(r); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| void TVariant::set(const TDate& d) | ||||
| { | ||||
|   if (_type == _datefld) | ||||
|     *((TDate*)_ptr) = d; | ||||
|   else | ||||
|   { | ||||
|     set_null(); | ||||
|     _type = _datefld; | ||||
|     _ptr = new TDate(d); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| void TVariant::set(const long n) | ||||
| { | ||||
|   if (_type != _longfld) | ||||
|     set_null(); | ||||
|   _type = _longfld; | ||||
|   _ptr = (void*)n; | ||||
| } | ||||
| 
 | ||||
| bool TVariant::is_zero() const | ||||
| { | ||||
|   switch (_type) | ||||
|   { | ||||
|   case _datefld: return !as_date().ok(); | ||||
|   case _longfld: return _ptr == NULL; | ||||
|   case _realfld: return as_real().is_zero(); | ||||
|   case _alfafld: return real::is_null(as_string()); | ||||
|   default: break; | ||||
|   } | ||||
|   return true; | ||||
| } | ||||
| 
 | ||||
| bool TVariant::is_empty() const | ||||
| { | ||||
|  if (_type == _alfafld) | ||||
|    return as_string().empty(); | ||||
|  return is_zero(); | ||||
| } | ||||
| 
 | ||||
| TDate TVariant::as_date() const | ||||
| { | ||||
|   if (_type == _datefld) | ||||
|     return *(TDate*)_ptr; | ||||
|   if (_type == _intfld || _type == _realfld) | ||||
|     return TDate(as_int()); | ||||
|   return TDate(as_string()); | ||||
| } | ||||
| 
 | ||||
| long TVariant::as_int() const | ||||
| { | ||||
|   long n = 0; | ||||
|   switch(_type) | ||||
|   { | ||||
|   case _datefld: n = as_date().date2ansi(); break; | ||||
|   case _longfld: n = (long)_ptr; break; | ||||
|   case _realfld: n = as_real().integer(); break; | ||||
|   case _alfafld: n = atoi(as_string()); break; | ||||
|   default : break; | ||||
|   } | ||||
|   return n; | ||||
| } | ||||
| 
 | ||||
| bool TVariant::as_bool() const | ||||
| { | ||||
|   bool ok = false; | ||||
|   if (_type == _alfafld) | ||||
|     ok = strchr("1XY", as_string()[0]) != NULL; | ||||
|   else | ||||
|     ok = as_int() != 0; | ||||
|   return ok; | ||||
| } | ||||
| 
 | ||||
| COLOR TVariant::as_color() const | ||||
| { | ||||
|   const unsigned long rgb = as_int(); | ||||
|   unsigned char r = XVT_COLOR_GET_RED(rgb); | ||||
|   unsigned char g = XVT_COLOR_GET_GREEN(rgb); | ||||
|   unsigned char b = XVT_COLOR_GET_BLUE(rgb); | ||||
|   return MAKE_COLOR(r, g, b); | ||||
| } | ||||
| 
 | ||||
| real TVariant::as_real() const | ||||
| { | ||||
|   if (_type == _realfld) | ||||
|     return *(real*)_ptr; | ||||
|   switch(_type) | ||||
|   { | ||||
|   case _alfafld: return real(as_string()); break; | ||||
|   case _longfld: return real(as_int()); break; | ||||
|   default : break; | ||||
|   } | ||||
|   return ZERO; | ||||
| } | ||||
| 
 | ||||
| bool TVariant::as_string(TString& tmp) const | ||||
| { | ||||
|   tmp.cut(0); | ||||
|   switch(_type) | ||||
|   { | ||||
|   case _alfafld: tmp = *(TString*)_ptr; break; | ||||
|   case _datefld: tmp = as_date().string(); break; | ||||
|   case _longfld: tmp << as_int(); break; | ||||
|   case _realfld: tmp = as_real().string(); break; | ||||
|   default: break; | ||||
|   } | ||||
|   return !is_null(); | ||||
| } | ||||
| 
 | ||||
| const TString& TVariant::as_string() const | ||||
| { | ||||
|   if (_type == _alfafld) | ||||
|     return *(TString*)_ptr; | ||||
|   TString& tmp = get_tmp_string(); | ||||
|   as_string(tmp); | ||||
|   return tmp; | ||||
| } | ||||
| 
 | ||||
| void TVariant::convert_to(TFieldtypes ft) | ||||
| { | ||||
|   if (_type != ft) | ||||
|   { | ||||
|     switch (ft) | ||||
|     { | ||||
|     case _alfafld: set(as_string()); break; | ||||
|     case _datefld: set(as_date()); break; | ||||
|     case _longfld: set(as_int()); break; | ||||
|     case _realfld: set(as_real()); break; | ||||
|     default      : set_null(); break; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| void TVariant::copy(const TVariant& var) | ||||
| { | ||||
|   switch (var._type) | ||||
|   { | ||||
|   case _datefld: set(var.as_date()); break; | ||||
|   case _longfld: set(var.as_int()); break; | ||||
|   case _realfld: set(var.as_real()); break; | ||||
|   case _alfafld: set(var.as_string()); break; | ||||
|   default : set_null(); break; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| int TVariant::compare(const TSortable& s) const | ||||
| { | ||||
|   const TVariant& var = (const TVariant&)s; | ||||
|   int cmp = 0; | ||||
|   switch (_type) | ||||
|   { | ||||
|   case _datefld: cmp = as_date() - var.as_date(); break; | ||||
|   case _longfld: cmp = as_int() - var.as_int(); break; | ||||
|   case _realfld:  | ||||
|     { | ||||
|       const real n = as_real() - var.as_real(); | ||||
|       cmp = n.sign();  | ||||
|     } | ||||
|     break; | ||||
|   case _alfafld: cmp = as_string().compare(var.as_string()); break; | ||||
|   default : cmp = var.is_null() ? 0 : -1; | ||||
|   } | ||||
|   return cmp; | ||||
| } | ||||
| 
 | ||||
| TVariant& TVariant::add(const TVariant& var) | ||||
| { | ||||
|   switch (_type) | ||||
|   { | ||||
|   case _datefld: set(as_date() + var.as_int()); break; | ||||
|   case _longfld: set(as_int() + var.as_int()); break; | ||||
|   case _alfafld: *(TString*)_ptr << var.as_string(); break; | ||||
|   case _realfld: *(real*)_ptr += var.as_real(); break; | ||||
|   default: copy(var); break; | ||||
|   } | ||||
|   return *this; | ||||
| } | ||||
| 
 | ||||
| TVariant& TVariant::sub(const TVariant& var) | ||||
| { | ||||
|   switch (_type) | ||||
|   { | ||||
|   case _datefld: set(as_date() - var.as_int()); break; | ||||
|   case _longfld: | ||||
|     if (var.type() == _longfld) | ||||
|     { | ||||
|       set(as_int() - var.as_int()); | ||||
|       break; | ||||
|     } | ||||
|     // Fall down
 | ||||
|   default: | ||||
|     { | ||||
|       real n = as_real(); | ||||
|       n -= var.as_real(); | ||||
|       set(n); | ||||
|     } | ||||
|     break; | ||||
|   } | ||||
|   return *this; | ||||
| } | ||||
| 
 | ||||
| ///////////////////////////////////////////////////////////
 | ||||
| // TVariant_stack
 | ||||
| ///////////////////////////////////////////////////////////
 | ||||
| 
 | ||||
| TVariant& TVariant_stack::peek(int depth) | ||||
| { | ||||
|   const int sp = _sp-depth-1; | ||||
|   return sp >= 0 ? (TVariant&)_var[sp] : (TVariant &)NULL_VARIANT; | ||||
| } | ||||
| 
 | ||||
| bool TVariant_stack::drop() | ||||
| { | ||||
|   if (_sp > 0) | ||||
|   { | ||||
|     _sp--; | ||||
|     return true; | ||||
|   } | ||||
|   return false; | ||||
| } | ||||
| 
 | ||||
| TVariant& TVariant_stack::pop() | ||||
| { | ||||
|   TVariant& var = peek(0); | ||||
|   drop(); | ||||
|   return var; | ||||
| } | ||||
| 
 | ||||
| void TVariant_stack::roll(int depth) | ||||
| { | ||||
|   const int sp = _sp-depth-1; | ||||
|   if (sp >= 0) | ||||
|   { | ||||
|     TObject* var = _var.remove(sp, true); | ||||
|     _var.insert(var, _sp-1); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| void TVariant_stack::push(const TVariant& var) | ||||
| { | ||||
|   if (_var.objptr(_sp) == NULL) | ||||
|     _var.add(var, _sp); | ||||
|   else | ||||
|     (TVariant&)_var[_sp] = var; | ||||
|   _sp++; | ||||
| } | ||||
| 
 | ||||
| void TVariant_stack::push(long n) | ||||
| { | ||||
|   const TVariant var(n); | ||||
|   push(var); | ||||
| } | ||||
| 
 | ||||
| void TVariant_stack::push(const real& n) | ||||
| { | ||||
|   const TVariant var(n); | ||||
|   push(var); | ||||
| } | ||||
| 
 | ||||
| void TVariant_stack::push(const char* str) | ||||
| { | ||||
|   const TVariant var(str); | ||||
|   push(var); | ||||
| } | ||||
| 
 | ||||
| void TVariant_stack::reset() | ||||
| { | ||||
|   _sp = 0; | ||||
| } | ||||
| 
 | ||||
| bool TVariant_stack::overflow() const | ||||
| { | ||||
|   return _sp > 2048; | ||||
| } | ||||
							
								
								
									
										98
									
								
								include/variant.h
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										98
									
								
								include/variant.h
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,98 @@ | ||||
| #ifndef __VARIANT_H | ||||
| #define __VARIANT_H | ||||
| 
 | ||||
| #ifndef __DATE_H | ||||
| #include <date.h> | ||||
| #endif | ||||
| 
 | ||||
| #ifndef __REAL_H | ||||
| #include <real.h> | ||||
| #endif | ||||
| 
 | ||||
| #ifndef __RECTYPES_H | ||||
| #include <rectypes.h> | ||||
| #endif | ||||
| 
 | ||||
| ///////////////////////////////////////////////////////////
 | ||||
| // TVariant
 | ||||
| ///////////////////////////////////////////////////////////
 | ||||
| 
 | ||||
| class TVariant : public TSortable | ||||
| { | ||||
|   TFieldtypes _type; | ||||
|   void* _ptr; | ||||
| 
 | ||||
| protected: | ||||
|   virtual TObject* dup() const { return new TVariant(*this); } | ||||
|   void copy(const TVariant& var); | ||||
| 
 | ||||
| public: | ||||
|   TFieldtypes type() const { return _type; } // Internal use only
 | ||||
|   bool is_string() const { return _type == _alfafld; } | ||||
|   bool is_empty() const; | ||||
|   bool is_null() const { return _type == _nullfld; } | ||||
|   bool is_zero() const; | ||||
|   void set_null(); | ||||
|    | ||||
|   void set(const char* str); | ||||
|   void set(const real& r); | ||||
|   void set(const long n); | ||||
|   void set(const TDate& d); | ||||
| 
 | ||||
|   TVariant& operator=(const TVariant& var) { copy(var); return *this; } | ||||
|   TVariant& operator=(const char* str) { set(str); return *this; } | ||||
|   TVariant& operator=(const real& r) { set(r); return *this; } | ||||
|   TVariant& operator=(const long n) { set(n); return *this; } | ||||
|   TVariant& operator=(const TDate& d) { set(d); return *this; } | ||||
| 
 | ||||
|   const TString& as_string() const; | ||||
|   bool as_string(TString& str) const; | ||||
|   real as_real() const; | ||||
|   long as_int() const; | ||||
|   TDate as_date() const; | ||||
|   bool as_bool() const; | ||||
|   unsigned long as_color() const; | ||||
| 
 | ||||
|   void convert_to(TFieldtypes ft); | ||||
| 
 | ||||
|   virtual int compare(const TSortable& s) const; | ||||
|   TVariant& add(const TVariant& var); | ||||
|   TVariant& sub(const TVariant& var); | ||||
| 
 | ||||
|   TVariant() : _type(_nullfld), _ptr(NULL) { } | ||||
|   TVariant(const char* str) : _type(_alfafld), _ptr(new TString(str)) { } | ||||
|   TVariant(const real& num) : _type(_realfld), _ptr(new real(num)) { }; | ||||
|   TVariant(const TDate& d) : _type(_datefld), _ptr(new TDate(d)) { }; | ||||
|   TVariant(long num) : _type(_longfld), _ptr((void*)num) { }; | ||||
|   TVariant(bool ok) : _type(_longfld), _ptr((void*)ok) { }; | ||||
|   TVariant(const TVariant& var) : _type(_nullfld), _ptr(NULL) { copy(var); } | ||||
|   virtual ~TVariant() { set_null(); } | ||||
| }; | ||||
| 
 | ||||
| extern const TVariant NULL_VARIANT; | ||||
| 
 | ||||
| class TVariant_stack : public TObject | ||||
| { | ||||
|   TArray _var; | ||||
|   int _sp; | ||||
| 
 | ||||
| public: | ||||
|   int items() const { return _sp; } | ||||
|   bool drop(); | ||||
|   TVariant& pop(); | ||||
|   TVariant& peek(int depth = 0); | ||||
|   void roll(int depth); | ||||
| 
 | ||||
|   void push(const TVariant& var); | ||||
|   void push(long n); | ||||
|   void push(const real& n); | ||||
|   void push(const char* str); | ||||
|   void reset(); | ||||
|   bool overflow() const; | ||||
| 
 | ||||
|   TVariant_stack() : _sp(0) { } | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| #endif | ||||
| 
 | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user