Files correlati : ba0.exe Ricompilazione Demo : [ ] Commento : EP20140 Ho inserito la ditta 1 in anagrafica ditte e ho caricato i sui archivi, ho inserito la ditta 2 in anagrafica ditte ma non sono stati ancora generati i sui archivi:entrando nel programma scelta contabilità (e anche in tutti gli altri programmi che nella versione 1.7 visualizzavano la maschera seleziona ditta) non viene visualizzata la maschera seleziona ditta. La visualizzazione della maschera dipende quindi anche dal fatto che esista o meno la cartella della seconda ditta nel direttorio dei dati. git-svn-id: svn://10.65.10.50/trunk@11543 c028cbd2-c16b-5b4b-a496-9718f37d4682
719 lines
15 KiB
C++
Executable File
719 lines
15 KiB
C++
Executable File
#include <applicat.h>
|
|
#include <config.h>
|
|
#include <currency.h>
|
|
#include <dongle.h>
|
|
#include <execp.h>
|
|
#include <mask.h>
|
|
#include <prefix.h>
|
|
#include <relation.h>
|
|
#include <utility.h>
|
|
|
|
#include "ba0100a.h"
|
|
#include "ba0101.h"
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// Menu management
|
|
///////////////////////////////////////////////////////////
|
|
|
|
static int get_next_string(const char* s, int from, TString& str, char& brace)
|
|
{
|
|
if (from < 0)
|
|
return -1;
|
|
|
|
char closing = '\0';
|
|
int start = 0;
|
|
|
|
for (int i = from; s[i]; i++)
|
|
{
|
|
if (s[i] == closing)
|
|
{
|
|
char* fine = (char*)(s + i);
|
|
const char old = *fine;
|
|
*fine = '\0';
|
|
str = s + start;
|
|
*fine = old;
|
|
return i+1;
|
|
}
|
|
|
|
if (!closing)
|
|
{
|
|
switch(s[i])
|
|
{
|
|
case '\'':
|
|
case '"' : closing = s[i]; break;
|
|
case '<' : closing = '>' ; break;
|
|
case '[' : closing = ']' ; break;
|
|
default : break;
|
|
}
|
|
if (closing)
|
|
{
|
|
start = i+1;
|
|
brace = s[i];
|
|
}
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
static int get_next_int(const char* s, int from, int& val)
|
|
{
|
|
if (from < 0)
|
|
return -1;
|
|
|
|
const char* start = NULL;
|
|
for (int i = from; s[i]; i++)
|
|
{
|
|
if (start == NULL)
|
|
{
|
|
if (isdigit(s[i]))
|
|
start = s+i;
|
|
}
|
|
else
|
|
{
|
|
if (s[i] == ',')
|
|
break;
|
|
}
|
|
}
|
|
if (start != NULL)
|
|
val = atoi(start);
|
|
|
|
return i;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// TTimed_image
|
|
///////////////////////////////////////////////////////////
|
|
|
|
class TTimed_image : public TImage
|
|
{
|
|
clock_t _last_time;
|
|
|
|
public:
|
|
clock_t touch() { return _last_time = clock(); }
|
|
clock_t last_time() const { return _last_time; }
|
|
|
|
TTimed_image(const char* name) : TImage(name) { touch(); }
|
|
virtual ~TTimed_image() { }
|
|
};
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// Menu Item
|
|
///////////////////////////////////////////////////////////
|
|
|
|
TMenuitem::TMenuitem(TSubmenu* sm)
|
|
: _submenu(sm), _exist(-1), _firm(FALSE),
|
|
_password(FALSE), _reloadmenu(FALSE),
|
|
_color(NORMAL_COLOR), _icon(0)
|
|
{ }
|
|
|
|
TMenuitem::TMenuitem(const TMenuitem& mi)
|
|
: _submenu(mi._submenu), _exist(mi._exist), _firm(mi._firm),
|
|
_password(mi._password), _reloadmenu(mi._reloadmenu),
|
|
_color(mi._color), _icon(mi._icon), _enabled(mi._enabled),
|
|
_caption(mi._caption), _action(mi._action), _type(mi._type)
|
|
{ }
|
|
|
|
|
|
TMenu& TMenuitem::menu() const
|
|
{ return _submenu->menu(); }
|
|
|
|
void TMenuitem::create(const char* t)
|
|
{
|
|
TString16 flags;
|
|
char brace;
|
|
int start = 0;
|
|
|
|
start = get_next_string(t, start, _caption, brace);
|
|
start = get_next_string(t, start, _action, _type);
|
|
start = get_next_string(t, start, flags, brace);
|
|
start = get_next_int(t, start, _icon);
|
|
_caption = dictionary_translate(_caption);
|
|
|
|
for (int i = flags.len()-1; i >= 0; i--)
|
|
{
|
|
switch(toupper(flags[i]))
|
|
{
|
|
case 'D': _exist = FALSE; break;
|
|
case 'F': _firm = TRUE; break;
|
|
case 'P': _password = TRUE; break;
|
|
case 'R': _reloadmenu = TRUE; break;
|
|
default : break;
|
|
}
|
|
}
|
|
|
|
if (_type == '<')
|
|
{
|
|
if (_action.find('.') < 0)
|
|
_action << ".men";
|
|
TFilename n = _action; n.custom_path();
|
|
if (n.exist())
|
|
menu().read(_action, _action);
|
|
else
|
|
_action.cut(0);
|
|
_type = '[';
|
|
}
|
|
|
|
if (_action.empty())
|
|
{
|
|
_exist = FALSE;
|
|
_enabled = FALSE;
|
|
}
|
|
|
|
// Controlla lo stato di aggiornamento
|
|
if (_enabled && is_program())
|
|
_enabled = !menu().is_dangerous(_action);
|
|
}
|
|
|
|
int TMenuitem::icon() const
|
|
{
|
|
return _icon;
|
|
}
|
|
|
|
bool TMenuitem::enabled() const
|
|
{
|
|
bool yes = FALSE;
|
|
if (_exist)
|
|
{
|
|
if (is_submenu())
|
|
{
|
|
TSubmenu* mnu = menu().find(_action);
|
|
yes = mnu && mnu->enabled();
|
|
}
|
|
else
|
|
{
|
|
if (_exist < 0)
|
|
{
|
|
if (menu().is_dangerous(_action))
|
|
{
|
|
yes = FALSE;
|
|
}
|
|
else
|
|
{
|
|
const int endname = _action.find(' ');
|
|
TFilename name(endname > 0 ? _action.left(endname) : _action);
|
|
const char* ext[] = { "exe", "pif", "com", "bat", NULL };
|
|
for (int e = 0; ext[e]; e++)
|
|
{
|
|
name.ext(ext[e]);
|
|
if (name.exist())
|
|
break;
|
|
}
|
|
yes = ext[e] != NULL;
|
|
}
|
|
((TMenuitem*)this)->_exist = yes;
|
|
}
|
|
if (_exist)
|
|
{
|
|
TExternal_app app(_action);
|
|
yes = app.can_run();
|
|
}
|
|
if (!yes)
|
|
((TMenuitem*)this)->_enabled = FALSE;
|
|
}
|
|
}
|
|
return yes;
|
|
}
|
|
|
|
bool TMenuitem::perform_submenu() const
|
|
{
|
|
TSubmenu* mnu = menu().find(_action);
|
|
bool ok = mnu != NULL && mnu->enabled();
|
|
if (ok)
|
|
ok = menu().jumpto(mnu);
|
|
return ok;
|
|
}
|
|
|
|
bool TMenuitem::perform_program() const
|
|
{
|
|
bool ok = TRUE;
|
|
|
|
if (_password)
|
|
{
|
|
TMask mask("ba0100a");
|
|
mask.disable(F_USER);
|
|
mask.set(F_USER, "SERVIZIO");
|
|
ok = FALSE;
|
|
if (mask.run() == K_ENTER)
|
|
{
|
|
const TDate oggi(TODAY);
|
|
TString16 pwd; pwd << dongle().administrator() << (oggi.month() + oggi.day());
|
|
ok = pwd == mask.get(F_PASSWORD);
|
|
}
|
|
if (!ok) error_box("Password di servizio errata!\nAccesso negato.");
|
|
}
|
|
|
|
if (_firm && main_app().get_firm() == 0)
|
|
#ifdef _DEMO_
|
|
ok = menu().set_firm(1);
|
|
#else
|
|
ok = menu().set_firm(0);
|
|
#endif
|
|
|
|
if (ok)
|
|
{
|
|
TCurrency::force_cache_update(); // Chiude cache valute
|
|
prefix().set(NULL); // Chiude prefix
|
|
TExternal_app a(_action);
|
|
a.run(FALSE,3);
|
|
|
|
const bool maintenance_app = _action.compare("ba1 -0", 6, TRUE) == 0;
|
|
if (maintenance_app)
|
|
{
|
|
char line1[16],line2[16];
|
|
|
|
while (fexist("conv.his"))
|
|
{
|
|
FILE* fp = fopen("conv.his","r");
|
|
fgets(line1,15,fp);
|
|
fclose(fp);
|
|
// Ora aspetta...
|
|
time_t old_time ;
|
|
time( &old_time) ;
|
|
while ( time( (time_t *) 0 ) <= old_time ) do_events();
|
|
TExternal_app auto_conv("ba1 -0 -C");
|
|
auto_conv.run();
|
|
fp = fopen("conv.his","r");
|
|
if (fp != NULL)
|
|
{
|
|
fgets(line2,15,fp);
|
|
fclose(fp);
|
|
}
|
|
else strcpy(line2,"");
|
|
if (strcmp(line1,line2) == 0)
|
|
if (!yesno_box("La conversione non sembra procedere. Continuare?"))
|
|
break;
|
|
}
|
|
}
|
|
prefix().set("DEF"); // Aggiorna prefix
|
|
}
|
|
|
|
return ok;
|
|
}
|
|
|
|
bool TMenuitem::perform() const
|
|
{
|
|
bool ok = enabled();
|
|
if (ok)
|
|
{
|
|
if (is_submenu())
|
|
ok = perform_submenu();
|
|
else
|
|
ok = perform_program();
|
|
}
|
|
return ok;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// Submenu
|
|
///////////////////////////////////////////////////////////
|
|
|
|
TSubmenu::TSubmenu(TMenu* menu, const char* name)
|
|
: _menu(menu), _name(name), _enabled(TRUE), _firm(FALSE), _items(12)
|
|
{
|
|
}
|
|
|
|
void TSubmenu::read(TScanner& scanner)
|
|
{
|
|
while (scanner.ok())
|
|
{
|
|
TString& line = scanner.line();
|
|
if (line.empty())
|
|
break;
|
|
if (line[0] == '[')
|
|
{
|
|
scanner.push();
|
|
break;
|
|
}
|
|
|
|
char brace;
|
|
if (line.compare("Caption", 7, TRUE) == 0)
|
|
{
|
|
get_next_string(line, 8, _caption, brace);
|
|
_caption = dictionary_translate(_caption);
|
|
} else
|
|
if (line.compare("Module", 6, TRUE) == 0)
|
|
{
|
|
const int equal = line.find('=');
|
|
if (equal > 0)
|
|
{
|
|
bool disable = TRUE;
|
|
TToken_string mod(line.mid(equal+1, -1), ',');
|
|
FOR_EACH_TOKEN(mod, cod)
|
|
{
|
|
const int code = atoi(cod);
|
|
if (code == 0 || main_app().has_module(code))
|
|
{
|
|
disable = FALSE;
|
|
break;
|
|
}
|
|
}
|
|
if (disable)
|
|
_enabled = FALSE;
|
|
}
|
|
} else
|
|
if (line.compare("Picture", 7, TRUE) == 0)
|
|
{
|
|
// Estrae solamente il nome del file immagine, elimina path ed estensione
|
|
TFilename name;
|
|
get_next_string(line, 8, name, brace);
|
|
xvt_fsys_parse_pathname(name, NULL, NULL, _picture.get_buffer(), NULL, NULL);
|
|
} else
|
|
if (line.compare("Flags", 5, TRUE) == 0)
|
|
{
|
|
TString16 flags;
|
|
get_next_string(line, 6, flags, brace);
|
|
if (flags.find('D') >= 0)
|
|
_enabled = FALSE;
|
|
if (flags.find('F') >= 0)
|
|
_firm = TRUE;
|
|
} else
|
|
if (line.compare("Item", 4, TRUE) == 0)
|
|
{
|
|
TMenuitem* item = new TMenuitem(this);
|
|
add(item);
|
|
item->create(line);
|
|
}
|
|
}
|
|
}
|
|
|
|
int TSubmenu::find_string(const TString& str) const
|
|
{
|
|
bool found = FALSE;
|
|
|
|
TString caption;
|
|
caption = _caption; caption.upper();
|
|
if (caption.find(str) >= 0 || caption.match(str))
|
|
found = TRUE;
|
|
|
|
for (int i = 0; i < items(); i++)
|
|
{
|
|
const TMenuitem& mi = item(i);
|
|
caption = item(i).caption();
|
|
caption.upper();
|
|
const bool match = caption.find(str) >= 0 || caption.match(str);
|
|
found = match && mi.is_program() && mi.enabled();
|
|
if (found)
|
|
return i;
|
|
}
|
|
|
|
return found ? 0 : -1;
|
|
}
|
|
|
|
int TSubmenu::find(const TMenuitem& it) const
|
|
{
|
|
int i;
|
|
for (i = items()-1; i >= 0; i--)
|
|
{
|
|
const TMenuitem& mi = item(i);
|
|
if (mi.action() == it.action())
|
|
break;
|
|
}
|
|
return i;
|
|
}
|
|
|
|
TImage& TSubmenu::image() const
|
|
{
|
|
return menu().image(picture());
|
|
}
|
|
|
|
bool TSubmenu::perform(int i)
|
|
{
|
|
bool ok = i >= 0 && i < items();
|
|
if (ok)
|
|
ok = item(i).perform();
|
|
return ok;
|
|
}
|
|
|
|
bool TMenu::read(const char* name, TString& root)
|
|
{
|
|
TString str(255);
|
|
bool first = TRUE;
|
|
|
|
TFilename menuname = name;
|
|
menuname.custom_path();
|
|
TScanner scanner(menuname);
|
|
while (scanner.ok())
|
|
{
|
|
const TString& line = first ? scanner.line() : scanner.pop();
|
|
if (line.empty())
|
|
break;
|
|
|
|
char brace = '[';
|
|
get_next_string(line, 0, str, brace);
|
|
|
|
if (first)
|
|
{
|
|
root = str;
|
|
first = FALSE;
|
|
}
|
|
|
|
if (objptr(str) == NULL)
|
|
{
|
|
TSubmenu* mnu = new TSubmenu(this, str);
|
|
mnu->read(scanner);
|
|
add(str, mnu);
|
|
}
|
|
else
|
|
break; // Menu gia' caricato!
|
|
}
|
|
|
|
return first == FALSE;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// Menu
|
|
///////////////////////////////////////////////////////////
|
|
|
|
|
|
bool TMenu::read(const char* name)
|
|
{
|
|
TString root;
|
|
bool ok = read(name, root);
|
|
if (ok && _current == NULL)
|
|
{
|
|
_default_menu = root;
|
|
_current = find(root);
|
|
_item = 0;
|
|
}
|
|
return ok;
|
|
}
|
|
|
|
bool TMenu::set_firm(long firm) const
|
|
{
|
|
if (firm <= 0)
|
|
{
|
|
TRelation rel(LF_NDITTE);
|
|
TCursor cur(&rel);
|
|
if (cur.items() == 1)
|
|
{
|
|
cur = 0L;
|
|
firm = rel.curr().get_long("CODDITTA");
|
|
}
|
|
}
|
|
return main_app().set_firm(firm);
|
|
}
|
|
|
|
bool TMenu::jumpto(TSubmenu* next)
|
|
{
|
|
if (next && next->disabled())
|
|
next = NULL;
|
|
|
|
if (next)
|
|
{
|
|
if (next->query_firm())
|
|
{
|
|
#ifdef _DEMO_
|
|
if (!set_firm(1))
|
|
next = NULL;
|
|
#else
|
|
if (!set_firm(0))
|
|
next = NULL;
|
|
#endif
|
|
}
|
|
if (next)
|
|
{
|
|
if (_stack.count() >= 32)
|
|
_stack.destroy_base();
|
|
_stack.push(_current->name());
|
|
_current = next;
|
|
_item = 0;
|
|
}
|
|
}
|
|
|
|
return next != NULL;
|
|
}
|
|
|
|
bool TMenu::jumpto_root()
|
|
{
|
|
TSubmenu* sm = find(_default_menu);
|
|
return jumpto(sm);
|
|
}
|
|
|
|
TSubmenu& TMenu::pop()
|
|
{
|
|
TSubmenu* sm = _current;
|
|
if (!at_top())
|
|
{
|
|
TString& name = (TString&)_stack.pop();
|
|
sm = (TSubmenu*)objptr(name);
|
|
}
|
|
if (sm)
|
|
{
|
|
_current = sm;
|
|
_item = 0;
|
|
}
|
|
return *sm;
|
|
}
|
|
|
|
TSubmenu* TMenu::find_string(const TString& str)
|
|
{
|
|
TString upstr(str);
|
|
upstr.upper();
|
|
|
|
if (_last_search != upstr)
|
|
{
|
|
_last_search = upstr;
|
|
_ignore_list.destroy();
|
|
}
|
|
|
|
restart();
|
|
for (TSubmenu* sm = (TSubmenu*)get(); sm; sm = (TSubmenu*)get())
|
|
{
|
|
if (sm->enabled() && !_ignore_list.is_key(sm->name()))
|
|
{
|
|
const int item = sm->find_string(upstr);
|
|
if (item >= 0)
|
|
{
|
|
jumpto(sm);
|
|
_item = item;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (sm != NULL)
|
|
_ignore_list.add(sm->name());
|
|
else
|
|
_ignore_list.destroy();
|
|
|
|
return sm;
|
|
}
|
|
|
|
TSubmenu* TMenu::find_parent(const TSubmenu& sub)
|
|
{
|
|
restart();
|
|
for (TSubmenu* sm = (TSubmenu*)get(); sm; sm = (TSubmenu*)get())
|
|
{
|
|
for (int i = sm->items()-1; i >= 0; i--)
|
|
{
|
|
const TMenuitem& mi = sm->item(i);
|
|
if (mi.is_submenu() && mi.action().find(sub.name()) >= 0)
|
|
break;
|
|
}
|
|
}
|
|
return sm;
|
|
}
|
|
|
|
bool TMenu::perform()
|
|
{
|
|
bool ok = _current != NULL;
|
|
if (ok)
|
|
ok = _current->perform(_item);
|
|
return ok;
|
|
}
|
|
|
|
bool TMenu::can_be_transparent(const TImage& i) const
|
|
{
|
|
const int w = i.width()-1;
|
|
const int h = i.height()-1;
|
|
const COLOR col = i.get_pixel(0,0);
|
|
if (i.get_pixel(w,0) != col)
|
|
return FALSE;
|
|
if (i.get_pixel(w,h) != col)
|
|
return FALSE;
|
|
if (i.get_pixel(0,h) != col)
|
|
return FALSE;
|
|
return TRUE;
|
|
}
|
|
|
|
TImage& TMenu::image(const char* name)
|
|
{
|
|
TTimed_image* image = (TTimed_image*)_images.objptr(name);
|
|
if (image == NULL)
|
|
{
|
|
TFilename realname;
|
|
const char* ext[3] = { "jpg", "gif", "bmp" };
|
|
for (int i = 0; i < 3; i++)
|
|
{
|
|
realname = name;
|
|
realname << '.' << ext[i];
|
|
realname.custom_path();
|
|
if (realname.exist())
|
|
break;
|
|
}
|
|
if (realname.exist())
|
|
{
|
|
if (_images.items() == 0)
|
|
_default_bmp = name; // Store default bitmap name
|
|
|
|
image = new TTimed_image(realname);
|
|
if (can_be_transparent(*image))
|
|
image->convert_transparent_color(MASK_BACK_COLOR);
|
|
_images.add(name, image);
|
|
}
|
|
else
|
|
{
|
|
image = (TTimed_image*)_images.objptr(_default_bmp);
|
|
if (image == NULL)
|
|
fatal_box(FR("Impossibile trovare l'immagine %s"), (const char*)_default_bmp);
|
|
}
|
|
|
|
if (_images.items() > 3)
|
|
{
|
|
TString worst_bmp;
|
|
clock_t worst_time = image->touch(); // Impedisco di cancellare la prossima
|
|
_images.restart();
|
|
for (THash_object* o = _images.get_hashobj(); o; o = _images.get_hashobj())
|
|
{
|
|
if (o->key() != _default_bmp)
|
|
{
|
|
TTimed_image& i = (TTimed_image&)o->obj();
|
|
if (i.last_time() < worst_time)
|
|
{
|
|
worst_time = i.last_time();
|
|
worst_bmp = o->key();
|
|
}
|
|
}
|
|
}
|
|
_images.remove(worst_bmp);
|
|
}
|
|
}
|
|
image->touch();
|
|
return *image;
|
|
}
|
|
|
|
void TMenu::reload_images()
|
|
{
|
|
_images.destroy();
|
|
}
|
|
|
|
bool TMenu::has_module(const char* mod)
|
|
{
|
|
TString16 key;
|
|
|
|
if (_modules.items() == 0)
|
|
{
|
|
TScanner scanner(AUT_FILE);
|
|
TString16 val;
|
|
for (int aut = 0; scanner.line() != ""; aut++)
|
|
{
|
|
key.strncpy(scanner.token(), 2);
|
|
key.lower();
|
|
val.format("%d", aut);
|
|
_modules.add(key, val);
|
|
}
|
|
}
|
|
|
|
key.strncpy(mod, 2);
|
|
key.lower();
|
|
|
|
int module = 0;
|
|
TString* cod = (TString*)_modules.objptr(key);
|
|
if (cod) module = atoi(*cod);
|
|
return main_app().has_module(module);
|
|
}
|
|
|
|
bool TMenu::is_dangerous(const char* mod)
|
|
{
|
|
TString code(mod);
|
|
code.cut(2);
|
|
return _dangerous.get_pos(code) >= 0;
|
|
}
|
|
|
|
TMenu::TMenu() : _current(NULL), _item(0)
|
|
{ }
|
|
|
|
TMenu::~TMenu()
|
|
{ }
|