Files correlati : ba0.exe Commento : Corretto cambio studio quando da un codice ditta presente in quello studio ad un altro studio dove quel codice ditta non esiste. Ora la ditta viene richiesta quando nello studio di destinazione ce n'è più di una. git-svn-id: svn://10.65.10.50/branches/R_10_00@23390 c028cbd2-c16b-5b4b-a496-9718f37d4682
2507 lines
62 KiB
C++
Executable File
2507 lines
62 KiB
C++
Executable File
#include <applicat.h>
|
||
#include <automask.h>
|
||
#include <controls.h>
|
||
#include <config.h>
|
||
#include <dongle.h>
|
||
#include <execp.h>
|
||
#include <recarray.h>
|
||
#include <relation.h>
|
||
#include <progind.h>
|
||
#include <sheet.h>
|
||
#include <toolfld.h>
|
||
#include <utility.h>
|
||
#include <urldefid.h>
|
||
|
||
#include <nditte.h>
|
||
#include <user.h>
|
||
|
||
#include "ba0.h"
|
||
#include "ba0101.h"
|
||
#include "ba0102.h"
|
||
#include "ba0103.h"
|
||
#include "ba0100.h"
|
||
|
||
#include "ba0100a.h"
|
||
#include "ba0400a.h"
|
||
|
||
#define MEN_FILE "bamenu.men"
|
||
#define PREFERRED_MENU M_STYLE
|
||
|
||
#define DLG_TREE 301
|
||
#define DLG_LIST 302
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// TMenu_application declaration
|
||
///////////////////////////////////////////////////////////
|
||
|
||
class TMenu_application : public TSkeleton_application
|
||
{
|
||
TFilename _menuname;
|
||
|
||
TMenu _menu;
|
||
int _tree_view;
|
||
TString_array _preferred;
|
||
|
||
TMask* _mask;
|
||
|
||
protected: // TApplication
|
||
virtual bool user_create();
|
||
virtual bool destroy();
|
||
virtual bool menu(MENU_TAG m);
|
||
virtual long handler(WINDOW win, EVENT* ep);
|
||
virtual bool firm_change_enabled() const;
|
||
virtual void on_firm_change();
|
||
virtual bool test_assistance_year() const;
|
||
|
||
bool test_users_file() const;
|
||
bool ask_user_password(TString& utente);
|
||
|
||
protected:
|
||
void deconnect_user();
|
||
virtual void main_loop();
|
||
|
||
void test_temp();
|
||
int do_level();
|
||
// int do_tree(); // Deprecated
|
||
int do_explore();
|
||
int do_outlook();
|
||
int do_metro();
|
||
|
||
int get_user_status(const char* usr) const;
|
||
bool set_user_status(const char* usr, int status) const;
|
||
bool check_user();
|
||
|
||
static bool menu_item_handler(TMask_field& f, KEY k);
|
||
static bool menu_find_handler(TMask_field& f, KEY k);
|
||
static bool tree_handler(TMask_field& f, KEY k);
|
||
static bool explore_handler(TMask_field& f, KEY k);
|
||
|
||
bool choose_colors();
|
||
bool choose_editors();
|
||
bool choose_study();
|
||
|
||
void load_preferences();
|
||
void save_preferences();
|
||
void update_preferred_tree();
|
||
void update_preferred();
|
||
void add_to_preferred();
|
||
void manage_preferred();
|
||
void manage_mail();
|
||
|
||
bool dongle_update_needed() const;
|
||
bool test_programs();
|
||
bool copy_setup(const TString& remote_path);
|
||
|
||
public:
|
||
TTree_field& tree_field() const;
|
||
void select_tree_current();
|
||
static bool tree_find_handler(TMask_field& f, KEY k);
|
||
static bool tree_shrink_handler(TMask_field& f, KEY k);
|
||
|
||
public:
|
||
void reload_images();
|
||
TMenu& main_menu() { return _menu; }
|
||
|
||
TMenu_application(const char* name);
|
||
};
|
||
|
||
inline TMenu_application& app()
|
||
{ return (TMenu_application&)main_app(); }
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// Picture Mask
|
||
///////////////////////////////////////////////////////////
|
||
|
||
class TPicture_mask : public TMask
|
||
{
|
||
TSubmenu* _submenu;
|
||
TImage* _logo;
|
||
|
||
protected: // TMask
|
||
virtual void update();
|
||
virtual bool on_key(KEY k);
|
||
virtual void on_firm_change();
|
||
|
||
public:
|
||
virtual bool stop_run(KEY key);
|
||
void set_current(const TSubmenu& sm);
|
||
|
||
TPicture_mask(const char* name, int dx, int dy, const TSubmenu& sm, int x = -1, int y = -1);
|
||
virtual ~TPicture_mask();
|
||
};
|
||
|
||
bool TPicture_mask::stop_run(KEY key)
|
||
{
|
||
if (key == K_FORCE_CLOSE)
|
||
key = K_QUIT;
|
||
return TWindow::stop_run(key);
|
||
}
|
||
|
||
void TPicture_mask::update()
|
||
{
|
||
if (!ADVANCED_GRAPHICS)
|
||
return;
|
||
|
||
RCT client; xvt_vobj_get_client_rect(win(), &client);
|
||
RCT lgo = client, img = client;
|
||
|
||
const bool tree_view = id2pos(DLG_TREE) >= 0;
|
||
if (tree_view) // TreeView == 1
|
||
{
|
||
RCT tree; tfield(DLG_TREE).get_rect(tree);
|
||
lgo.left = tree.right; lgo.bottom /= 3;
|
||
img.left = tree.right; img.top = lgo.bottom; img.bottom = 2*lgo.bottom;
|
||
}
|
||
else
|
||
{
|
||
RCT but; field(101).get_rect(but);
|
||
lgo.right = but.left; lgo.bottom /= 2;
|
||
img.right = but.left; img.top = lgo.bottom;
|
||
}
|
||
|
||
if (_logo != NULL)
|
||
{
|
||
xvt_rect_inflate(&lgo, -CHARX, -CHARX);
|
||
_logo->draw(win(), lgo, 'C', 'T', '-');
|
||
}
|
||
|
||
const TImage& image = _submenu->image();
|
||
if (image.ok())
|
||
{
|
||
xvt_rect_inflate(&img, -CHARX, -CHARX);
|
||
image.draw(win(), img, 'C', 'C', '-');
|
||
}
|
||
}
|
||
|
||
bool TPicture_mask::on_key(KEY k)
|
||
{
|
||
switch (k)
|
||
{
|
||
case K_F3:
|
||
case K_F8:
|
||
set(DLG_USER, app().main_menu().last_search_string(), true);
|
||
return true;
|
||
default:
|
||
break;
|
||
}
|
||
|
||
return TMask::on_key(k);
|
||
}
|
||
|
||
void TPicture_mask::on_firm_change()
|
||
{
|
||
force_update();
|
||
}
|
||
|
||
void TPicture_mask::set_current(const TSubmenu& sm)
|
||
{
|
||
_submenu = (TSubmenu*)&sm;
|
||
}
|
||
|
||
TPicture_mask::TPicture_mask(const char* name, int dx, int dy,
|
||
const TSubmenu& submenu, int x, int y)
|
||
: TMask(name, 1, dx, dy, x, y), _submenu(NULL), _logo(NULL)
|
||
{
|
||
set_current(submenu);
|
||
|
||
//trova il logo corretto in base al producer
|
||
const TString& currlogo = get_logo();
|
||
_logo = new TImage(currlogo);
|
||
|
||
if (_logo->ok())
|
||
{
|
||
if (can_be_transparent(*_logo))
|
||
_logo->convert_transparent_color(MASK_BACK_COLOR);
|
||
}
|
||
else
|
||
{
|
||
delete _logo;
|
||
_logo = NULL;
|
||
}
|
||
}
|
||
|
||
TPicture_mask::~TPicture_mask()
|
||
{
|
||
if (_logo != NULL)
|
||
delete _logo;
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// Color Mask
|
||
///////////////////////////////////////////////////////////
|
||
|
||
class TColor_mask : public TAutomask
|
||
{
|
||
class TPreview_panel : public TWindow
|
||
{
|
||
TColor_mask* _owner;
|
||
protected:
|
||
COLOR get_color_entry(const char* name) const;
|
||
virtual void update();
|
||
virtual PNT log2dev(long x, long y) const { PNT p = { short(ROWY*y), short(CHARX*x) }; return p; }
|
||
virtual void log2dev(const TRectangle& rctl, RCT& r) const
|
||
{
|
||
r.left = short(rctl.x*CHARX);
|
||
r.top = short(rctl.y*ROWY);
|
||
r.right = short(r.left + rctl.width()*CHARX);
|
||
r.bottom = short(r.top + rctl.height()*ROWY);
|
||
if (rctl.height() > 0)
|
||
r.bottom -= ROWY-CHARY;
|
||
}
|
||
public:
|
||
TPreview_panel(short x, short y, short dx, short dy, TColor_mask* owner);
|
||
} *_preview;
|
||
|
||
class TPreview_icons : public TWindow
|
||
{
|
||
TColor_mask* _owner;
|
||
protected:
|
||
virtual void update();
|
||
public:
|
||
TPreview_icons(short x, short y, short dx, short dy, TColor_mask* owner);
|
||
} *_icons;
|
||
|
||
int _cur_theme;
|
||
TAssoc_array _color;
|
||
|
||
protected: // TMask
|
||
virtual bool stop_run(KEY key) { return TWindow::stop_run(key); }
|
||
virtual bool on_field_event(TOperable_field& f, TField_event e, long jolly);
|
||
|
||
TProp_field& colors_field() const;
|
||
TProp_field& options_field() const;
|
||
|
||
void colors2mask();
|
||
void mask2colors();
|
||
void options2mask();
|
||
void mask2options();
|
||
void enable_options();
|
||
|
||
protected:
|
||
COLOR get_color_entry(const char* c) const;
|
||
void set_color_entry(const char* name, COLOR col);
|
||
const TString& get_font_desc() const;
|
||
void set_font_desc(const TString& fd);
|
||
const char* cid2name(short cid) const;
|
||
COLOR cid2color(short cid) const;
|
||
COLOR cid2syscolor(short cid, const XVT_COLOR_COMPONENT* cc) const;
|
||
|
||
bool find_themes_ini(TFilename& ininame) const;
|
||
void load_themes();
|
||
bool apply_theme();
|
||
|
||
void save_colors(TConfig& colors);
|
||
|
||
public:
|
||
void save_colors();
|
||
TColor_mask();
|
||
};
|
||
|
||
COLOR TColor_mask::TPreview_panel::get_color_entry(const char* name) const
|
||
{ return _owner->get_color_entry(name); }
|
||
|
||
TColor_mask::TPreview_panel::TPreview_panel(short x, short y, short dx, short dy, TColor_mask* owner)
|
||
: _owner(owner)
|
||
{ create(x, y, dx, dy, "", 0, W_PLAIN, owner->page_win(0)); }
|
||
|
||
void TColor_mask::TPreview_panel::update()
|
||
{
|
||
COLOR p, b;
|
||
|
||
const int x = 0;
|
||
const int y = 0;
|
||
const int w = columns();
|
||
const int h = rows();
|
||
|
||
b = get_color_entry("MaskBack");
|
||
clear(b);
|
||
|
||
set_pen(p = get_color_entry("MaskLight"));
|
||
line(x+1, y, x+w-2, y);
|
||
line(x+1, y, x+1, y+h-1);
|
||
|
||
set_pen(p = get_color_entry("MaskDark"));
|
||
line(x+1, y+h-1, x+w-2, y+h-1);
|
||
line(x+w-2, y+h-1, x+w-2, y);
|
||
|
||
const TString& font_desc = _owner->get_font_desc();
|
||
if (font_desc.full())
|
||
{
|
||
XVT_FNTID fontid = xvt_font_create();
|
||
xvt_font_deserialize(fontid, font_desc);
|
||
xvt_dwin_set_font(win(), fontid);
|
||
xvt_font_destroy(fontid);
|
||
}
|
||
else
|
||
xvt_dwin_set_font(win(), xvtil_default_font());
|
||
|
||
set_opaque_text(false);
|
||
|
||
p = get_color_entry("Prompt");
|
||
b = get_color_entry("MaskBack");
|
||
set_color(p, b);
|
||
stringat(x+4, y+0, TR("Prompt"));
|
||
|
||
set_pen(p = get_color_entry("Normal"));
|
||
set_brush(b = get_color_entry("NormalBack"));
|
||
frame(x+3, y+1, x+w-3, y+2, 0);
|
||
set_color(p, b);
|
||
stringat(x+4, y+1, TR("Campo normale"));
|
||
|
||
set_pen(p = get_color_entry("Normal")); // Stesso inchiostro del normale
|
||
set_brush(b = get_color_entry("RequiredBack"));
|
||
frame(x+3, y+2, x+w-3, y+3, 0);
|
||
set_color(p, b);
|
||
stringat(x+4, y+2, TR("Campo obbligatorio"));
|
||
|
||
set_pen(p = get_color_entry("Focus"));
|
||
set_brush(b = get_color_entry("FocusBack"));
|
||
frame(x+3, y+3, x+w-3, y+4, 0);
|
||
set_color(p, b);
|
||
stringat(x+4, y+3, TR("Campo attivo"));
|
||
|
||
set_pen(p = get_color_entry("Disabled"));
|
||
set_brush(b = get_color_entry("DisabledBack"));
|
||
frame(x+3, y+4, x+w-3, y+5, 0);
|
||
set_color(p, b);
|
||
stringat(x+4, y+4, TR("Campo disabilitato"));
|
||
|
||
set_pen(p = get_color_entry("ButtonLight"));
|
||
set_brush(b = get_color_entry("ButtonBack"));
|
||
frame(x+3, y+5, x+w-3, y+6, 0);
|
||
set_color(get_color_entry("Normal"), b);
|
||
stringat(x+4, y+5, TR("Bottone normale"));
|
||
}
|
||
|
||
void TColor_mask::TPreview_icons::update()
|
||
{
|
||
RCT rct; xvt_vobj_get_client_rect(win(), &rct);
|
||
clear(MASK_BACK_COLOR);
|
||
set_pen(MASK_DARK_COLOR);
|
||
xvt_dwin_draw_rect(win(), &rct);
|
||
|
||
const int s = _owner->get_int(218);
|
||
const int sz = 16 + s*8;
|
||
const int y = (rct.bottom - sz)/2;
|
||
int x = (rct.right - 3*sz)/2;
|
||
for (short id = 201; id <= 203; id++, x += sz)
|
||
xvt_dwin_draw_tool(win(), x, y, id, sz);
|
||
}
|
||
|
||
TColor_mask::TPreview_icons::TPreview_icons(short x, short y, short dx, short dy, TColor_mask* owner)
|
||
: _owner(owner)
|
||
{ create(x, y, dx, dy, "", 0, W_PLAIN, owner->page_win(1)); }
|
||
|
||
void TColor_mask::load_themes()
|
||
{
|
||
TList_field& fl = lfield(211);
|
||
|
||
TToken_string codes = fl.get_codes();
|
||
TToken_string values = fl.get_values();
|
||
|
||
const int default_items = 3; // Corrente, Tradizionale, Sistema
|
||
// Elimina tutti gli elementi non standard (oltre il terzo)
|
||
if (codes.items() > default_items)
|
||
{
|
||
for (int i = 0; i < 2; i++)
|
||
{
|
||
TToken_string& str = i == 0 ? codes : values;
|
||
int pos = 0;
|
||
for (int j = 0; j < default_items; j++)
|
||
pos = str.find(str.separator(), pos);
|
||
str.cut(pos);
|
||
}
|
||
}
|
||
|
||
int k = codes.items();
|
||
|
||
TFilename ininame; find_themes_ini(ininame);
|
||
TConfig default_themes(ininame);
|
||
TString_array pl;
|
||
default_themes.list_paragraphs(pl);
|
||
FOR_EACH_ARRAY_ROW(pl, i, row)
|
||
{
|
||
codes.add(k++);
|
||
values.add(row->left(15));
|
||
}
|
||
|
||
TConfig user_themes(CONFIG_GUI, "Colors");
|
||
user_themes.list_paragraphs(pl);
|
||
FOR_EACH_ARRAY_ROW(pl, j, raw)
|
||
{
|
||
if (raw->starts_with("Theme_"))
|
||
{
|
||
codes.add(k++);
|
||
values.add(raw->mid(6, 15));
|
||
}
|
||
}
|
||
|
||
if (k > default_items)
|
||
fl.replace_items(codes, values);
|
||
}
|
||
|
||
bool TColor_mask::find_themes_ini(TFilename& ininame) const
|
||
{
|
||
ininame = get_oem_info("Themes");
|
||
bool ok = ininame.full();
|
||
if (ok)
|
||
{
|
||
ininame.insert("setup/");
|
||
ok = ininame.exist();
|
||
if (!ok)
|
||
{
|
||
ininame = "res/themes.ini"; // Compatibility mode
|
||
ok = ininame.exist();
|
||
}
|
||
}
|
||
return ok;
|
||
}
|
||
|
||
void TColor_mask::colors2mask()
|
||
{
|
||
TProp_field& pg = colors_field();
|
||
pg.freeze(true);
|
||
FOR_EACH_ASSOC_STRING(_color, h, key, color)
|
||
{
|
||
const TFixed_string str(color);
|
||
if (str.find(',') > 0) // E' una proprieta' colore?
|
||
pg.set_property(key, color);
|
||
}
|
||
pg.freeze(false);
|
||
_preview->force_update();
|
||
}
|
||
|
||
void TColor_mask::mask2colors()
|
||
{
|
||
const TProp_field& pg = colors_field();
|
||
FOR_EACH_ASSOC_STRING(_color, h, key, color)
|
||
{
|
||
const TFixed_string str(color);
|
||
if (str.find(',') > 0) // E' una proprieta' colore?
|
||
{
|
||
const COLOR rgb = pg.get_color_property(key);
|
||
if (rgb != COLOR_INVALID)
|
||
set_color_entry(key, rgb);
|
||
}
|
||
}
|
||
_preview->force_update();
|
||
}
|
||
|
||
TProp_field& TColor_mask::colors_field() const
|
||
{ return (TProp_field&)field(212); }
|
||
|
||
TProp_field& TColor_mask::options_field() const
|
||
{ return (TProp_field&)field(213); }
|
||
|
||
bool TColor_mask::apply_theme()
|
||
{
|
||
bool applied = false;
|
||
|
||
const int theme = get_int(211);
|
||
if (theme > 2) // Normal theme
|
||
{
|
||
const TList_field& fl = lfield(211);
|
||
TToken_string values = fl.get_values();
|
||
|
||
TString name = values.get(theme);
|
||
|
||
TFilename thini; find_themes_ini(thini);
|
||
TConfig def_themes(thini, name);
|
||
TAssoc_array& def_colors = def_themes.list_variables();
|
||
|
||
name.insert("Theme_");
|
||
TConfig usr_themes(CONFIG_GUI, name);
|
||
TAssoc_array& usr_colors = usr_themes.list_variables();
|
||
|
||
TAssoc_array& colors = usr_colors.empty() ? def_colors : usr_colors;
|
||
if (!colors.empty())
|
||
{
|
||
_color = colors;
|
||
FOR_EACH_MASK_FIELD((*this), i, f)
|
||
{
|
||
const TFieldref* fr = f->field();
|
||
if (fr != NULL)
|
||
{
|
||
const TString* val = (const TString*)_color.objptr(fr->name());
|
||
if (val != NULL)
|
||
f->set(*val);
|
||
}
|
||
}
|
||
applied = true;
|
||
}
|
||
}
|
||
|
||
if (!applied)
|
||
{
|
||
switch (theme)
|
||
{
|
||
case 1: // Campo default colors
|
||
{
|
||
for (short bid = 101; bid <= 114; bid++)
|
||
{
|
||
const char* name = cid2name(bid);
|
||
const COLOR color = cid2color(bid);
|
||
set_color_entry(name, color);
|
||
}
|
||
set_font_desc("");
|
||
applied = true;
|
||
}
|
||
break;
|
||
case 2: // System colors
|
||
{
|
||
const XVT_COLOR_COMPONENT* cc = (XVT_COLOR_COMPONENT*)xvt_vobj_get_attr(NULL_WIN, ATTR_APP_CTL_COLORS);
|
||
for (short bid = 101; bid <= 114; bid++)
|
||
{
|
||
const char* name = cid2name(bid);
|
||
const COLOR color = cid2syscolor(bid, cc);
|
||
set_color_entry(name, color);
|
||
}
|
||
xvt_mem_free((DATA_PTR)cc);
|
||
|
||
XVT_FNTID defont = xvtil_default_font(false, false); // Legge il font standard
|
||
XVT_FNTID fontid = xvt_res_get_font(0); // Legge il font di sistema
|
||
xvt_font_set_size(fontid, xvt_font_get_size(defont)); // Forza l'altezza standard
|
||
TString256 fd; xvt_font_serialize(fontid, fd.get_buffer(), fd.size());
|
||
set_font_desc(fd);
|
||
xvt_font_destroy(fontid); // Rilascia il font di sistema
|
||
|
||
TProp_field& pf = options_field();
|
||
pf.set_property("Campi3D", xvt_sys_get_os_version() != XVT_WS_WIN_10);
|
||
pf.set_property("NativeControls", true);
|
||
applied = true;
|
||
}
|
||
break;
|
||
default: // User defined settings
|
||
{
|
||
TConfig color(CONFIG_GUI, "Colors");
|
||
_color = color.list_variables();
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (applied)
|
||
_cur_theme = theme;
|
||
colors2mask();
|
||
|
||
return applied;
|
||
}
|
||
|
||
bool TColor_mask::on_field_event(TOperable_field& f, TField_event e, long jolly)
|
||
{
|
||
const short id = f.dlg();
|
||
bool ok = true;
|
||
|
||
switch (id)
|
||
{
|
||
case 211:
|
||
if (e == fe_init)
|
||
load_themes();
|
||
if (e == fe_modify && is_running())
|
||
{
|
||
const int new_theme = atoi(f.get());
|
||
if (new_theme != _cur_theme)
|
||
apply_theme();
|
||
}
|
||
break;
|
||
case DLG_OK:
|
||
if (e == fe_button)
|
||
{
|
||
stop_run(K_CTRL+'R');
|
||
return false;
|
||
}
|
||
break;
|
||
case DLG_SAVEREC:
|
||
if (e == fe_button)
|
||
{
|
||
stop_run(K_ENTER);
|
||
return false;
|
||
}
|
||
break;
|
||
case DLG_NEWREC:
|
||
if (e == fe_button)
|
||
{
|
||
TString80 name = user();
|
||
xvt_dm_post_string_prompt(TR("Nome del tema"), name.get_buffer(), 16);
|
||
if (name.full())
|
||
{
|
||
name.trim();
|
||
name.upper();
|
||
name.insert("Theme_");
|
||
{
|
||
TConfig ini(CONFIG_GUI, name);
|
||
save_colors(ini);
|
||
}
|
||
load_themes();
|
||
}
|
||
return false;
|
||
}
|
||
break;
|
||
case DLG_DELREC:
|
||
if (e == fe_button)
|
||
{
|
||
TList_field& themes = lfield(211);
|
||
const int pos = atoi(themes.get());
|
||
bool can_delete = pos > 2;
|
||
if (can_delete) // Tema non standard
|
||
{
|
||
TToken_string values = themes.get_values();
|
||
TString name = values.get(pos);
|
||
bool done = yesno_box(FR("Confermare la cancellazione del tema %s"), name.get_buffer());
|
||
if (done)
|
||
{
|
||
name.insert("Theme_");
|
||
TConfig ini(CONFIG_GUI, name);
|
||
if (ini.new_paragraph())
|
||
done = can_delete = false;
|
||
else
|
||
ini.remove_all();
|
||
}
|
||
if (done)
|
||
load_themes();
|
||
}
|
||
if (!can_delete)
|
||
error_box(TR("Tema non cancellabile"));
|
||
return false;
|
||
}
|
||
break;
|
||
case DLG_USER:
|
||
if (e == fe_button)
|
||
{
|
||
XVT_FNTID fontid = xvt_font_create();
|
||
TString256 fd = get_font_desc();
|
||
if (fd.full())
|
||
xvt_font_deserialize(fontid, fd);
|
||
else
|
||
xvt_font_copy(fontid, xvtil_default_font(), XVT_FA_ALL);
|
||
if (xvt_dm_post_font_sel(win(), fontid, NULL, 0))
|
||
{
|
||
xvt_font_serialize(fontid, fd.get_buffer(), fd.size());
|
||
set_font_desc(fd);
|
||
_preview->force_update();
|
||
}
|
||
xvt_font_destroy(fontid);
|
||
return false;
|
||
}
|
||
break;
|
||
case 212:
|
||
if (e == fe_init)
|
||
colors2mask(); else
|
||
if (e == fe_modify)
|
||
mask2colors();
|
||
break;
|
||
case 213:
|
||
if (e == fe_init)
|
||
options2mask(); else
|
||
if (e == fe_modify)
|
||
{
|
||
mask2options();
|
||
enable_options();
|
||
}
|
||
break;
|
||
case 218:
|
||
if (e == fe_init || e == fe_modify)
|
||
_icons->force_update();
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
return ok;
|
||
}
|
||
|
||
void TColor_mask::enable_options()
|
||
{
|
||
TProp_field& pf = options_field();
|
||
pf.freeze(true);
|
||
const bool ag = pf.get_bool_property("AdvancedGraphics");
|
||
pf.enable_property("Campi3D", ag);
|
||
pf.enable_property("NativeControls", ag);
|
||
pf.enable_property("AnimatedBoxes", ag);
|
||
pf.freeze(false);
|
||
}
|
||
|
||
void TColor_mask::options2mask()
|
||
{
|
||
TProp_field& pf = options_field();
|
||
pf.freeze(true);
|
||
FOR_EACH_ASSOC_STRING(_color, obj, key, str) if (pf.has_property(key))
|
||
pf.set_property(key, str);
|
||
pf.freeze(false);
|
||
|
||
set(216, _color.get_int("TreeView"));
|
||
set(217, _color.get_int("InterLine"));
|
||
const int sz = _color.get_int("ToolSize");
|
||
set(218, (sz-16)/8);
|
||
enable_options();
|
||
}
|
||
|
||
void TColor_mask::mask2options()
|
||
{
|
||
TString4 val;
|
||
TProp_field& pf = options_field();
|
||
TVariant var;
|
||
FOR_EACH_ASSOC_STRING(_color, obj, key, str) if (pf.get_var_property(key, var))
|
||
{
|
||
if (var.is_bool())
|
||
{
|
||
val = var.as_bool() ? "X" : "";
|
||
_color.add(key, val, true);
|
||
}
|
||
}
|
||
|
||
val.cut(0) << get_int(216);
|
||
_color.add("TreeView", val, true);
|
||
|
||
val.cut(0) << get_int(217);
|
||
_color.add("InterLine", val, true);
|
||
|
||
val.cut(0) << (16+get_int(218)*8);
|
||
_color.add("ToolSize", val, true);
|
||
}
|
||
|
||
TColor_mask::TColor_mask()
|
||
: TAutomask("ba0200a"), _cur_theme(0)
|
||
{
|
||
TConfig color(CONFIG_GUI, "Colors");
|
||
_color = color.list_variables();
|
||
if (!_color.is_key("RunModal"))
|
||
_color.add("RunModal", empty_string());
|
||
|
||
_preview = new TPreview_panel(1, 12, -1, -1, this);
|
||
_icons = new TPreview_icons(1, 14, -2, -1, this);
|
||
}
|
||
|
||
void TColor_mask::save_colors(TConfig& colors)
|
||
{
|
||
mask2options(); // Si assicura che venga trasferito anche ToolSize, che non e' nel TPropField
|
||
FOR_EACH_ASSOC_STRING(_color, obj, key, str)
|
||
colors.set(key, str);
|
||
}
|
||
|
||
void TColor_mask::save_colors()
|
||
{
|
||
TConfig colors(CONFIG_GUI, "Colors");
|
||
save_colors(colors);
|
||
const bool full = colors.get_bool("RunModal");
|
||
TMenuitem::always_run_fullscreen(full);
|
||
}
|
||
|
||
const TString& TColor_mask::get_font_desc() const
|
||
{ return _color.get_str("FontDesc"); }
|
||
|
||
COLOR TColor_mask::get_color_entry(const char* name) const
|
||
{
|
||
COLOR c = COLOR_INVALID;
|
||
const TString& s = _color.get_str(name);
|
||
if (s.full())
|
||
{
|
||
TToken_string colore(s, ',');
|
||
const byte r = (byte)colore.get_int();
|
||
const byte g = (byte)colore.get_int();
|
||
const byte b = (byte)colore.get_int();
|
||
c = RGB2COLOR(r, g, b);
|
||
}
|
||
return c;
|
||
}
|
||
|
||
void TColor_mask::set_color_entry(const char* name, COLOR col)
|
||
{
|
||
TString* s = (TString*)_color.objptr(name);
|
||
if (s == NULL)
|
||
{
|
||
s = new TString(15);
|
||
_color.add(name, s);
|
||
}
|
||
s->format("%d,%d,%d", XVT_COLOR_GET_RED(col), XVT_COLOR_GET_GREEN(col), XVT_COLOR_GET_BLUE(col));
|
||
}
|
||
|
||
void TColor_mask::set_font_desc(const TString& fd)
|
||
{ _color.add("FontDesc", fd, true); }
|
||
|
||
const char* TColor_mask::cid2name(short cid) const
|
||
{
|
||
const int colors = 14;
|
||
const char* name[colors] = { "MaskBack", "MaskLight", "MaskDark",
|
||
"Normal", "NormalBack", "RequiredBack",
|
||
"Focus", "FocusBack",
|
||
"Disabled", "DisabledBack",
|
||
"ButtonBack", "ButtonLight", "ButtonDark",
|
||
"Prompt" };
|
||
const int i = cid < DLG_USER ? cid : cid - 101;
|
||
CHECK(i >= 0 && i < colors, "Invalid color id");
|
||
return name[i];
|
||
}
|
||
|
||
COLOR TColor_mask::cid2color(short cid) const
|
||
{
|
||
COLOR color[] = { XVT_MAKE_COLOR(201,194,188), COLOR_WHITE, COLOR_GRAY,
|
||
COLOR_BLACK, COLOR_WHITE, blend_colors(COLOR_WHITE, COLOR_YELLOW, 0.60),
|
||
COLOR_BLACK, COLOR_YELLOW,
|
||
COLOR_DKGRAY, COLOR_LTGRAY,
|
||
COLOR_LTGRAY, COLOR_WHITE, COLOR_GRAY,
|
||
COLOR_BLACK };
|
||
|
||
const int i = cid < DLG_USER ? cid : cid - 101;
|
||
CHECK(i >= 0 && i < 14, "Invalid color id");
|
||
return color[i];
|
||
}
|
||
|
||
COLOR TColor_mask::cid2syscolor(short cid, const XVT_COLOR_COMPONENT* cc) const
|
||
{
|
||
int entry[] = { XVT_COLOR_BACKGROUND, XVT_COLOR_BLEND, XVT_COLOR_BORDER,
|
||
XVT_COLOR_FOREGROUND, XVT_COLOR_BACKGROUND, XVT_COLOR_BACKGROUND,
|
||
XVT_COLOR_HIGHLIGHT, XVT_COLOR_SELECT,
|
||
XVT_COLOR_BLEND, XVT_COLOR_BORDER,
|
||
XVT_COLOR_BACKGROUND, XVT_COLOR_BLEND, XVT_COLOR_BORDER,
|
||
XVT_COLOR_FOREGROUND
|
||
};
|
||
const unsigned int component = entry[cid < DLG_USER ? cid : cid-101];
|
||
for (int i = 0; cc[i].type != XVT_COLOR_NULL; i++) if (cc[i].type == component)
|
||
{
|
||
switch (cid)
|
||
{
|
||
case 105: return COLOR_WHITE;
|
||
case 106: return blend_colors(cid2syscolor(105, cc), cid2syscolor(108, cc), 0.60);
|
||
default : return cc[i].color;
|
||
}
|
||
}
|
||
return COLOR_BLACK;
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// Menu application
|
||
///////////////////////////////////////////////////////////
|
||
|
||
bool TMenu_application::test_assistance_year() const
|
||
{ return true; }
|
||
|
||
bool TMenu_application::menu_item_handler(TMask_field&f, KEY k)
|
||
{
|
||
if (k == K_SPACE)
|
||
{
|
||
app()._menu.select(f.dlg()-101);
|
||
f.set_focusdirty(false);
|
||
return f.mask().stop_run(K_AUTO_ENTER);
|
||
}
|
||
return true;
|
||
}
|
||
|
||
bool TMenu_application::menu_find_handler(TMask_field&f, KEY k)
|
||
{
|
||
if (k == K_TAB && f.focusdirty() && !f.empty())
|
||
{
|
||
const TString& v = f.get();
|
||
if (app()._menu.find_string(v))
|
||
{
|
||
f.set_focusdirty(false);
|
||
return f.mask().stop_run(K_F9);
|
||
}
|
||
else
|
||
{
|
||
beep();
|
||
return false;
|
||
}
|
||
}
|
||
return true;
|
||
}
|
||
|
||
int TMenu_application::do_level()
|
||
{
|
||
const TSubmenu& curr = _menu.current();
|
||
const int bwidth = 20;
|
||
|
||
TPicture_mask mask(curr.caption(), 0, 0, curr, 0, 0);
|
||
CHECK(_mask == NULL, "Two masks are better than one?");
|
||
_mask = &mask;
|
||
|
||
const int ampiezza = 51;
|
||
const int margin = (mask.columns()-80) / 2;
|
||
const int x = mask.columns() - ampiezza - margin;
|
||
|
||
int y = 1;
|
||
|
||
TString caption;
|
||
for (int i = 0; i < curr.items() && i < 16; i++, y++)
|
||
{
|
||
const TMenuitem& item = curr[i];
|
||
caption = item.caption();
|
||
if (item.is_submenu() && caption.right(3) != "...")
|
||
caption << "...";
|
||
|
||
mask.add_static(-1, 0, caption, x+4, y);
|
||
const short id = 100+y;
|
||
const int bmp = item.is_submenu() ? BMP_DIRDN: BMP_STOPREC;
|
||
mask.add_button(id, 0, "", x, y, 1, 1, "", bmp);
|
||
|
||
mask.set_handler(id, menu_item_handler);
|
||
if (item.disabled())
|
||
mask.disable(id);
|
||
}
|
||
|
||
|
||
mask.add_static(DLG_NULL, 0, PR("Cerca"), x, -4);
|
||
|
||
TEdit_field& ef = mask.add_string(DLG_USER, 0, "", x, -3, 50, "", ampiezza - 2);
|
||
ef.set_handler(menu_find_handler);
|
||
|
||
const int bottone = ampiezza / 3;
|
||
const int spazio = (ampiezza - bottone * 2) / 3;
|
||
|
||
const bool top = _menu.at_top();
|
||
mask.add_button(DLG_QUIT, 0, PR("Fine"), x + spazio, -1, bottone, 2);
|
||
if (!top)
|
||
mask.add_button(DLG_CANCEL, 0, PR("Menu precedente"), x + spazio * 2 + bottone, -1, bottone, 2);
|
||
|
||
mask.first_focus(101+_menu.selected());
|
||
|
||
const int k = mask.run();
|
||
|
||
int m = 0;
|
||
switch (k)
|
||
{
|
||
case K_ESC:
|
||
_menu.pop();
|
||
m = -1;
|
||
break;
|
||
case K_QUIT:
|
||
mask.reset();
|
||
m = -2;
|
||
break;
|
||
case K_F9:
|
||
case K_CTRL+'R':
|
||
m = 0;
|
||
break;
|
||
default:
|
||
m = _menu.selected() + 1; // Sempre > 0
|
||
break;
|
||
}
|
||
|
||
// Azzero solo ora altrimenti il menu normale crede di non poter fare il cambio ditta
|
||
_mask = NULL;
|
||
|
||
return m;
|
||
}
|
||
|
||
|
||
void TMenu_application::test_temp()
|
||
{
|
||
TFilename dir; dir.tempdir(); // Directory temporanea
|
||
if (count_files(dir, true) > 20 && yesno_box(FR("Cancellare tutti i file temporanei in %s?"), (const char*)dir))
|
||
remove_files(dir, true);
|
||
}
|
||
|
||
HIDDEN bool pwd_handler(TMask_field& fld, KEY key)
|
||
{
|
||
if (key == K_F8)
|
||
{
|
||
TMask& m = fld.mask();
|
||
TString pwd;
|
||
TString usr = dongle().administrator(&pwd);
|
||
TLocalisamfile users(LF_USER);
|
||
users.put(USR_USERNAME, usr);
|
||
users.read();
|
||
pwd = decode(users.get(USR_PASSWORD));
|
||
m.set(F_USER, usr);
|
||
m.set(F_PASSWORD, pwd);
|
||
m.stop_run(K_ENTER);
|
||
}
|
||
return true;
|
||
}
|
||
|
||
HIDDEN bool user_mask_handler(TMask& mask, KEY key)
|
||
{
|
||
if (key == K_ENTER)
|
||
mask.stop_run(key);
|
||
return true;
|
||
}
|
||
|
||
void TMenu_application::reload_images()
|
||
{
|
||
_menu.reload_images();
|
||
}
|
||
|
||
bool TMenu_application::test_users_file() const
|
||
{
|
||
bool ok = prefix_valid();
|
||
if (ok)
|
||
{
|
||
TSystemisamfile users(LF_USER);
|
||
ok = users.open_ex() == NOERR;
|
||
if (ok)
|
||
users.close();
|
||
}
|
||
return ok;
|
||
}
|
||
|
||
bool TMenu_application::ask_user_password(TString& utente)
|
||
{
|
||
bool ok = false;
|
||
|
||
// Disabilita le voci di personalizzazione
|
||
enable_options_menu(false);
|
||
|
||
if (!test_users_file())
|
||
{
|
||
error_box(TR("Non e' possibile accedere al file degli utenti: necessita manutenzione"));
|
||
TExternal_app app("ba1 -0");
|
||
app.run(true, 1, false);
|
||
return ok; // False
|
||
}
|
||
|
||
TMask m("ba0100a");
|
||
m.set_handler(user_mask_handler);
|
||
|
||
if (is_power_station())
|
||
{
|
||
m.set_handler(F_USER, pwd_handler);
|
||
m.set_handler(F_PASSWORD, pwd_handler);
|
||
}
|
||
|
||
m.set(F_USER, utente);
|
||
m.first_focus(F_PASSWORD);
|
||
|
||
TEdit_field& e = m.efield(F_USER);
|
||
e.browse()->set_filter("ISGROUP!=\"X\"");
|
||
|
||
TLocalisamfile& users = e.browse()->cursor()->file();
|
||
|
||
TString pwd;
|
||
for (int i = 0; i < 3 && !ok; i++)
|
||
{
|
||
if (utente.not_empty() && utente != dongle().administrator())
|
||
{
|
||
m.set(F_USER, utente);
|
||
m.first_focus(F_PASSWORD);
|
||
}
|
||
|
||
if (m.run() == K_ESC)
|
||
break;
|
||
|
||
utente = m.get(F_USER);
|
||
TString pwd;
|
||
|
||
users.put(USR_USERNAME, utente);
|
||
if (users.read() == NOERR)
|
||
{
|
||
pwd = decode(users.get(USR_PASSWORD));
|
||
}
|
||
else
|
||
{
|
||
// Creo l'amministratore se necessario
|
||
users.zero();
|
||
if (utente == dongle().administrator(&pwd))
|
||
{
|
||
users.put(USR_USERNAME, utente);
|
||
users.put(USR_USERDESC, "Amministratore");
|
||
users.put(USR_PASSWORD, encode(pwd));
|
||
users.write();
|
||
}
|
||
else
|
||
utente.cut(0);
|
||
}
|
||
|
||
const TString& pass = m.get(F_PASSWORD);
|
||
ok = utente.full() && pwd == pass;
|
||
|
||
if (ok)
|
||
{
|
||
if (users.get_bool(USR_CONNECTED))
|
||
{
|
||
ok = yesno_box("%s\n%s",
|
||
TR("L'utente risulta essere gi<67> collegato"),
|
||
TR("Si desidera continuare ugualmente?"));
|
||
}
|
||
}
|
||
else
|
||
{
|
||
error_box(TR("Utente e/o password errata: fare attenzione alle maiuscole"));
|
||
m.reset(F_PASSWORD);
|
||
}
|
||
}
|
||
|
||
if (ok && users.curr().exist(USR_DATAPWD))
|
||
{
|
||
const long expiration = ini_get_int(CONFIG_STUDIO, "Main", "PasswordExpiration");
|
||
bool runba = expiration > 0;
|
||
while (runba)
|
||
{
|
||
runba = users.get(USR_PASSWORD).empty();
|
||
if (!runba)
|
||
{
|
||
const TDate oggi(TODAY);
|
||
const TDate datapwd = users.get_date(USR_DATAPWD);
|
||
if (datapwd.ok())
|
||
runba = expiration < (oggi-datapwd); // Password scaduta
|
||
else
|
||
{
|
||
// Scrivi la data se necessario
|
||
users.put(USR_DATAPWD, oggi);
|
||
users.rewrite();
|
||
}
|
||
}
|
||
if (runba)
|
||
{
|
||
warning_box(TR("E' necessario inserire una nuova password"));
|
||
user() = utente;
|
||
TExternal_app app("ba1 -3");
|
||
app.run();
|
||
users.reread();
|
||
}
|
||
}
|
||
}
|
||
|
||
// Abilita le voci di personalizzazione
|
||
enable_options_menu(true);
|
||
|
||
return ok;
|
||
}
|
||
|
||
// Testa stato utente: 0 inesistente; 1 = esiste; 2 connesso; 4 conversione in corso
|
||
// ATTENZIONE: non usare mai cache() in ba0!
|
||
int TMenu_application::get_user_status(const char* usr) const
|
||
{
|
||
CHECK(usr && *usr, "Utente nullo");
|
||
|
||
int status = 0;
|
||
if (test_users_file())
|
||
{
|
||
TLocalisamfile utonti(LF_USER);
|
||
utonti.put(USR_USERNAME, usr);
|
||
status = utonti.read() == NOERR;
|
||
if (status)
|
||
{
|
||
if (utonti.get_bool(USR_CONNECTED))
|
||
status |= 2;
|
||
if (dongle().administrator() == usr && utonti.get(USR_AUTSTR) == "CONVERTING")
|
||
status |= 4;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// Senza file aperti questo e' il massimo che posso fare
|
||
status = dongle().administrator() == usr;
|
||
}
|
||
|
||
return status;
|
||
}
|
||
|
||
bool TMenu_application::set_user_status(const char* usr, int status) const
|
||
{
|
||
CHECK(usr && *usr, "Utente nullo");
|
||
|
||
bool ok = false;
|
||
if (test_users_file())
|
||
{
|
||
TLocalisamfile utonti(LF_USER);
|
||
utonti.put(USR_USERNAME, usr);
|
||
if (utonti.read(_isequal, _lock) == NOERR)
|
||
{
|
||
utonti.put(USR_CONNECTED, status & 2 ? "X" : "");
|
||
ok = utonti.rewrite() == NOERR;
|
||
}
|
||
}
|
||
if (status & 2)
|
||
{
|
||
// Memorizza utente per riproporlo la prossima volta
|
||
TConfig campo_ini(CONFIG_INSTALL, "Main");
|
||
campo_ini.set("User", usr);
|
||
}
|
||
|
||
return ok;
|
||
}
|
||
|
||
|
||
bool TMenu_application::check_user()
|
||
{
|
||
bool ok = dongle().type() == _no_dongle;
|
||
if (!ok)
|
||
{
|
||
TString utente = user();
|
||
|
||
if (_mask == NULL) // Primo login della sessione;
|
||
{
|
||
TConfig campo_ini(CONFIG_INSTALL, "Main");
|
||
const bool use_system_user = campo_ini.get_bool("AutoLogin");
|
||
if (use_system_user && test_users_file())
|
||
ok = !cache().get(LF_USER, utente).empty();
|
||
}
|
||
|
||
if (!ok)
|
||
ok = ask_user_password(utente);
|
||
|
||
if (ok)
|
||
{
|
||
const TString& autstr = cache().get(LF_USER, dongle().administrator(), USR_AUTSTR);
|
||
if (autstr == "CONVERTING")
|
||
{
|
||
TString msg; msg << TR("E' in corso una conversione archivi") << ":\n";
|
||
if (utente == dongle().administrator())
|
||
{
|
||
msg << TR("Si desidera continuare ugualmente?");
|
||
ok = yesno_box(msg);
|
||
}
|
||
else
|
||
{
|
||
msg << TR("Accesso negato.");
|
||
ok = error_box(msg);
|
||
}
|
||
}
|
||
|
||
if (ok)
|
||
{
|
||
dongle().logout();
|
||
user() = utente;
|
||
ok = get_serial_number() >= 0;
|
||
if (!ok)
|
||
error_box(TR("Probabilmente <20> stato superato il numero massimo di utenti"));
|
||
}
|
||
|
||
if (ok)
|
||
set_user_status(utente, 3); // Esistente e connesso (1 | 2 = 3)
|
||
}
|
||
}
|
||
|
||
if (ok)
|
||
{
|
||
set_perms(); // Aggiorna permessi utente
|
||
customize_colors(); // Aggiorna set di colori
|
||
reload_images(); // Ritrasparentizza immagini e abilitazioni alberi
|
||
xvt_dwin_invalidate_rect(TASK_WIN, NULL); // Ridisegna sfondo
|
||
load_preferences(); // Aggiorna menu preferiti
|
||
test_temp(); // Cancella file temporanei
|
||
}
|
||
|
||
return ok;
|
||
}
|
||
|
||
HIDDEN int compare_version(const char* v1, int p1, const char* v2, int p2)
|
||
{
|
||
TString16 ver1(v1), ver2(v2);
|
||
ver1.trim();
|
||
if (ver1.len() == 4)
|
||
ver1.insert((v1[0] == '9') ? "19" : "20", 0);
|
||
ver2.trim();
|
||
if (ver2.len() == 4)
|
||
ver2.insert((v2[0] == '9') ? "19" : "20", 0);
|
||
|
||
int res = ver1.compare(ver2, -1, true);
|
||
if (res == 0)
|
||
res = p1 - p2;
|
||
|
||
return res;
|
||
}
|
||
|
||
static int get_module_version(TConfig& cfg, void* jolly)
|
||
{
|
||
const TString& p = cfg.get_paragraph();
|
||
if (p.len() == 2)
|
||
{
|
||
TAssoc_array& map = *(TAssoc_array*)jolly;
|
||
TToken_string* tok = new TToken_string(15);
|
||
*tok = cfg.get("Versione");
|
||
tok->add(cfg.get("Patch"));
|
||
map.add(p, tok);
|
||
}
|
||
return false;
|
||
}
|
||
|
||
bool TMenu_application::copy_setup(const TString& remote_path)
|
||
{
|
||
const TFixed_string local_setupdir("setup");
|
||
TFilename remote_setupdir = remote_path;
|
||
remote_setupdir.add(local_setupdir);
|
||
//controlla se esiste la directory;<3B> necessario in quanto se <20> una vecchia 4.0 potrebbe non esserci
|
||
bool ok = remote_setupdir.exist();
|
||
if (ok)
|
||
{
|
||
remote_setupdir.add("*.*");
|
||
|
||
TString_array ar;
|
||
list_files(remote_setupdir, ar);
|
||
|
||
if (!ar.empty())
|
||
{
|
||
make_dir(local_setupdir);
|
||
TFilename strsrc, strdst;
|
||
FOR_EACH_ARRAY_ROW (ar, i, row)
|
||
{
|
||
strsrc = *row;
|
||
const TFixed_string n = strsrc.name();
|
||
if (n.blank() || n.compare("Thumbs.db", -1, true) == 0)
|
||
continue;
|
||
strdst = local_setupdir;
|
||
strdst.add(n);
|
||
//se la copia dei files si inchioda esce
|
||
ok = fcopy(strsrc, strdst);
|
||
if (!ok)
|
||
break;
|
||
} //FOR_EACH_ARRAY...
|
||
} //if(!ar.empty...
|
||
} //if(remote_setupdir...
|
||
else
|
||
ok = cantread_box(remote_setupdir);
|
||
|
||
return ok;
|
||
}
|
||
|
||
bool TMenu_application::test_programs()
|
||
{
|
||
TToken_string dangerous;
|
||
int update_needed = 0;
|
||
const bool is_client = ini_get_int(CONFIG_INSTALL, "Main", "Type") == 3;
|
||
bool sy_needed = false;
|
||
|
||
TString msg = TR("I seguenti moduli devono essere aggiornati prima dell'utilizzo:\n");
|
||
if (is_client)
|
||
{
|
||
TConfig install("install.ini", "Main");
|
||
TFilename remote_name = install.get("DiskPath");
|
||
remote_name.add("install.ini");
|
||
|
||
if (remote_name.exist())
|
||
{
|
||
TProgind pi(3, TR("Controllo aggiornamento programmi"), false, true);
|
||
|
||
TConfig remote_install(remote_name, "Main");
|
||
remote_install.write_protect();
|
||
|
||
TAssoc_array my_modules, his_modules;
|
||
pi.addstatus(1);
|
||
install.for_each_paragraph(get_module_version, &my_modules);
|
||
pi.addstatus(1);
|
||
remote_install.for_each_paragraph(get_module_version, &his_modules);
|
||
pi.addstatus(1);
|
||
|
||
//giro su tutti i moduli che sono sul server
|
||
const TDongle& chiavetta = dongle();
|
||
FOR_EACH_ASSOC_STRING(his_modules, h, str_code, str_tok)
|
||
{
|
||
//per prima cosa controlla se deve aggiornare SY e/o BA
|
||
const TString4 code = str_code;
|
||
if (code == "sr")
|
||
continue; // Un client non pu<70> aggiornare il modulo server!
|
||
|
||
int module = 0;
|
||
if (code != "sy" && code != "ba")
|
||
module = chiavetta.module_name2code(code);
|
||
|
||
if (chiavetta.active(module) && chiavetta.shown(module))
|
||
{
|
||
//const TString4 code = dongle().module_code2name(module);
|
||
TToken_string* mytok = (TToken_string*)my_modules.objptr(code);
|
||
TToken_string* histok = (TToken_string*)his_modules.objptr(code);
|
||
|
||
const TString16 v1 = mytok ? mytok->get(0) : "";
|
||
const int p1 = mytok ? mytok->get_int() : 0;
|
||
const TString16 v2 = histok ? histok->get(0) : "";
|
||
const int p2 = histok ? histok->get_int() : 0;
|
||
if (!v1.blank() && compare_version(v1, p1, v2, p2) < 0)
|
||
{
|
||
// Non disabilitare mai il modulo base! Se non funzionasse qualcosa (vedi anno di assistenza)...
|
||
//...non lascierebbe funzionare nulla!!!!
|
||
if (module > 0)
|
||
dangerous.add(code);
|
||
else
|
||
{
|
||
if (code == "sy")
|
||
sy_needed = true;
|
||
}
|
||
|
||
if (msg.len() < 200)
|
||
{
|
||
TString name;
|
||
if (code == "sy")
|
||
name = TR("Sistema");
|
||
else
|
||
name = chiavetta.module_code2desc(module);
|
||
if (update_needed > 0)
|
||
msg << ", ";
|
||
msg << name;
|
||
}
|
||
else
|
||
{
|
||
if (msg.right(1) != ".")
|
||
msg << ",etc.";
|
||
}
|
||
update_needed++;
|
||
} //if (!v1.blank()...
|
||
} //if (chiavetta.active(module...
|
||
} //FOR_EACH_ASSOC_STR
|
||
} //if(remote_name.exist()...
|
||
|
||
if (update_needed > 0 && yesno_box(msg))
|
||
{
|
||
//copia il contenuto della setup del server nella setup del client
|
||
if (sy_needed)
|
||
{
|
||
if (copy_setup(remote_name.path()))
|
||
{
|
||
//mette il flag di installing
|
||
set_installing_flag();
|
||
//lancia setup in modalita' aggiornamento client e si suicida! (banzai!!)
|
||
TExternal_app app("setup\\SetCmpUp.exe -uc");
|
||
app.run(true, 0, false);
|
||
}
|
||
}
|
||
else //lancia l'installazione moduli alla vecchia maniera (e' una vecchia 4.0)
|
||
{
|
||
TExternal_app app("ba1 -6 /uADMIN");
|
||
app.run(true, 0, false);
|
||
}
|
||
//se lancia un'installazione->esce!!!
|
||
return false;
|
||
|
||
} //(if(update_needed>0...
|
||
} //if(is_client..
|
||
|
||
TString16 module;
|
||
TDate expires;
|
||
Tdninst dninst;
|
||
if (dninst.find_expiring(30, module, expires))
|
||
{
|
||
TString msg;
|
||
msg = TR("L'abilitazione ");
|
||
if (module == "*")
|
||
msg << TR(" di ") << dongle().product();
|
||
else
|
||
{
|
||
if (module.len() == 2)
|
||
msg << TR(" del modulo ") << module;
|
||
else
|
||
msg << TR(" del programma ") << module;
|
||
}
|
||
msg << TR(" scadr<64> il ") << expires << TR(":\nsi consiglia di contattare ")
|
||
<< dongle().reseller() << '.';
|
||
xvt_dm_popup_warning(msg);
|
||
}
|
||
|
||
_menu.set_dangerous_modules(dangerous);
|
||
return true;
|
||
}
|
||
|
||
bool TMenu_application::dongle_update_needed() const
|
||
{
|
||
bool ok = TApplication::test_assistance_year(false);
|
||
|
||
if (ok)
|
||
{
|
||
// Se sono una postazione client verifico l'aggiornamento di dninst.zip
|
||
if (xvt_sys_get_session_id() <= 0 && ini_get_int(CONFIG_INSTALL, "Main", "Type") == 3)
|
||
{
|
||
// Controlla se deve aggiornare il dninst.zip locale da quello del server
|
||
const char* const local_name = "setup/dninst.zip";
|
||
TFilename remote_name = ini_get_string(CONFIG_GENERAL, "Main", "DiskPath");
|
||
remote_name.add(local_name);
|
||
if (remote_name.exist())
|
||
{
|
||
const long remote_date = xvt_fsys_file_attr(remote_name, XVT_FILE_ATTR_MTIME);
|
||
const long local_date = xvt_fsys_file_attr(local_name, XVT_FILE_ATTR_MTIME);
|
||
if (remote_date > local_date)
|
||
xvt_fsys_fcopy(remote_name, local_name);
|
||
}
|
||
}
|
||
Tdninst dninst; // file aggiornatissimo ormai ...
|
||
const int dninst_year = dninst.assist_year();
|
||
const int dongle_year = dongle().year_assist();
|
||
ok = dninst_year <= dongle_year;
|
||
}
|
||
|
||
return !ok;
|
||
}
|
||
|
||
bool TMenu_application::user_create()
|
||
{
|
||
disable_menu_item(M_FILE_PRINT); // Questa voce di menu non serve per ora
|
||
disable_menu_item(M_FILE_PREVIEW); // Figuriamoci questa
|
||
|
||
if (dongle().type() == _no_dongle)
|
||
{
|
||
if (!yesno_box(TR("ATTENZIONE\nQuesto programma <20> in versione dimostrativa.\n"
|
||
"Esso funzioner<65> con alcune limitazioni sulle registrazioni.\n"
|
||
"Si desidera proseguire?")))
|
||
return false;
|
||
|
||
TString_array ssa;
|
||
int nssa = list_files("*.ssa", ssa);
|
||
if (nssa == 0)
|
||
{
|
||
nssa = list_files("setup/*.ssax", ssa);
|
||
if (nssa == 0)
|
||
{
|
||
TExternal_app app("setup/ssagetinfo");
|
||
app.run(false, 0, false);
|
||
nssa = list_files("setup/*.ssax", ssa);
|
||
}
|
||
if (nssa > 0)
|
||
{
|
||
TFilename dst;
|
||
if (xvt_fsys_get_desktop(dst.get_buffer()) == NOERR)
|
||
{
|
||
TFilename src = ssa.row(0);
|
||
dst.add(src.name());
|
||
if (xvt_fsys_fcopy(src, dst))
|
||
{
|
||
TFilename key = dst.name(); key.ext("ssa");
|
||
DIRECTORY dir; xvt_fsys_get_default_dir(&dir);
|
||
message_box(TR("E' stato creato sul desktop il file %s\n"
|
||
"Inviatelo ad abilitazioni_campo@sirio-is.it per ottenere il corrispondente\n"
|
||
"file %s da copiare in %s"),
|
||
dst.name(), key.name(), dir.path);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (dongle_update_needed())
|
||
{
|
||
TExternal_app app("ba1 -4");
|
||
app.run();
|
||
}
|
||
if (!check_user())
|
||
return false;
|
||
}
|
||
|
||
if (!test_programs())
|
||
return false;
|
||
|
||
if (!_menu.ok())
|
||
{
|
||
TWait_cursor hourglass;
|
||
TFilename menu = _menuname;
|
||
menu.ext("men");
|
||
_menu.read(menu);
|
||
update_preferred_tree();
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
void TMenu_application::deconnect_user()
|
||
{
|
||
if (get_user_status(user()) & 2) // Se e' connesso
|
||
set_user_status(user(), 1); // Sconnettilo
|
||
}
|
||
|
||
bool TMenu_application::destroy()
|
||
{
|
||
deconnect_user();
|
||
return true;
|
||
}
|
||
|
||
void TMenu_application::main_loop()
|
||
{
|
||
bool run = user_create();
|
||
|
||
while (run)
|
||
{
|
||
int m = 0;
|
||
switch (_tree_view)
|
||
{
|
||
// case 1: m = do_tree(); break;
|
||
case 2: m = do_explore(); break;
|
||
case 3: m = do_outlook(); break;
|
||
case 4: m = do_metro(); break;
|
||
default: m = do_level(); break;
|
||
}
|
||
if (m > 0)
|
||
_menu.perform();
|
||
else
|
||
run = m >= -1;
|
||
if (installing()) //esce dal ciclo se ha lanciato una installazione moduli
|
||
break;
|
||
}
|
||
}
|
||
|
||
static bool _options_menu_enabled = false;
|
||
|
||
void enable_options_menu(bool on)
|
||
{
|
||
_options_menu_enabled = on;
|
||
|
||
const WINDOW tw = TASK_WIN;
|
||
xvt_menu_set_item_enabled(tw, M_FILE_NEW, on); // Cambio ditta
|
||
xvt_menu_set_item_enabled(tw, M_FILE_PG_SETUP, on); // Imposta Stampante
|
||
for (int i = 2; i <= 7; i++) // Menu opzioni
|
||
xvt_menu_set_item_enabled(tw, MENU_ITEM_ID(i), on);
|
||
xvt_menu_update(tw);
|
||
}
|
||
|
||
bool TMenu_application::choose_colors()
|
||
{
|
||
const KEY CTLR = K_CTRL+'R';
|
||
enable_options_menu(false);
|
||
|
||
bool update_needed = false;
|
||
KEY key = CTLR;
|
||
while (key == CTLR)
|
||
{
|
||
TColor_mask cm;
|
||
key = cm.run();
|
||
if (key == K_ENTER || key == CTLR) // Salva o Applica
|
||
{
|
||
_tree_view = cm.get_int(216); // Aggiorna stile menu
|
||
cm.save_colors(); // Aggiorna config
|
||
customize_colors(); // Aggiorna set di colori
|
||
reload_images(); // Aggiorna bitmaps del menu
|
||
|
||
// Ridisegna sfondo
|
||
TTemp_window tw(TASK_WIN);
|
||
tw.force_update();
|
||
update_needed = true;
|
||
}
|
||
}
|
||
|
||
// Provoca chiusura forzata del menu
|
||
if (update_needed && _mask != NULL)
|
||
_mask->stop_run(CTLR);
|
||
|
||
enable_options_menu(true);
|
||
return key == K_ENTER;
|
||
}
|
||
|
||
HIDDEN bool browse_file_handler(TMask_field& f, KEY k)
|
||
{
|
||
bool ok = true;
|
||
|
||
if (k == K_F9)
|
||
{
|
||
TFilename n = f.get(); n.ext("exe");
|
||
FILE_SPEC fs; xvt_fsys_convert_str_to_fspec(n, &fs);
|
||
|
||
//DIRECTORY dir; xvt_fsys_get_dir(&dir);
|
||
const int err = xvt_dm_post_file_open(&fs, TR("Selezione programma"));
|
||
//xvt_fsys_set_dir(&dir);
|
||
if (err == FL_OK)
|
||
{
|
||
xvt_fsys_convert_fspec_to_str(&fs, n.get_buffer(), n.size());
|
||
f.set(n);
|
||
}
|
||
}
|
||
|
||
if (k == K_TAB && f.focusdirty())
|
||
{
|
||
TFilename infile(f.get());
|
||
if (infile.not_empty())
|
||
{
|
||
TFilename outfile;
|
||
if (!infile.search_in_path(outfile))
|
||
{
|
||
if (*infile.ext() == '\0')
|
||
infile.ext("exe");
|
||
if (!infile.search_in_path(outfile))
|
||
ok = error_box("Il programma %s non esiste!", (const char*)infile);
|
||
}
|
||
}
|
||
}
|
||
|
||
return ok;
|
||
}
|
||
|
||
HIDDEN bool link_notify(TSheet_field& s, int r, KEY k)
|
||
{
|
||
bool ok = true;
|
||
if (k == K_INS)
|
||
{
|
||
ok = s.items() < 29; // Accetta 29 righe al massimo
|
||
}
|
||
return ok;
|
||
}
|
||
|
||
bool TMenu_application::choose_editors()
|
||
{
|
||
enable_options_menu(false);
|
||
|
||
TConfig link(CONFIG_GUI, "Link");
|
||
|
||
TMask* msk = new TMask("ba0300a");
|
||
TMask& m = *msk;
|
||
|
||
TSheet_field& sheet = m.sfield(201);
|
||
sheet.set_notify(link_notify);
|
||
TMask& sm = sheet.sheet_mask();
|
||
sm.set_handler(102, browse_file_handler);
|
||
|
||
TAssoc_array& var = (TAssoc_array&)link.list_variables();
|
||
FOR_EACH_ASSOC_STRING(var, obj, key, str)
|
||
{
|
||
TToken_string& row = sheet.row(-1);
|
||
if (strlen(key) <= 3)
|
||
{
|
||
row = key;
|
||
row.lower();
|
||
row.add(str);
|
||
}
|
||
}
|
||
sheet.rows_array().sort();
|
||
|
||
if (m.run() == K_ENTER)
|
||
{
|
||
link.remove_all();
|
||
FOR_EACH_SHEET_ROW_BACK(sheet, r, row)
|
||
{
|
||
TString16 ext = row->get(0);
|
||
if (!ext.blank())
|
||
{
|
||
ext.lower();
|
||
TFilename prg = row->get();
|
||
link.set(ext, prg);
|
||
}
|
||
}
|
||
}
|
||
delete msk;
|
||
|
||
enable_options_menu(true);
|
||
|
||
return true;
|
||
}
|
||
|
||
HIDDEN int dir_sort(const TObject** d1, const TObject** d2)
|
||
{
|
||
const TString& s1 = (const TString&)**d1;
|
||
const TString& s2 = (const TString&)**d2;
|
||
return xvt_str_compare_ignoring_case(s1, s2);
|
||
}
|
||
|
||
class TStudy_mask : public TAutomask
|
||
{
|
||
private:
|
||
bool is_valid_study(const char* path) const;
|
||
void list_studies(TString_array& s, bool count_firms) const;
|
||
|
||
protected:
|
||
virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
|
||
virtual long handler(WINDOW win, EVENT* e);
|
||
|
||
public:
|
||
TStudy_mask();
|
||
};
|
||
|
||
long TStudy_mask::handler(WINDOW win, EVENT* e)
|
||
{
|
||
if (e->type == E_CHAR && e->v.chr.ch == K_ENTER)
|
||
{
|
||
if (!efield(DLG_USER).empty())
|
||
stop_run(K_ENTER);
|
||
}
|
||
return TAutomask::handler(win, e);
|
||
}
|
||
|
||
bool TStudy_mask::is_valid_study(const char* path) const
|
||
{
|
||
TFilename n = path; n.add("com/dir.gen");
|
||
return n.find(' ') < 0 && xvt_fsys_access(n, 0x2) == 0; // NO blanks and write permission
|
||
}
|
||
|
||
void TStudy_mask::list_studies(TString_array& sht, bool firms_count) const
|
||
{
|
||
TWait_cursor hourglass;
|
||
TFilename str = firm2dir(-1);
|
||
for (int i = str.len()-2; i > 0; i--)
|
||
{
|
||
if (str[i] == '\\' || str[i] == '/')
|
||
{
|
||
str.cut(i);
|
||
break;
|
||
}
|
||
}
|
||
str.add("*");
|
||
SLIST dirs = xvt_fsys_list_files(DIR_TYPE, str, true);
|
||
|
||
for (SLIST_ELT e = xvt_slist_get_first(dirs); e; e = xvt_slist_get_next(dirs, e))
|
||
{
|
||
const char* f = xvt_slist_get(dirs, e, NULL);
|
||
if (is_valid_study(f))
|
||
{
|
||
if (firms_count)
|
||
{
|
||
str = f; str.add("?????A");
|
||
SLIST firms = xvt_fsys_list_files(DIR_TYPE, str, true);
|
||
const int nf = xvt_slist_count(firms);
|
||
xvt_slist_destroy(firms);
|
||
if (nf > 0)
|
||
{
|
||
TToken_string row = f;
|
||
row.add(nf);
|
||
sht.add(row);
|
||
}
|
||
}
|
||
else
|
||
sht.add(f);
|
||
}
|
||
}
|
||
xvt_slist_destroy(dirs);
|
||
}
|
||
|
||
bool TStudy_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
|
||
{
|
||
switch (o.dlg())
|
||
{
|
||
case DLG_FINDREC:
|
||
if (e == fe_button)
|
||
send_key(K_F9, DLG_USER, &o);
|
||
break;
|
||
case DLG_USER:
|
||
if (e == fe_init)
|
||
o.set(firm2dir(-1));
|
||
if (e == fe_modify || e == fe_close)
|
||
{
|
||
TFilename s = o.get();
|
||
if (e == fe_modify && s.full() && !is_valid_study(s))
|
||
{
|
||
const TString name = s.name_only();
|
||
TString_array std; list_studies(std, false);
|
||
TString strBest;
|
||
double dBest = 0;
|
||
FOR_EACH_ARRAY_ROW(std, i, row)
|
||
{
|
||
const TFilename study = *row;
|
||
const TString& sn = study.name_only();
|
||
const double score = xvt_str_fuzzy_compare_ignoring_case(name, sn);
|
||
if (score > dBest)
|
||
{
|
||
strBest = study;
|
||
dBest = score;
|
||
if (score == 1.0)
|
||
break;
|
||
}
|
||
}
|
||
if (dBest > 0.75)
|
||
o.set(s = strBest);
|
||
}
|
||
if (!is_valid_study(s))
|
||
return error_box("%s %s", (const char*)s, TR("non <20> uno studio valido!"));
|
||
}
|
||
if (e == fe_button)
|
||
{
|
||
TArray_sheet sht(-1, -1, 78, 20, TR("Scelta studio"), HR("Studio@50|Ditte@5R"));
|
||
list_studies(sht.rows_array(), true);
|
||
sht.rows_array().TArray::sort(dir_sort);
|
||
if (sht.run() == K_ENTER)
|
||
o.set(sht.row(-1).get(0)); // -1 = selected row
|
||
}
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
TStudy_mask::TStudy_mask() : TAutomask(TR("Scelta studio"), 1, 60, 3)
|
||
{
|
||
add_button_tool(DLG_OK, "", TOOL_OK);
|
||
add_button_tool(DLG_FINDREC, TR("Ricerca"), TOOL_FINDREC);
|
||
add_button_tool(DLG_NULL, "", 0);
|
||
add_button_tool(DLG_HELP, TR("Help"), TOOL_HELP);
|
||
add_button_tool(DLG_NULL, "", 0);
|
||
add_button_tool(DLG_CANCEL, "", TOOL_CANCEL);
|
||
add_string(DLG_USER, 0, "", 1, 1, 260, "B", 56);
|
||
set_handlers();
|
||
}
|
||
|
||
bool TMenu_application::choose_study()
|
||
{
|
||
// Disabilita le voci di personalizzazione
|
||
enable_options_menu(false);
|
||
|
||
TStudy_mask m;
|
||
TPrefix& p = prefix();
|
||
const TString oldstudy = p.get_studio();
|
||
|
||
bool ok = m.run() == K_ENTER;
|
||
if (ok && oldstudy != m.get(DLG_USER))
|
||
{
|
||
ok = p.set_studio(m.get(DLG_USER));
|
||
if (ok)
|
||
{
|
||
deconnect_user();
|
||
ok = check_user();
|
||
enable_options_menu(true); // Abilita le voci di personalizzazione
|
||
_menu.set_firm(0L);
|
||
}
|
||
if (ok)
|
||
_mask->stop_run(K_F9); // Ricarica maschera
|
||
else
|
||
dispatch_e_menu(M_FILE_QUIT); // Termina applicazione gracefully
|
||
}
|
||
else
|
||
enable_options_menu(true); // Abilita le voci di personalizzazione
|
||
|
||
return ok;
|
||
}
|
||
|
||
long TMenu_application::handler(WINDOW win, EVENT* ep)
|
||
{
|
||
long ret = TApplication::handler(win, ep);
|
||
|
||
if (_mask != NULL)
|
||
{
|
||
switch (ep->type)
|
||
{
|
||
case E_FONT: // Sono cambiate le opzioni di visualizzazione
|
||
_mask->stop_run(K_CTRL + 'R');
|
||
break;
|
||
case E_PROCESS: // Notifica nascita e morte processi
|
||
if (_tree_view >= 3)
|
||
{
|
||
TOutlook_mask& m = (TOutlook_mask&)*_mask;
|
||
m.handler(m.win(), ep);
|
||
}
|
||
break;
|
||
case E_SIZE:
|
||
if (_tree_view >= 3)
|
||
{
|
||
WINDOW winm = _mask->win();
|
||
RCT rctw; xvt_vobj_get_client_rect(win, &rctw);
|
||
RCT rctm; xvt_vobj_get_client_rect(winm, &rctm);
|
||
if (rctm.right != rctw.right || rctm.bottom != rctw.bottom)
|
||
{
|
||
xvt_vobj_move(winm, &rctw);
|
||
_mask->force_update();
|
||
}
|
||
}
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
return ret;
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// Tree view implementation
|
||
///////////////////////////////////////////////////////////
|
||
|
||
bool TMenu_application::tree_handler(TMask_field& f, KEY k)
|
||
{
|
||
if (k == K_CTRL + K_SPACE)
|
||
{
|
||
TTree_field& tf = (TTree_field&)f;
|
||
TMenu_tree& mt = *(TMenu_tree*)tf.tree();
|
||
const TMenuitem& mi = mt.curr_item();
|
||
mi.perform();
|
||
|
||
if (mi.is_submenu())
|
||
{
|
||
TPicture_mask& pm = (TPicture_mask&)f.mask();
|
||
if (mt.expanded())
|
||
{
|
||
TMenu& menu = mt.curr_submenu().menu();
|
||
pm.set_current(menu.current());
|
||
}
|
||
pm.force_update();
|
||
}
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
TTree_field& TMenu_application::tree_field() const
|
||
{
|
||
CHECK(_tree_view > 0, "No menu tree");
|
||
return _mask->tfield(_tree_view >= 3 ? 101 : 301);
|
||
}
|
||
|
||
void TMenu_application::select_tree_current()
|
||
{
|
||
TTree_field& tf = tree_field();
|
||
synchronize_tree_field(tf);
|
||
tf.set_focus();
|
||
}
|
||
|
||
bool TMenu_application::tree_find_handler(TMask_field&f, KEY k)
|
||
{
|
||
if (k == K_TAB && f.focusdirty() && !f.empty())
|
||
{
|
||
const TString& v = f.get();
|
||
TTree_field& tf = app().tree_field();
|
||
TMenu_tree& mt = *(TMenu_tree*)tf.tree();
|
||
if (mt.find_string(v))
|
||
app().select_tree_current();
|
||
else
|
||
beep();
|
||
}
|
||
return true;
|
||
}
|
||
|
||
bool TMenu_application::tree_shrink_handler(TMask_field&f, KEY k)
|
||
{
|
||
if (k == K_SPACE)
|
||
{
|
||
TTree_field& tf = app().tree_field();
|
||
TMenu_tree& mt = (TMenu_tree&)*tf.tree();
|
||
mt.shrink_all();
|
||
mt.goto_root();
|
||
app().select_tree_current();
|
||
}
|
||
return true;
|
||
}
|
||
|
||
void TMenu_application::update_preferred()
|
||
{
|
||
MENU_ITEM* mm = xvt_menu_get_tree(TASK_WIN);
|
||
MENU_ITEM* mi;
|
||
for (mi = mm; mi != NULL && mi->tag != 0 && mi->tag != PREFERRED_MENU; mi++);
|
||
if (mi == NULL || mi->tag <= 0 || mi->child == NULL)
|
||
{
|
||
NFCHECK("Can't find Preferiti Menu");
|
||
return;
|
||
}
|
||
|
||
const int prefs = min(_preferred.items(), 24);
|
||
int i;
|
||
MENU_ITEM* pm = (MENU_ITEM*)xvt_mem_zalloc((prefs+4)*sizeof(MENU_ITEM));
|
||
memcpy(pm, mi->child, 3*sizeof(MENU_ITEM));
|
||
for (i = 0; i < 2; i++)
|
||
{
|
||
const char* src = mi->child[i].text;
|
||
pm[i].text = xvt_str_duplicate(src);
|
||
}
|
||
xvt_res_free_menu_tree(mi->child);
|
||
mi->child = pm;
|
||
|
||
for (i = -1; i < prefs; i++)
|
||
{
|
||
MENU_ITEM& m = pm[i+3];
|
||
if (i >= 0)
|
||
{
|
||
m.tag = MENU_ITEM_ID(50+i);
|
||
m.enabled = true;
|
||
const char* src = _preferred.row(i).get(0);
|
||
m.text = xvt_str_duplicate(src);
|
||
}
|
||
else
|
||
{
|
||
m.tag = -1;
|
||
m.separator = true;
|
||
}
|
||
}
|
||
|
||
xvt_menu_set_tree(TASK_WIN, mm);
|
||
xvt_menu_update(TASK_WIN);
|
||
xvt_res_free_menu_tree(mm);
|
||
|
||
update_preferred_tree();
|
||
}
|
||
|
||
void TMenu_application::update_preferred_tree()
|
||
{
|
||
TSubmenu* pref = _menu.find("MENU_PREFERITI");
|
||
if (pref != NULL)
|
||
{
|
||
TToken_string node(16, '.');
|
||
pref->destroy_items();
|
||
FOR_EACH_ARRAY_ROW(_preferred, i, row)
|
||
{
|
||
int slash = row->rfind('/');
|
||
if (slash < 0)
|
||
slash = row->rfind(row->separator());
|
||
node = row->mid(slash+1);
|
||
if (node.items() == 2)
|
||
{
|
||
const char* sub = node.get(0);
|
||
TSubmenu* sm = _menu.find(sub);
|
||
if (sm != NULL)
|
||
{
|
||
const int num = node.get_int(1);
|
||
if (num >= 0 && num < sm->items())
|
||
pref->add(new TMenuitem(sm->item(num)));
|
||
}
|
||
}
|
||
}
|
||
|
||
if (_tree_view >= 3 && _mask != NULL)
|
||
{
|
||
FOR_EACH_MASK_FIELD(*_mask, i, f)
|
||
{
|
||
if (f->is_kind_of(CLASS_OUTLOOK_FIELD))
|
||
{
|
||
f->set_focusdirty(false);
|
||
f->on_hit(); // fe_init
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
void TMenu_application::load_preferences()
|
||
{
|
||
TConfig cfg(CONFIG_GUI, "ba0");
|
||
_preferred.destroy();
|
||
TToken_string row;
|
||
for (int i = 0; ; i++)
|
||
{
|
||
row = cfg.get("Preferred", NULL, i);
|
||
if (row.empty_items())
|
||
break;
|
||
_preferred.add(row);
|
||
}
|
||
update_preferred();
|
||
|
||
cfg.set_paragraph("Colors");
|
||
TMenuitem::always_run_fullscreen(cfg.get_bool("RunModal"));
|
||
_tree_view = cfg.get_int("TreeView", NULL, -1, 3);
|
||
}
|
||
|
||
void TMenu_application::save_preferences()
|
||
{
|
||
TConfig cfg(CONFIG_GUI, "ba0");
|
||
int i;
|
||
for (i = 0; i < _preferred.items(); i++)
|
||
cfg.set("Preferred", _preferred.row(i), NULL, true, i);
|
||
cfg.set("Preferred", "", NULL, true, i);
|
||
}
|
||
|
||
void TMenu_application::add_to_preferred()
|
||
{
|
||
if (_mask == NULL) // Succede durante il login!
|
||
return;
|
||
|
||
const int max_pref = 32; // Massimo numero di preferiti
|
||
if (_preferred.items() < max_pref)
|
||
{
|
||
TToken_string tok;
|
||
|
||
switch (_tree_view)
|
||
{
|
||
case 0:
|
||
{
|
||
const TMask_field& butt = _mask->focus_field();
|
||
const int index = butt.dlg() - 101;
|
||
if (index >= 0 && index < max_pref)
|
||
{
|
||
_menu.select(index);
|
||
tok = _menu.curr_item().caption();
|
||
tok.add(_menu.current().name());
|
||
tok << '.' << index;
|
||
}
|
||
}
|
||
break;
|
||
case 2:
|
||
{
|
||
TMenulist_field& mf = (TMenulist_field&)_mask->field(DLG_LIST);
|
||
mf.curr_item(tok);
|
||
}
|
||
break;
|
||
default:
|
||
{
|
||
TTree_field& tf = tree_field();
|
||
tf.goto_selected();
|
||
if (tf.tree()->has_father()) // Aggiunge solo nodi NON radice
|
||
{
|
||
tf.tree()->get_description(tok);
|
||
TString id; tf.tree()->curr_id(id);
|
||
tok.add(id);
|
||
}
|
||
else
|
||
error_box(TR("Non <20> possibile aggiungere voci di primo livello"));
|
||
}
|
||
break;
|
||
}
|
||
if (tok.full() && tok.find("MENU_PREFERITI")<0 && _preferred.find(tok)<0)
|
||
{
|
||
_preferred.add(tok);
|
||
save_preferences();
|
||
update_preferred();
|
||
}
|
||
}
|
||
else
|
||
error_box(TR("Non <20> possibile memorizzare pi<70> di %d preferenze"), _preferred.items());
|
||
}
|
||
|
||
class TPreferred_mask : public TAutomask
|
||
{
|
||
protected:
|
||
virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
|
||
|
||
public:
|
||
TPreferred_mask() : TAutomask("ba0400a") { }
|
||
};
|
||
|
||
bool TPreferred_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
|
||
{
|
||
switch (o.dlg())
|
||
{
|
||
case F_PREF_SHEET:
|
||
switch (e)
|
||
{
|
||
case se_query_add:
|
||
return false;
|
||
case se_enter:
|
||
enable(F_PREF_UP, jolly > 0);
|
||
enable(F_PREF_DN, jolly < ((TSheet_field&)o).items()-1);
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
break;
|
||
case F_PREF_UP:
|
||
if (e == fe_button)
|
||
{
|
||
TSheet_field& sf = sfield(F_PREF_SHEET);
|
||
const int r = sf.selected();
|
||
if (r > 0)
|
||
{
|
||
sf.rows_array().swap(r, r-1);
|
||
sf.select(r-1);
|
||
sf.force_update();
|
||
}
|
||
}
|
||
break;
|
||
case F_PREF_DN:
|
||
if (e == fe_button)
|
||
{
|
||
TSheet_field& sf = sfield(F_PREF_SHEET);
|
||
const int r = sf.selected();
|
||
if (r < sf.items()-1)
|
||
{
|
||
sf.rows_array().swap(r, r+1);
|
||
sf.select(r+1);
|
||
sf.force_update();
|
||
}
|
||
}
|
||
break;
|
||
case DLG_DELREC:
|
||
if (e == fe_button && jolly == 0) // Main delete button pressed
|
||
{
|
||
TSheet_field& sf = sfield(F_PREF_SHEET);
|
||
const int r = sf.selected();
|
||
if (r >= 0)
|
||
sf.destroy(r);
|
||
return false;
|
||
}
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
void TMenu_application::manage_preferred()
|
||
{
|
||
TPreferred_mask* m = new TPreferred_mask;
|
||
|
||
TSheet_field& sf = m->sfield(F_PREF_SHEET);
|
||
sf.rows_array() = _preferred;
|
||
sf.force_update();
|
||
|
||
if (m->run() == K_ENTER)
|
||
{
|
||
_preferred = sf.rows_array();
|
||
save_preferences();
|
||
update_preferred();
|
||
}
|
||
delete m;
|
||
}
|
||
|
||
void TMenu_application::manage_mail()
|
||
{
|
||
TMask m("ba0100m");
|
||
TConfig cfg(CONFIG_USER, "Mail");
|
||
FOR_EACH_MASK_FIELD(m, i, f) if (f->field())
|
||
f->set(f->field()->read(cfg, "Mail"));
|
||
if (m.run() == K_ENTER)
|
||
{
|
||
FOR_EACH_MASK_FIELD(m, i, f) if (f->field())
|
||
f->field()->write(cfg, "Mail", f->get());
|
||
}
|
||
}
|
||
|
||
|
||
/* Deprecated
|
||
int TMenu_application::do_tree()
|
||
{
|
||
_menu.jumpto_root();
|
||
const TSubmenu& curr = _menu.current();
|
||
TPicture_mask mask(curr.caption(), 0, 0, curr, 0, 0);
|
||
CHECK(_mask == NULL, "Two masks are better than one?");
|
||
_mask = &mask;
|
||
|
||
const int margin = (mask.columns()-80) / 2;
|
||
const int twidth = mask.columns() - 51;
|
||
const int bwidth = (mask.columns() - twidth - 8);
|
||
|
||
TMenu_tree tree(_menu);
|
||
TTree_field& tree_fld = mask.add_tree(DLG_TREE, 0, 0, 0, twidth, -1);
|
||
tree_fld.set_tree(&tree);
|
||
tree_fld.set_handler(tree_handler);
|
||
|
||
const int inizio = twidth - margin + 2;
|
||
const int ampiezza = mask.columns() - inizio - margin;
|
||
const int bottone = ampiezza / 3;
|
||
const int spazio = (ampiezza - 2 * bottone) / 3;
|
||
|
||
mask.add_static(DLG_NULL, 0, PR("Cerca"), inizio + 2, -4);
|
||
|
||
TEdit_field& ef = mask.add_string(DLG_USER, 0, "", inizio + 2, -3, 50, "", ampiezza - 4);
|
||
ef.set_handler(tree_find_handler);
|
||
|
||
TButton_field& mf = mask.add_button(201, 0, PR("Menu Principale"), inizio + spazio * 2 + bottone, -1, bottone, 2);
|
||
mf.set_handler(tree_shrink_handler);
|
||
|
||
mask.add_button(DLG_QUIT, 0, PR("Fine"), inizio + spazio, -1, bottone, 2);
|
||
|
||
mask.first_focus(DLG_TREE);
|
||
KEY key = mask.run();
|
||
_mask = NULL;
|
||
|
||
return key == K_QUIT ? -2 : 0;
|
||
}
|
||
*/
|
||
|
||
int TMenu_application::do_explore()
|
||
{
|
||
CHECK(_mask == NULL, "Two masks are better than one?");
|
||
_menu.jumpto_root();
|
||
TExplorer_mask mask(_menu);
|
||
_mask = &mask;
|
||
|
||
KEY key = mask.run();
|
||
_mask = NULL;
|
||
|
||
return key == K_QUIT ? -2 : 0;
|
||
}
|
||
|
||
int TMenu_application::do_outlook()
|
||
{
|
||
CHECK(_mask == NULL, "Two masks are better than one?");
|
||
TOutlook_mask mask(_menu);
|
||
_mask = &mask;
|
||
|
||
KEY key = mask.run();
|
||
|
||
_mask = NULL;
|
||
|
||
return key == K_QUIT ? -2 : 0;
|
||
}
|
||
|
||
int TMenu_application::do_metro()
|
||
{
|
||
CHECK(_mask == NULL, "Two masks are better than one?");
|
||
TMetro_mask mask(_menu);
|
||
_mask = &mask;
|
||
|
||
KEY key = mask.run();
|
||
|
||
_mask = NULL;
|
||
|
||
return key == K_QUIT ? -2 : 0;
|
||
}
|
||
|
||
bool TMenu_application::firm_change_enabled() const
|
||
{
|
||
bool yes = _mask != NULL || _tree_view == 0; // Impedisci il cambio ditta durante il login
|
||
if (yes)
|
||
yes &= _options_menu_enabled;
|
||
return yes;
|
||
}
|
||
|
||
void TMenu_application::on_firm_change()
|
||
{
|
||
TConfig cfgs(CONFIG_STUDIO, "Main"); // Forza creazione STUDIO.INI copiandolo eventulamente da PRASSIS.INI
|
||
TConfig cfgd(CONFIG_DITTA, "ba"); // Forza creazione DITTA.INI copiandolo eventulamente da PRASSID.INI
|
||
}
|
||
|
||
bool TMenu_application::menu(MENU_TAG mt)
|
||
{
|
||
bool ok = true;
|
||
switch (mt)
|
||
{
|
||
case BAR_ITEM_ID(1): main_loop(); ok = false; break;
|
||
case MENU_ITEM_ID(2): choose_colors(); break;
|
||
case MENU_ITEM_ID(3): choose_editors(); break;
|
||
case MENU_ITEM_ID(4): choose_study(); break;
|
||
case MENU_ITEM_ID(5): add_to_preferred(); break;
|
||
case MENU_ITEM_ID(6): manage_preferred(); break;
|
||
case MENU_ITEM_ID(7):
|
||
if (check_user())
|
||
_mask->stop_run(K_CTRL + 'R'); // Ricarica maschera
|
||
break;
|
||
case MENU_ITEM_ID(8): manage_mail(); break;
|
||
default:
|
||
if (mt >= MENU_ITEM_ID(50) && mt < MENU_ITEM_ID(50+_preferred.items()))
|
||
{
|
||
bool ok = false;
|
||
const int index = mt - MENU_ITEM_ID(50);
|
||
TToken_string node(_preferred.row(index).get(1), '/');
|
||
if (_tree_view != 0)
|
||
{
|
||
TMenu_tree& met = *(TMenu_tree*)tree_field().tree();
|
||
ok = node.items() == 1 ? met.find_leaf(node) : met.goto_node(node);
|
||
if (ok)
|
||
{
|
||
select_tree_current();
|
||
if (met.curr_item().is_program())
|
||
tree_field().on_key(K_CTRL+K_SPACE); // Esegue subito il programma
|
||
}
|
||
}
|
||
else
|
||
{
|
||
TToken_string mi(node.get(-2), '.');
|
||
const char* sub = mi.get(0);
|
||
TSubmenu* sm = _menu.find(sub);
|
||
if (sm && _menu.jumpto(sm))
|
||
{
|
||
ok = true;
|
||
_menu.select(mi.get_int());
|
||
_mask->stop_run(K_CTRL + 'R');
|
||
}
|
||
}
|
||
if (!ok)
|
||
beep();
|
||
}
|
||
break;
|
||
}
|
||
return ok;
|
||
}
|
||
|
||
TMenu_application::TMenu_application(const char* name)
|
||
: _menuname(name), _mask(NULL), _tree_view(3)
|
||
{ }
|
||
|
||
int ba0100(int argc, char** argv)
|
||
{
|
||
if (xvt_vobj_get_attr(NULL_WIN, ATTR_APPL_ALREADY_RUNNING))
|
||
return warning_box(TR("Il menu principale <20> gi<67> in esecuzione!"));
|
||
|
||
TApplication::check_parameters(argc, argv);
|
||
|
||
TString& u = user();
|
||
if (u.blank())
|
||
{
|
||
TConfig campo_ini(CONFIG_INSTALL, "Main");
|
||
const bool su = campo_ini.get_bool("AutoLogin");
|
||
if (su) // usa utente di windows
|
||
{
|
||
xvt_sys_get_user_name(u.get_buffer(), u.size()+1);
|
||
u.upper();
|
||
if (u.compare("Administrator", -1, true) == 0) // Converti amministratore
|
||
u = dongle().administrator();
|
||
}
|
||
if (u.blank())
|
||
u = campo_ini.get("User"); // Ultimo utente usato
|
||
if (u.blank())
|
||
u = dongle().administrator(); // Usa amministratore come extrema ratio
|
||
}
|
||
|
||
TFilename menu = (argc < 2) ? MEN_FILE : argv[1];
|
||
bool ok = menu.custom_path();
|
||
if (!ok && argc >= 2)
|
||
{
|
||
menu = MEN_FILE;
|
||
ok = menu.custom_path();
|
||
}
|
||
if (ok)
|
||
{
|
||
TMenu_application *ma = new TMenu_application(menu);
|
||
ma->run(argc, argv, TR("Menu Principale"));
|
||
delete ma;
|
||
}
|
||
else
|
||
cantread_box(menu);
|
||
|
||
return 0;
|
||
}
|