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:
guy 2004-06-15 14:55:33 +00:00
parent f72c70c29b
commit dcd927717e
15 changed files with 807 additions and 621 deletions

View File

@ -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)

View File

@ -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

View File

@ -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)
{
}

View File

@ -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() { }
};

View File

@ -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

View File

@ -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()

View File

@ -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();
};

View File

@ -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

View File

@ -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
///////////////////////////////////////////////////////////

View File

@ -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;
}

View File

@ -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

View File

@ -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; }

View File

@ -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
View 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
View 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