1258 lines
28 KiB
C++
1258 lines
28 KiB
C++
|
#include <applicat.h>
|
|||
|
#include <browfile.h>
|
|||
|
#include <extcdecl.h>
|
|||
|
#include <filetext.h>
|
|||
|
#include <msksheet.h>
|
|||
|
#include <prefix.h>
|
|||
|
#include <relation.h>
|
|||
|
#include <sheet.h>
|
|||
|
#include <utility.h>
|
|||
|
#include <viswin.h>
|
|||
|
|
|||
|
#include "ba1800.h"
|
|||
|
|
|||
|
///////////////////////////////////////////////////////////
|
|||
|
// Utilities
|
|||
|
///////////////////////////////////////////////////////////
|
|||
|
|
|||
|
HIDDEN int get_isamfiles()
|
|||
|
{
|
|||
|
FileDes dir;
|
|||
|
CGetFile(LF_DIR, &dir, _nolock, NORDIR);
|
|||
|
return (int)dir.EOD;
|
|||
|
}
|
|||
|
|
|||
|
HIDDEN int str2isamfile(const TString& str)
|
|||
|
{
|
|||
|
int logic_num = 0;
|
|||
|
if (!str.blank())
|
|||
|
{
|
|||
|
const int logic = atoi(str);
|
|||
|
if (logic > 0)
|
|||
|
{
|
|||
|
if (logic > LF_DIR && logic < LF_EXTERNAL)
|
|||
|
{
|
|||
|
if (logic < get_isamfiles())
|
|||
|
{
|
|||
|
TBaseisamfile file(logic);
|
|||
|
if (file.is_valid() == NOERR)
|
|||
|
logic_num = logic;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
const int len = str.len();
|
|||
|
if (len == 3 || (str[0] == '%' && len == 4))
|
|||
|
{
|
|||
|
const int first = len == 3 ? 0 : 1;
|
|||
|
if (isalpha(str[first]) && isalnum(str[first+1]) && isalnum(str[first+2]))
|
|||
|
logic_num = str[0] == '%' ? LF_TABCOM : LF_TAB;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
return logic_num;
|
|||
|
}
|
|||
|
|
|||
|
HIDDEN int choose_isamfile(int selected)
|
|||
|
{
|
|||
|
TArray_sheet sht(-1,-1,-4,-4,"Selezione archivio", "Codice|Descrizione archivio@70");
|
|||
|
TToken_string tt(80);
|
|||
|
|
|||
|
long sel = 0;
|
|||
|
|
|||
|
const int nfiles = get_isamfiles();
|
|||
|
for (int logic = LF_TABCOM; logic < nfiles; logic++)
|
|||
|
{
|
|||
|
if (logic == selected)
|
|||
|
sel = sht.items();
|
|||
|
const char* desc = prefix().description(logic);
|
|||
|
if (*desc && stricmp(desc, "File non presente") != 0)
|
|||
|
{
|
|||
|
tt.format("%d", logic);
|
|||
|
tt.add(desc);
|
|||
|
sht.add(tt);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
sht.select(sel);
|
|||
|
if (sht.run() == K_ENTER)
|
|||
|
{
|
|||
|
sel = sht.selected();
|
|||
|
selected = sht.row(sel).get_int(0);
|
|||
|
}
|
|||
|
else
|
|||
|
selected = 0;
|
|||
|
return selected;
|
|||
|
}
|
|||
|
|
|||
|
///////////////////////////////////////////////////////////
|
|||
|
// THandled_mask
|
|||
|
///////////////////////////////////////////////////////////
|
|||
|
|
|||
|
enum TField_event { fe_null, fe_init, fe_modify, fe_button, fe_close,
|
|||
|
se_enter, se_query_modify, se_notify_modify,
|
|||
|
se_query_add, se_notify_add,
|
|||
|
se_query_del, se_notify_del };
|
|||
|
|
|||
|
class THandled_mask : public TMask
|
|||
|
{
|
|||
|
private:
|
|||
|
static bool universal_handler(TMask_field& f, KEY k);
|
|||
|
static bool universal_notifier(TSheet_field& f, int row, KEY k);
|
|||
|
|
|||
|
protected:
|
|||
|
void set_handlers();
|
|||
|
|
|||
|
public:
|
|||
|
virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly) pure;
|
|||
|
bool error_box(const char* fmt, ...); // No more f.error_box
|
|||
|
|
|||
|
THandled_mask() { }
|
|||
|
THandled_mask(const char* name, int num = 0);
|
|||
|
virtual ~THandled_mask() { }
|
|||
|
};
|
|||
|
|
|||
|
#define build_msg() char* _msg = (char*)(const char*)_ctl_data._park;va_list argptr;va_start(argptr,fmt);vsprintf(_msg,fmt,argptr);va_end(argptr)
|
|||
|
|
|||
|
bool THandled_mask::error_box(const char* fmt, ...)
|
|||
|
{
|
|||
|
TString message(1024);
|
|||
|
char* msg = message.get_buffer();
|
|||
|
va_list argptr;
|
|||
|
va_start(argptr, fmt);
|
|||
|
vsprintf(msg, fmt, argptr);
|
|||
|
va_end(argptr);
|
|||
|
|
|||
|
if (is_sheetmask() && !is_running())
|
|||
|
{
|
|||
|
xvt_statbar_set(msg);
|
|||
|
beep();
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
post_error_message(msg, 3);
|
|||
|
}
|
|||
|
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
bool THandled_mask::universal_handler(TMask_field& f, KEY key)
|
|||
|
{
|
|||
|
THandled_mask& wm = (THandled_mask&)f.mask();
|
|||
|
TOperable_field& of = (TOperable_field&)f;
|
|||
|
TField_event fe = fe_null;
|
|||
|
long jolly = key;
|
|||
|
switch (key)
|
|||
|
{
|
|||
|
case K_TAB:
|
|||
|
if (wm.is_running() || wm.get_sheet() != NULL)
|
|||
|
{
|
|||
|
if (f.focusdirty() && f.is_edit())
|
|||
|
fe = fe_modify;
|
|||
|
}
|
|||
|
else
|
|||
|
fe = fe_init;
|
|||
|
break;
|
|||
|
case K_SPACE:
|
|||
|
if (!f.is_edit())
|
|||
|
{
|
|||
|
if (wm.is_running())
|
|||
|
{
|
|||
|
if (f.is_kind_of(CLASS_BUTTON_FIELD))
|
|||
|
fe = fe_button;
|
|||
|
else
|
|||
|
fe = fe_modify;
|
|||
|
}
|
|||
|
else
|
|||
|
fe = fe_init;
|
|||
|
}
|
|||
|
break;
|
|||
|
case K_ENTER:
|
|||
|
fe = fe_close;
|
|||
|
break;
|
|||
|
case K_F9:
|
|||
|
if (f.is_edit())
|
|||
|
fe = fe_button;
|
|||
|
break;
|
|||
|
default:
|
|||
|
fe = fe_null;
|
|||
|
break;
|
|||
|
}
|
|||
|
return fe == fe_null ? TRUE : wm.on_field_event(of, fe, jolly);
|
|||
|
}
|
|||
|
|
|||
|
bool THandled_mask::universal_notifier(TSheet_field& s, int row, KEY key)
|
|||
|
{
|
|||
|
THandled_mask& wm = (THandled_mask&)s.mask();
|
|||
|
TField_event fe = fe_null;
|
|||
|
switch (key)
|
|||
|
{
|
|||
|
case K_INS:
|
|||
|
fe = se_query_add;
|
|||
|
break;
|
|||
|
case K_CTRL+K_INS:
|
|||
|
fe = se_notify_add;
|
|||
|
break;
|
|||
|
case K_DEL:
|
|||
|
fe = se_query_del;
|
|||
|
break;
|
|||
|
case K_CTRL+K_DEL:
|
|||
|
fe = se_notify_del;
|
|||
|
break;
|
|||
|
case K_TAB:
|
|||
|
fe = se_enter;
|
|||
|
break;
|
|||
|
case K_CTRL+K_TAB:
|
|||
|
fe = se_query_modify;
|
|||
|
break;
|
|||
|
case K_ENTER:
|
|||
|
fe = se_notify_modify;
|
|||
|
break;
|
|||
|
default:
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
return fe == fe_null ? TRUE : wm.on_field_event(s, fe, row);
|
|||
|
}
|
|||
|
|
|||
|
void THandled_mask::set_handlers()
|
|||
|
{
|
|||
|
for (int i = fields()-1; i >= 0; i--)
|
|||
|
{
|
|||
|
TMask_field& f = fld(i);
|
|||
|
if (f.is_operable())
|
|||
|
{
|
|||
|
f.set_handler(universal_handler);
|
|||
|
if (f.is_sheet())
|
|||
|
((TSheet_field&)f).set_notify(universal_notifier);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
THandled_mask::THandled_mask(const char* name, int num)
|
|||
|
: TMask(name, num)
|
|||
|
{
|
|||
|
set_handlers();
|
|||
|
}
|
|||
|
|
|||
|
///////////////////////////////////////////////////////////
|
|||
|
// TColumnizer_win
|
|||
|
///////////////////////////////////////////////////////////
|
|||
|
|
|||
|
class TColumnizer_win : public TViswin
|
|||
|
{
|
|||
|
// Array delle posizioni di inizio campo
|
|||
|
TPointer_array _column;
|
|||
|
bool _clickable;
|
|||
|
|
|||
|
protected: // TViswin
|
|||
|
virtual void handler(WINDOW win, EVENT* ep);
|
|||
|
virtual void paint_row(long r);
|
|||
|
virtual void paint_column(long c, bool end);
|
|||
|
|
|||
|
protected: // Internal use
|
|||
|
int on_column(long col);
|
|||
|
|
|||
|
public:
|
|||
|
bool clickable() const { return _clickable; }
|
|||
|
void set_clickable(bool on = TRUE) { _clickable = on; }
|
|||
|
|
|||
|
void destroy_columns() { _column.destroy(); }
|
|||
|
long add_column(long col) { return _column.add_long(col); }
|
|||
|
long get_column(int index) const { return _column.get_long(index); }
|
|||
|
|
|||
|
TColumnizer_win(int x, int y, int dx, int dy, WINDOW parent, TBrowsefile_field* field);
|
|||
|
virtual ~TColumnizer_win() { }
|
|||
|
};
|
|||
|
|
|||
|
int TColumnizer_win::on_column(long col)
|
|||
|
{
|
|||
|
int index = -1;
|
|||
|
if (col > 0)
|
|||
|
{
|
|||
|
int action = 1; // 1 = Add, 2 = Remove
|
|||
|
for (int i = _column.items()-1; i >= 0; i--)
|
|||
|
{
|
|||
|
const long cur_col = _column.get_long(i);
|
|||
|
if (cur_col == col)
|
|||
|
{
|
|||
|
action = 2;
|
|||
|
break;
|
|||
|
}
|
|||
|
if (cur_col < col)
|
|||
|
{
|
|||
|
action = 1;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
TSheet_field& sf = browsefile_field()->mask().sfield(F_FIELDS);
|
|||
|
switch(action)
|
|||
|
{
|
|||
|
case 1:
|
|||
|
index = _column.insert_long(col, i+1);
|
|||
|
sf.insert(index, TRUE, FALSE);
|
|||
|
break;
|
|||
|
case 2:
|
|||
|
_column.destroy(i, TRUE);
|
|||
|
sf.destroy(i+1, TRUE);
|
|||
|
break;
|
|||
|
default:
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
return index;
|
|||
|
}
|
|||
|
|
|||
|
void TColumnizer_win::handler(WINDOW win, EVENT* ep)
|
|||
|
{
|
|||
|
switch(ep->type)
|
|||
|
{
|
|||
|
case E_MOUSE_DOWN:
|
|||
|
xvt_win_trap_pointer (win);
|
|||
|
erase_point();
|
|||
|
break;
|
|||
|
case E_MOUSE_MOVE:
|
|||
|
break;
|
|||
|
case E_MOUSE_UP:
|
|||
|
TViswin::handler(win, ep);
|
|||
|
if (_clickable)
|
|||
|
{
|
|||
|
on_column(get_point().x);
|
|||
|
update();
|
|||
|
}
|
|||
|
break;
|
|||
|
case E_MOUSE_DBL:
|
|||
|
break;
|
|||
|
default:
|
|||
|
TViswin::handler(win, ep);
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void TColumnizer_win::paint_column(long j, bool end)
|
|||
|
{
|
|||
|
TViswin::paint_column(j, end);
|
|||
|
if (j > origin().x)
|
|||
|
{
|
|||
|
for (int i = _column.items()-1; i >= 0; i--)
|
|||
|
{
|
|||
|
if (_column.get_long(i) == j)
|
|||
|
{
|
|||
|
autoscroll(TRUE);
|
|||
|
_pixmap = TRUE;
|
|||
|
set_pen(COLOR_BLACK);
|
|||
|
const int x = tabx((int)j+6);
|
|||
|
line(x, taby(1), x, taby((int)lines()+1));
|
|||
|
_pixmap = FALSE;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void TColumnizer_win::paint_row(long r)
|
|||
|
{
|
|||
|
TViswin::paint_row(r);
|
|||
|
autoscroll(TRUE);
|
|||
|
_pixmap = TRUE;
|
|||
|
set_pen(COLOR_BLACK);
|
|||
|
for (int i = _column.items()-1; i >= 0; i--)
|
|||
|
{
|
|||
|
const int j = (int)_column.get_long(i);
|
|||
|
if (j > origin().x)
|
|||
|
{
|
|||
|
const int x = tabx(j+6);
|
|||
|
line(x, taby((int)r+1), x, taby((int)r+2));
|
|||
|
}
|
|||
|
}
|
|||
|
_pixmap = FALSE;
|
|||
|
}
|
|||
|
|
|||
|
TColumnizer_win::TColumnizer_win(int x, int y, int dx, int dy, WINDOW parent, TBrowsefile_field* field)
|
|||
|
: TViswin("", "", FALSE, FALSE, FALSE, x, y, dy, dx, TRUE, parent, field),
|
|||
|
_clickable(field->enabled())
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
///////////////////////////////////////////////////////////
|
|||
|
// TColumnizer_field
|
|||
|
///////////////////////////////////////////////////////////
|
|||
|
|
|||
|
class TColumnizer_field : public TBrowsefile_field
|
|||
|
{
|
|||
|
protected: // TMask_field
|
|||
|
virtual void create(WINDOW parent);
|
|||
|
|
|||
|
protected: // Internal use
|
|||
|
TColumnizer_win& col_win() const { return *(TColumnizer_win*)vis_win(); }
|
|||
|
|
|||
|
public: // TMask_field
|
|||
|
virtual void enable(bool on = TRUE);
|
|||
|
|
|||
|
public:
|
|||
|
void destroy_columns() { col_win().destroy_columns(); }
|
|||
|
void add_column(long col) { col_win().add_column(col); }
|
|||
|
long get_column(int index) const { return col_win().get_column(index); }
|
|||
|
|
|||
|
TColumnizer_field(THandled_mask* m);
|
|||
|
virtual ~TColumnizer_field() { }
|
|||
|
};
|
|||
|
|
|||
|
void TColumnizer_field::enable(bool on)
|
|||
|
{
|
|||
|
TBrowsefile_field::enable(on);
|
|||
|
col_win().set_clickable(on);
|
|||
|
}
|
|||
|
|
|||
|
void TColumnizer_field::create(WINDOW parent)
|
|||
|
{
|
|||
|
TColumnizer_win* cw = new TColumnizer_win(_ctl_data._x, _ctl_data._y,
|
|||
|
_ctl_data._width, _ctl_data._size,
|
|||
|
parent, this);
|
|||
|
set_vis_win(cw);
|
|||
|
TBrowsefile_field::create(parent);
|
|||
|
}
|
|||
|
|
|||
|
TColumnizer_field::TColumnizer_field(THandled_mask* m)
|
|||
|
: TBrowsefile_field(m)
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
///////////////////////////////////////////////////////////
|
|||
|
// TWizard_mask
|
|||
|
///////////////////////////////////////////////////////////
|
|||
|
|
|||
|
class TWizard_mask : public THandled_mask
|
|||
|
{
|
|||
|
TRelation* _rel;
|
|||
|
TRelation_description* _reldesc;
|
|||
|
|
|||
|
bool _frozen;
|
|||
|
|
|||
|
protected: // TMask
|
|||
|
virtual TMask_field* parse_field(TScanner& scanner);
|
|||
|
|
|||
|
protected: // THandled_mask
|
|||
|
virtual bool on_field_event(TOperable_field& f, TField_event e, long jolly);
|
|||
|
|
|||
|
protected: // Internal use only
|
|||
|
bool file_open(TFilename& name) const;
|
|||
|
void load_ini(const TString& ininame);
|
|||
|
void save_ini(const TFilename& ininame) const;
|
|||
|
bool load_aga(const TFilename& name);
|
|||
|
void file_preview() const;
|
|||
|
bool is_aga_file(const TFilename& name) const;
|
|||
|
bool import_file();
|
|||
|
|
|||
|
TRelation_description* rel_desc(int logicnum);
|
|||
|
|
|||
|
// First non-static handlers in history!
|
|||
|
bool file_handler(TOperable_field& f, TField_event e);
|
|||
|
bool ini_handler(TOperable_field& f, TField_event e);
|
|||
|
bool isamfile_handler(TOperable_field& f, TField_event e);
|
|||
|
|
|||
|
public:
|
|||
|
TRelation_description* rel_desc();
|
|||
|
|
|||
|
TWizard_mask();
|
|||
|
virtual ~TWizard_mask();
|
|||
|
};
|
|||
|
|
|||
|
///////////////////////////////////////////////////////////
|
|||
|
// TFields_mask
|
|||
|
///////////////////////////////////////////////////////////
|
|||
|
|
|||
|
class TFields_mask : public THandled_mask
|
|||
|
{
|
|||
|
protected: // THandled_mask
|
|||
|
virtual bool on_field_event(TOperable_field& of, TField_event fe, long jolly);
|
|||
|
|
|||
|
protected: // Internal use
|
|||
|
bool field_handler(TOperable_field& of, TField_event fe);
|
|||
|
|
|||
|
public:
|
|||
|
TRelation_description* rel_desc() const;
|
|||
|
|
|||
|
TFields_mask(const char* name, int number);
|
|||
|
virtual ~TFields_mask();
|
|||
|
};
|
|||
|
|
|||
|
bool TFields_mask::on_field_event(TOperable_field& of, TField_event fe, long jolly)
|
|||
|
{
|
|||
|
bool ok = TRUE;
|
|||
|
switch(of.dlg())
|
|||
|
{
|
|||
|
case F_FIELD:
|
|||
|
ok = field_handler(of, fe);
|
|||
|
break;
|
|||
|
default:
|
|||
|
break;
|
|||
|
}
|
|||
|
return ok;
|
|||
|
}
|
|||
|
|
|||
|
TRelation_description* TFields_mask::rel_desc() const
|
|||
|
{
|
|||
|
TSheet_field* sf = get_sheet();
|
|||
|
TWizard_mask& wm = (TWizard_mask&)sf->mask();
|
|||
|
TRelation_description* rd = wm.rel_desc();
|
|||
|
return rd;
|
|||
|
}
|
|||
|
|
|||
|
bool TFields_mask::field_handler(TOperable_field& of, TField_event fe)
|
|||
|
{
|
|||
|
bool ok = TRUE;
|
|||
|
|
|||
|
if (fe == fe_button)
|
|||
|
{
|
|||
|
TRelation_description* rd = rel_desc();
|
|||
|
if (rd)
|
|||
|
{
|
|||
|
if (rd->choose_field(of.get()))
|
|||
|
{
|
|||
|
of.set(rd->field_name());
|
|||
|
fe = fe_modify;
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
ok = error_box("Selezionare un file valido");
|
|||
|
}
|
|||
|
|
|||
|
if (fe == fe_modify || fe_close)
|
|||
|
{
|
|||
|
const TString& n = of.get();
|
|||
|
if (n.not_empty())
|
|||
|
{
|
|||
|
TRelation_description* rd = rel_desc();
|
|||
|
if (rd)
|
|||
|
{
|
|||
|
const char* d = rd->get_field_description(n);
|
|||
|
if (*d)
|
|||
|
set(F_DESCR, d);
|
|||
|
else
|
|||
|
ok = error_box("Il campo %s non esiste",
|
|||
|
(const char*)n, rd->file_desc());
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
return ok;
|
|||
|
}
|
|||
|
|
|||
|
TFields_mask::TFields_mask(const char* name, int number)
|
|||
|
: THandled_mask(name, number)
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
TFields_mask::~TFields_mask()
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
///////////////////////////////////////////////////////////
|
|||
|
// TFields_sheet
|
|||
|
///////////////////////////////////////////////////////////
|
|||
|
|
|||
|
class TFields_sheet : public TSheet_field
|
|||
|
{
|
|||
|
TFields_mask* _sheet_mask;
|
|||
|
|
|||
|
protected: // TSheet_field
|
|||
|
virtual void create(WINDOW win);
|
|||
|
virtual TMask& sheet_mask() const;
|
|||
|
|
|||
|
public:
|
|||
|
void describe_fields();
|
|||
|
bool handler(TField_event fe, long row);
|
|||
|
|
|||
|
TFields_sheet(THandled_mask* m);
|
|||
|
virtual ~TFields_sheet();
|
|||
|
};
|
|||
|
|
|||
|
TMask& TFields_sheet::sheet_mask() const
|
|||
|
{
|
|||
|
return _sheet_mask ? *(TMask*)_sheet_mask : TSheet_field::sheet_mask();
|
|||
|
}
|
|||
|
|
|||
|
void TFields_sheet::create(WINDOW win)
|
|||
|
{
|
|||
|
TSheet_field::create(win);
|
|||
|
|
|||
|
const TFilename& name = sheet_mask().source_file();
|
|||
|
const int number = sheet_mask().number();
|
|||
|
|
|||
|
_sheet_mask = new TFields_mask(name, number);
|
|||
|
_sheet_mask->set_sheet(this);
|
|||
|
}
|
|||
|
|
|||
|
void TFields_sheet::describe_fields()
|
|||
|
{
|
|||
|
TRelation_description* rd = _sheet_mask->rel_desc();
|
|||
|
if (rd)
|
|||
|
{
|
|||
|
TString str;
|
|||
|
for (int r = items()-1; r >= 0; r--)
|
|||
|
{
|
|||
|
TToken_string& riga = row(r);
|
|||
|
str = riga.get(0);
|
|||
|
str = rd->get_field_description(str);
|
|||
|
if (str.not_empty())
|
|||
|
riga.add(str, F_DESCR-FIRST_FIELD);
|
|||
|
}
|
|||
|
force_update();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
bool TFields_sheet::handler(TField_event fe, long row)
|
|||
|
{
|
|||
|
bool ok = TRUE;
|
|||
|
return ok;
|
|||
|
}
|
|||
|
|
|||
|
TFields_sheet::TFields_sheet(THandled_mask* m)
|
|||
|
: TSheet_field(m), _sheet_mask(NULL)
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
TFields_sheet::~TFields_sheet()
|
|||
|
{
|
|||
|
if (_sheet_mask)
|
|||
|
delete _sheet_mask;
|
|||
|
}
|
|||
|
|
|||
|
bool TWizard_mask::file_open(TFilename& fname) const
|
|||
|
{
|
|||
|
DIRECTORY dir;
|
|||
|
FILE_SPEC fs;
|
|||
|
|
|||
|
xvt_fsys_get_dir(&dir);
|
|||
|
xvt_fsys_get_dir(&fs.dir);
|
|||
|
strcpy(fs.type, fname.ext());
|
|||
|
strcpy(fs.name, fname);
|
|||
|
strcpy(fs.creator, "WIZ");
|
|||
|
|
|||
|
const bool good = xvt_dm_post_file_open(&fs, "Selezionare il file ...") == FL_OK;
|
|||
|
xvt_fsys_set_dir(&dir);
|
|||
|
|
|||
|
if (good)
|
|||
|
fname = fs.name;
|
|||
|
|
|||
|
return good;
|
|||
|
}
|
|||
|
|
|||
|
void TWizard_mask::load_ini(const TString& ininame)
|
|||
|
{
|
|||
|
const bool was_frozen = _frozen;
|
|||
|
_frozen = TRUE;
|
|||
|
|
|||
|
TConfig ini(ininame, "MAIN");
|
|||
|
const int recsize = ini.get_int("RECORDSIZE");
|
|||
|
if (recsize > 0)
|
|||
|
{
|
|||
|
set(F_FIXEDLEN, "X", TRUE);
|
|||
|
set(F_RECLEN, recsize, TRUE);
|
|||
|
}
|
|||
|
else
|
|||
|
set(F_RECSEP, ini.get("RECORDSEP").left(4), TRUE);
|
|||
|
set(F_SKIPLINES, ini.get_int("SKIPLINES"));
|
|||
|
|
|||
|
const TString& fldsep = ini.get("FIELDSEP");
|
|||
|
set(F_FIELDSEP, fldsep.left(1), TRUE);
|
|||
|
|
|||
|
ini.set_paragraph("RECORD");
|
|||
|
|
|||
|
if (fldsep.empty())
|
|||
|
{
|
|||
|
TColumnizer_field& cf = (TColumnizer_field&)field(F_COLUMNIZER);
|
|||
|
for (int i = 0; ; i++)
|
|||
|
{
|
|||
|
if (i > 0)
|
|||
|
{
|
|||
|
const long position = ini.get_long("POSITION", NULL, i);
|
|||
|
if (position > 0)
|
|||
|
cf.add_column(position);
|
|||
|
else
|
|||
|
break;
|
|||
|
}
|
|||
|
else
|
|||
|
cf.destroy_columns();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
_frozen = was_frozen;
|
|||
|
}
|
|||
|
|
|||
|
void TWizard_mask::save_ini(const TFilename& ininame) const
|
|||
|
{
|
|||
|
if (!ininame.blank())
|
|||
|
{
|
|||
|
if (!ininame.exist() ||
|
|||
|
yesno_box("Si desidera sovrascrivere il file %s", (const char*)ininame))
|
|||
|
{
|
|||
|
TConfig ini(ininame, "MAIN");
|
|||
|
ini.remove_all();
|
|||
|
ini.set("RECORDSEP", get(F_RECSEP));
|
|||
|
ini.set("RECORDSIZE", get(F_RECLEN));
|
|||
|
ini.set("SKIPLINES", get(F_SKIPLINES));
|
|||
|
const TString& fieldsep = get(F_FIELDSEP);
|
|||
|
ini.set("FIELDSEP", fieldsep);
|
|||
|
ini.set("TYPEFIELD", -1);
|
|||
|
|
|||
|
ini.set_paragraph("RECORD");
|
|||
|
ini.remove_all();
|
|||
|
ini.set("USE", get(F_ISAM));
|
|||
|
|
|||
|
if (fieldsep.empty())
|
|||
|
{
|
|||
|
const TColumnizer_field& cf = (const TColumnizer_field&)field(F_COLUMNIZER);
|
|||
|
long last_column = 0;
|
|||
|
for (int i = 0; ; i++)
|
|||
|
{
|
|||
|
const long column = cf.get_column(i);
|
|||
|
if (column <= 0)
|
|||
|
break;
|
|||
|
const long len = column - last_column;
|
|||
|
ini.set("POSITION", last_column, NULL, TRUE, i);
|
|||
|
ini.set("LENGTH", len, NULL, TRUE, i);
|
|||
|
last_column = column;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
TSheet_field& sf = sfield(F_FIELDS);
|
|||
|
FOR_EACH_SHEET_ROW(sf, r, row)
|
|||
|
{
|
|||
|
ini.set("FIELD", row->get(0), NULL, TRUE, r);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
bool TWizard_mask::is_aga_file(const TFilename& name) const
|
|||
|
{
|
|||
|
bool yes = stricmp(name.ext(), "txt") == 0;
|
|||
|
if (yes)
|
|||
|
{
|
|||
|
TScanner aga(name);
|
|||
|
yes = aga.paragraph("Data"); // Esiste il paragrafo dati?
|
|||
|
}
|
|||
|
return yes;
|
|||
|
}
|
|||
|
|
|||
|
bool TWizard_mask::load_aga(const TFilename& name)
|
|||
|
{
|
|||
|
TWait_cursor hourglass;
|
|||
|
const bool was_frozen = _frozen;
|
|||
|
_frozen = TRUE;
|
|||
|
|
|||
|
TSheet_field& sf = sfield(F_FIELDS);
|
|||
|
TScanner aga(name);
|
|||
|
TToken_string riga(1024);
|
|||
|
TToken_string campo(15, ',');
|
|||
|
TString isam;
|
|||
|
bool inside_header = FALSE;
|
|||
|
|
|||
|
while (aga.line().not_empty())
|
|||
|
{
|
|||
|
riga = aga.token();
|
|||
|
|
|||
|
if (riga.compare("[Data]", -1, TRUE) == 0)
|
|||
|
{
|
|||
|
set(F_FIXEDLEN, "", TRUE);
|
|||
|
set(F_RECLEN, "", TRUE);
|
|||
|
set(F_RECSEP, "", TRUE);
|
|||
|
set(F_FIELDSEP, "|", TRUE);
|
|||
|
set(F_SKIPLINES, aga.linenum(), TRUE);
|
|||
|
set(F_ISAM, isam, TRUE);
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
if (inside_header)
|
|||
|
{
|
|||
|
if (riga.compare("Fields", 6, TRUE) == 0)
|
|||
|
{
|
|||
|
const int uguale = riga.find('=');
|
|||
|
if (uguale >= 0)
|
|||
|
{
|
|||
|
riga.ltrim(uguale+1);
|
|||
|
for(campo = riga.get(0); campo.not_empty(); campo = riga.get())
|
|||
|
{
|
|||
|
sf.row(-1) = campo.get(0);
|
|||
|
sf.check_row(sf.items()-1);
|
|||
|
}
|
|||
|
}
|
|||
|
} else
|
|||
|
if (riga.compare("File", 4, TRUE) == 0)
|
|||
|
{
|
|||
|
const int uguale = riga.find('=');
|
|||
|
if (uguale >= 0)
|
|||
|
{
|
|||
|
isam = riga.mid(uguale+1);
|
|||
|
isam.trim();
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
inside_header = riga[0] != '[';
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if (riga.compare("[Header]", -1, TRUE) == 0)
|
|||
|
{
|
|||
|
sf.destroy();
|
|||
|
inside_header = TRUE;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
sf.force_update();
|
|||
|
|
|||
|
_frozen = was_frozen;
|
|||
|
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
|
|||
|
void TWizard_mask::file_preview() const
|
|||
|
{
|
|||
|
TWait_cursor hourglass;
|
|||
|
const TString& fname = get(F_FILE);
|
|||
|
if (_frozen/* || !fexist(fname) */)
|
|||
|
return;
|
|||
|
|
|||
|
const int MAXLINE = 8192;
|
|||
|
const bool fixedlen = get_bool(F_FIXEDLEN);
|
|||
|
const int reclen = fixedlen ? get_int(F_RECLEN) : 0;
|
|||
|
const long skiplines = get_long(F_SKIPLINES);
|
|||
|
const TString& recsep = get(F_RECSEP);
|
|||
|
const TString& fieldsep = get(F_FIELDSEP);
|
|||
|
|
|||
|
int flags = ios::in | ios::nocreate;
|
|||
|
if (fixedlen)
|
|||
|
flags |= ios::binary;
|
|||
|
ifstream f(fname, flags);
|
|||
|
|
|||
|
if (fixedlen)
|
|||
|
{
|
|||
|
streamoff offset = reclen * skiplines;
|
|||
|
f.seekg(offset, ios::beg);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
for (long s = skiplines; s > 0; s--)
|
|||
|
{
|
|||
|
if (*recsep)
|
|||
|
f.ignore(MAXLINE, *recsep);
|
|||
|
else
|
|||
|
f.ignore(MAXLINE, '\n');
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
TString_array righe;
|
|||
|
|
|||
|
int displines = get_int(F_DISPLINES);
|
|||
|
if (displines <= 0) displines = 4;
|
|||
|
for (int l = 0; l < displines; l++)
|
|||
|
{
|
|||
|
righe.add(new TToken_string(MAXLINE), l);
|
|||
|
TToken_string& riga = righe.row(l);
|
|||
|
char* buff = riga.get_buffer();
|
|||
|
|
|||
|
if (fixedlen)
|
|||
|
{
|
|||
|
f.read(buff, reclen);
|
|||
|
riga.cut(reclen);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if (*recsep)
|
|||
|
{
|
|||
|
f.getline(buff, riga.size(), *recsep);
|
|||
|
f.ignore(strlen(recsep)-1);
|
|||
|
}
|
|||
|
else
|
|||
|
f.getline(buff, riga.size());
|
|||
|
}
|
|||
|
if (f.eof())
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
TColumnizer_field& cf = (TColumnizer_field&)field(F_COLUMNIZER);
|
|||
|
if (fieldsep.blank())
|
|||
|
{
|
|||
|
cf.enable();
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
TPointer_array maxlen;
|
|||
|
int maxcol = 0;
|
|||
|
int l;
|
|||
|
for (l = righe.items()-1; l >= 0; l--)
|
|||
|
{
|
|||
|
TToken_string& riga = righe.row(l);
|
|||
|
riga.separator(fieldsep[0]);
|
|||
|
int col = 0;
|
|||
|
FOR_EACH_TOKEN(riga, tok)
|
|||
|
{
|
|||
|
const long len = *tok ? strlen(tok) : 1;
|
|||
|
if (len > maxlen.get_long(col))
|
|||
|
maxlen.add_long(len, col);
|
|||
|
col++;
|
|||
|
}
|
|||
|
if (col > maxcol)
|
|||
|
maxcol = col;
|
|||
|
}
|
|||
|
cf.disable();
|
|||
|
cf.destroy_columns();
|
|||
|
long last_column = 0;
|
|||
|
for (l = 0; l < maxcol; l++)
|
|||
|
{
|
|||
|
const long len = maxlen.get_long(l);
|
|||
|
last_column += len;
|
|||
|
cf.add_column(last_column);
|
|||
|
}
|
|||
|
|
|||
|
TToken_string oldrow;
|
|||
|
TString str;
|
|||
|
for (l = righe.items()-1; l >= 0; l--)
|
|||
|
{
|
|||
|
TToken_string& riga = righe.row(l);
|
|||
|
oldrow = riga;
|
|||
|
riga.cut(0);
|
|||
|
int col = 0;
|
|||
|
FOR_EACH_TOKEN(oldrow, tok)
|
|||
|
{
|
|||
|
const int len = (int)maxlen.get_long(col);
|
|||
|
str = tok;
|
|||
|
if (str[0] =='#' || real::is_real(str))
|
|||
|
str.right_just(len);
|
|||
|
else
|
|||
|
str.left_just(len);
|
|||
|
riga << str;
|
|||
|
col++;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
cf.vis_win()->destroy_lines();
|
|||
|
for (l = 0; l < righe.items(); l++)
|
|||
|
{
|
|||
|
TToken_string& riga = righe.row(l);
|
|||
|
riga.replace('|', '<EFBFBD>'); // Grossa crisi coi tubi
|
|||
|
riga.replace('@', '#'); // Grossa crisi con le lumache
|
|||
|
if (fixedlen)
|
|||
|
{
|
|||
|
riga.replace('\n', '<EFBFBD>'); // Grossa crisi con l'a capo
|
|||
|
if (reclen > 256) // Grossa crisi con le righe lunghe
|
|||
|
riga.cut(256);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if (riga.len() > 256) // Grossa crisi con le righe lunghe
|
|||
|
riga.cut(256);
|
|||
|
}
|
|||
|
cf.add_line(riga);
|
|||
|
}
|
|||
|
cf.goto_pos(0, 0);
|
|||
|
}
|
|||
|
|
|||
|
TRelation_description* TWizard_mask::rel_desc(int logicnum)
|
|||
|
{
|
|||
|
if (_rel && _rel->lfile().num() != logicnum)
|
|||
|
{
|
|||
|
delete _rel;
|
|||
|
_rel = NULL;
|
|||
|
delete _reldesc;
|
|||
|
_reldesc = NULL;
|
|||
|
}
|
|||
|
if (_rel == NULL && logicnum > 0)
|
|||
|
{
|
|||
|
_rel = new TRelation(logicnum);
|
|||
|
_reldesc = new TRelation_description(*_rel);
|
|||
|
}
|
|||
|
|
|||
|
return _reldesc;
|
|||
|
}
|
|||
|
|
|||
|
TRelation_description* TWizard_mask::rel_desc()
|
|||
|
{
|
|||
|
TRelation_description* rd = NULL;
|
|||
|
const TString& isam = get(F_ISAM);
|
|||
|
const int logicnum = str2isamfile(isam);
|
|||
|
if (logicnum > 0)
|
|||
|
rd = rel_desc(logicnum);
|
|||
|
return rd;
|
|||
|
}
|
|||
|
|
|||
|
bool TWizard_mask::file_handler(TOperable_field& f, TField_event e)
|
|||
|
{
|
|||
|
bool ok = TRUE;
|
|||
|
|
|||
|
if (e == fe_button)
|
|||
|
{
|
|||
|
TFilename n("*.txt");
|
|||
|
if (file_open(n))
|
|||
|
{
|
|||
|
f.set(n);
|
|||
|
e = fe_modify;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (e == fe_modify)
|
|||
|
{
|
|||
|
TFilename n = f.get();
|
|||
|
if (n.exist())
|
|||
|
{
|
|||
|
if (is_aga_file(n))
|
|||
|
{
|
|||
|
load_aga(n);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
const char* ext[] = { "imp", "ini", NULL };
|
|||
|
for (int e = 0; ext[e]; e++)
|
|||
|
{
|
|||
|
n.ext(ext[e]);
|
|||
|
if (n.exist())
|
|||
|
{
|
|||
|
set(F_INI, n, TRUE);
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
n = n.name();
|
|||
|
n.ext("");
|
|||
|
if ((n[0] == 'f' || n[0] == 'F') && atoi(n.mid(1,-1)))
|
|||
|
n.ltrim(1);
|
|||
|
if (str2isamfile(n))
|
|||
|
set(F_ISAM, TRUE);
|
|||
|
|
|||
|
file_preview();
|
|||
|
}
|
|||
|
else
|
|||
|
ok = error_box("Il file non esiste");
|
|||
|
}
|
|||
|
return ok;
|
|||
|
}
|
|||
|
|
|||
|
bool TWizard_mask::ini_handler(TOperable_field& f, TField_event e)
|
|||
|
{
|
|||
|
bool ok = TRUE;
|
|||
|
switch (e)
|
|||
|
{
|
|||
|
case fe_button:
|
|||
|
{
|
|||
|
TFilename n("*.imp");
|
|||
|
if (file_open(n))
|
|||
|
f.set(n);
|
|||
|
else
|
|||
|
break;
|
|||
|
}
|
|||
|
case fe_init:
|
|||
|
case fe_modify:
|
|||
|
{
|
|||
|
const TFilename n = f.get();
|
|||
|
const bool pieno = !n.blank();
|
|||
|
enable(F_SAVE, pieno);
|
|||
|
if (pieno)
|
|||
|
{
|
|||
|
if (n.exist())
|
|||
|
{
|
|||
|
load_ini(n);
|
|||
|
file_preview();
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
break;
|
|||
|
default:
|
|||
|
break;
|
|||
|
}
|
|||
|
return ok;
|
|||
|
}
|
|||
|
|
|||
|
bool TWizard_mask::isamfile_handler(TOperable_field& f, TField_event e)
|
|||
|
{
|
|||
|
bool ok = TRUE;
|
|||
|
switch (e)
|
|||
|
{
|
|||
|
case fe_init:
|
|||
|
disable(F_IMPORT);
|
|||
|
break;
|
|||
|
case fe_button:
|
|||
|
{
|
|||
|
int logicnum = str2isamfile(f.get());
|
|||
|
logicnum = choose_isamfile(logicnum);
|
|||
|
if (logicnum > 0)
|
|||
|
f.set(logicnum);
|
|||
|
else
|
|||
|
break;
|
|||
|
}
|
|||
|
case fe_modify:
|
|||
|
{
|
|||
|
bool can_import = str2isamfile(f.get()) > 0;
|
|||
|
if (can_import)
|
|||
|
{
|
|||
|
TFields_sheet& fs = (TFields_sheet&)sfield(F_FIELDS);
|
|||
|
fs.describe_fields();
|
|||
|
}
|
|||
|
else
|
|||
|
ok = error_box("File non valido");
|
|||
|
can_import &= fexist(get(F_FILE));
|
|||
|
enable(F_IMPORT, can_import);
|
|||
|
reset(F_ZAP);
|
|||
|
}
|
|||
|
break;
|
|||
|
}
|
|||
|
return ok;
|
|||
|
}
|
|||
|
|
|||
|
bool TWizard_mask::import_file()
|
|||
|
{
|
|||
|
bool ok = FALSE;
|
|||
|
|
|||
|
const TFilename filename = get(F_FILE);
|
|||
|
if (!filename.exist())
|
|||
|
return error_box("Il file %s non esiste", (const char*)filename);
|
|||
|
|
|||
|
const int logicnum = str2isamfile(get(F_ISAM));
|
|||
|
if (logicnum <= 0)
|
|||
|
return error_box("E' necessario specificare un file di destinazione valido");
|
|||
|
|
|||
|
rel_desc(0); // Chiude il file isam correntemente in uso, altrimenti niente _excllock
|
|||
|
TSystemisamfile sif(logicnum);
|
|||
|
int err = sif.open_ex(_excllock);
|
|||
|
if (err != NOERR)
|
|||
|
return error_box("Impossibile aprire il file %d: errore %d", logicnum, err);
|
|||
|
const bool empty = sif.items() == 0L;
|
|||
|
sif.close();
|
|||
|
|
|||
|
if (get_bool(F_ZAP))
|
|||
|
{
|
|||
|
if (!empty && yesno_box("Procedere con l'azzeramento del file %d?", logicnum))
|
|||
|
sif.packfile(FALSE, TRUE);
|
|||
|
}
|
|||
|
|
|||
|
const TFilename ininame = get(F_INI);
|
|||
|
if (ininame.exist())
|
|||
|
{
|
|||
|
TFile_text txt(filename, ininame);
|
|||
|
err = txt.open('r');
|
|||
|
if (err == NOERR)
|
|||
|
{
|
|||
|
TRecord_text rec;
|
|||
|
for (long numrec = 1; txt.read(rec) == NOERR; numrec++)
|
|||
|
{
|
|||
|
err = txt.autosave(rec);
|
|||
|
if (err != NOERR)
|
|||
|
{
|
|||
|
ok = error_box("Errore %d durante la scrittura del record %ld:",
|
|||
|
err, numrec);
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
ok = error_box("Impossibile leggere il file %s", (const char*)filename);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if (is_aga_file(filename))
|
|||
|
{
|
|||
|
err = sif.open_ex(_excllock);
|
|||
|
if (err == NOERR)
|
|||
|
ok = sif.load(filename) == NOERR;
|
|||
|
else
|
|||
|
ok = error_box("Impossibile aprire il file %d: errore %d", logicnum, err);
|
|||
|
sif.close();
|
|||
|
}
|
|||
|
else
|
|||
|
ok = error_box("Il file %s non esiste", (const char*)ininame);
|
|||
|
}
|
|||
|
return ok;
|
|||
|
}
|
|||
|
|
|||
|
bool TWizard_mask::on_field_event(TOperable_field& f, TField_event e, long jolly)
|
|||
|
{
|
|||
|
bool ok = TRUE;
|
|||
|
switch(f.dlg())
|
|||
|
{
|
|||
|
case F_FILE:
|
|||
|
ok = file_handler(f, e);
|
|||
|
break;
|
|||
|
case F_INI:
|
|||
|
ok = ini_handler(f, e);
|
|||
|
break;
|
|||
|
case F_RECLEN:
|
|||
|
case F_RECSEP:
|
|||
|
case F_FIELDSEP:
|
|||
|
case F_SKIPLINES:
|
|||
|
case F_DISPLINES:
|
|||
|
case F_FIXEDLEN:
|
|||
|
if (e == fe_modify)
|
|||
|
file_preview();
|
|||
|
break;
|
|||
|
case F_ISAM:
|
|||
|
ok = isamfile_handler(f, e);
|
|||
|
break;
|
|||
|
case F_SAVE:
|
|||
|
if (e == fe_button)
|
|||
|
save_ini(get(F_INI));
|
|||
|
break;
|
|||
|
case F_IMPORT:
|
|||
|
if (e == fe_button)
|
|||
|
import_file();
|
|||
|
break;
|
|||
|
case F_FIELDS:
|
|||
|
ok = ((TFields_sheet&)f).handler(e, jolly);
|
|||
|
break;
|
|||
|
default:
|
|||
|
break;
|
|||
|
}
|
|||
|
return ok;
|
|||
|
}
|
|||
|
|
|||
|
TMask_field* TWizard_mask::parse_field(TScanner& scanner)
|
|||
|
{
|
|||
|
const TString& key = scanner.key();
|
|||
|
if (key == "BR")
|
|||
|
return new TColumnizer_field(this);
|
|||
|
if (key == "SP")
|
|||
|
return new TFields_sheet(this);
|
|||
|
return THandled_mask::parse_field(scanner);
|
|||
|
}
|
|||
|
|
|||
|
TWizard_mask::TWizard_mask()
|
|||
|
: _frozen(FALSE), _reldesc(NULL), _rel(NULL)
|
|||
|
{
|
|||
|
read_mask("ba1800a", 0, 1);
|
|||
|
set_handlers();
|
|||
|
}
|
|||
|
|
|||
|
TWizard_mask::~TWizard_mask()
|
|||
|
{
|
|||
|
if (_reldesc)
|
|||
|
delete _reldesc;
|
|||
|
if (_rel)
|
|||
|
delete _rel;
|
|||
|
}
|
|||
|
|
|||
|
///////////////////////////////////////////////////////////
|
|||
|
// Wizard main app
|
|||
|
///////////////////////////////////////////////////////////
|
|||
|
|
|||
|
class TImport_wizard : public TSkeleton_application
|
|||
|
{
|
|||
|
protected: // TSkeleton_application
|
|||
|
virtual void main_loop();
|
|||
|
};
|
|||
|
|
|||
|
void TImport_wizard::main_loop()
|
|||
|
{
|
|||
|
TWizard_mask m;
|
|||
|
m.run();
|
|||
|
}
|
|||
|
|
|||
|
int ba1800(int argc, char* argv[])
|
|||
|
{
|
|||
|
TImport_wizard of_oz;
|
|||
|
of_oz.run(argc, argv, "Import Wizard");
|
|||
|
return 0;
|
|||
|
}
|