Supporto base per tema METRO

git-svn-id: svn://10.65.10.50/branches/R_10_00@23185 c028cbd2-c16b-5b4b-a496-9718f37d4682
This commit is contained in:
guy 2016-04-15 08:12:39 +00:00
parent 7fede88bb6
commit dddb1a668f
15 changed files with 1009 additions and 261 deletions

View File

@ -1,6 +1,7 @@
#include <applicat.h>
#include <automask.h>
#include <controls.h>
#include <config.h>
#include <dongle.h>
#include <execp.h>
#include <recarray.h>
@ -64,6 +65,7 @@ protected:
// 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;
@ -563,8 +565,8 @@ bool TColor_mask::apply_theme()
set_font_desc(fd);
xvt_font_destroy(fontid); // Rilascia il font di sistema
TProp_field& pf = options_field();
pf.set_property("Campi3D", true);
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;
}
@ -1600,6 +1602,7 @@ void TMenu_application::main_loop()
// 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)
@ -1949,14 +1952,14 @@ long TMenu_application::handler(WINDOW win, EVENT* ep)
_mask->stop_run(K_CTRL + 'R');
break;
case E_PROCESS: // Notifica nascita e morte processi
if (_tree_view == 3)
if (_tree_view >= 3)
{
TOutlook_mask& m = (TOutlook_mask&)*_mask;
m.handler(m.win(), ep);
}
break;
case E_SIZE:
if (_tree_view == 3)
if (_tree_view >= 3)
{
WINDOW winm = _mask->win();
RCT rctw; xvt_vobj_get_client_rect(win, &rctw);
@ -2006,7 +2009,7 @@ bool TMenu_application::tree_handler(TMask_field& f, KEY k)
TTree_field& TMenu_application::tree_field() const
{
CHECK(_tree_view > 0, "No menu tree");
return _mask->tfield(_tree_view == 3 ? 101 : 301);
return _mask->tfield(_tree_view >= 3 ? 101 : 301);
}
void TMenu_application::select_tree_current()
@ -2117,11 +2120,17 @@ void TMenu_application::update_preferred_tree()
}
}
if (_tree_view == 3 && _mask != NULL)
if (_tree_view >= 3 && _mask != NULL)
{
TMask_field& ol = _mask->field(102);
ol.set_focusdirty(false);
ol.on_hit(); // fe_init
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;
}
}
}
}
}
@ -2130,9 +2139,10 @@ void TMenu_application::load_preferences()
{
TConfig cfg(CONFIG_GUI, "ba0");
_preferred.destroy();
TToken_string row;
for (int i = 0; ; i++)
{
TToken_string row = cfg.get("Preferred", NULL, i);
row = cfg.get("Preferred", NULL, i);
if (row.empty_items())
break;
_preferred.add(row);
@ -2376,6 +2386,19 @@ int TMenu_application::do_outlook()
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

View File

@ -287,7 +287,7 @@ bool TMenuitem::perform_submenu() const
bool TMenuitem::run_modal() const
{
bool yes = true;
if (submenu().menu().mask_mode() == 3) // outlook mode
if (submenu().menu().mask_mode() >= 3) // outlook mode
{
yes = _password || _action.match("ba[12] -*", true) || _action.starts_with("cg6", true);
}
@ -341,17 +341,21 @@ bool TMenuitem::perform_program() const
(const char*)user(), (const char*)caption());
}
const bool install_app = _action.starts_with("ba1 -6", true);
if (install_app)
if (_action.starts_with("ba1 -6", true))
{
user() = dongle().administrator(); // Divento temporaneamente amministratore
a.run(true, 3); // e' una installazione -> applicazione in asincrono
set_installing_flag();
} else
if (_action.starts_with("ba7 -0", true))
{
xvt_sys_execute(_action, FALSE, FALSE);
return false; // Evita di creare un finestra ospite per il postino!
} else
if (_action.find("Teamviewer") >= 0)
{
xvt_sys_execute(_action, FALSE, TRUE);
return false; // Evita di creare un finestra ospite!
return false; // Evita di creare un finestra ospite per la teleassistenza!
}
else
{
@ -366,6 +370,12 @@ bool TMenuitem::perform_program() const
{
a.run(true, 1, false); // e' un programma asincrono
}
// incrementa conteggio utilizzo programmi
TToken_string cnt = ini_get_string(CONFIG_GUI, "Counters", _action);
cnt.add(cnt.get_int(0)+1, 0);
cnt.add(TDate(TODAY).date2ansi(), 1);
ini_set_string(CONFIG_GUI, "Counters", _action, cnt);
}
}
@ -668,6 +678,7 @@ TSubmenu& TMenu::pop()
TSubmenu* TMenu::find_string(const TString& str)
{
TString upstr(str);
upstr.trim();
upstr.upper();
if (_last_search != upstr)

View File

@ -964,25 +964,35 @@ void TMenulist_field::curr_item(TToken_string& id) const
void draw_spider(WINDOW w, int mode, const PNT& mouse)
{
static bool _spider = ADVANCED_GRAPHICS && is_power_reseller(true); // Attiva eventuale ragno;
if (_spider && xvt_vobj_is_focusable(w))
// Attiva eventuale ragno;
static int _spider = (ADVANCED_GRAPHICS && is_power_reseller(true)) ?
ini_get_int(CONFIG_GUI, "Colors", "TreeView", 3) : 0;
if (_spider>=2 && xvt_vobj_is_focusable(w))
{
RCT client; xvt_vobj_get_client_rect(w, &client);
CBRUSH brush_yellow;
brush_yellow.color = _spider == 4 ? COLOR_WHITE : COLOR_YELLOW;
brush_yellow.pat = PAT_SOLID;
CPEN pen_thick; pen_thick.color = COLOR_BLACK;
pen_thick.pat = PAT_SOLID; pen_thick.style =P_SOLID;
pen_thick.width = 2;
const int nRadius = 48;
if (client.right > 2*nRadius && client.bottom > 2*nRadius)
{
const PNT p0 = { client.top+3*nRadius/2, client.right-3*nRadius/2 }; // Centro dello smile
CBRUSH brush_yellow; brush_yellow.color = COLOR_YELLOW; brush_yellow.pat = PAT_SOLID;
xvt_dwin_set_std_cpen(w, TL_PEN_BLACK);
if (mode & 0x1)
{
// Disegno la faccina
xvt_dwin_set_cbrush(w, &brush_yellow);
xvt_dwin_set_cpen(w, &pen_thick);
RCT rct; xvt_rect_set(&rct, p0.h-nRadius, p0.v-nRadius, p0.h+nRadius, p0.v+nRadius);
xvt_dwin_draw_oval(w, &rct);
}
xvt_dwin_set_std_cpen(w, TL_PEN_BLACK);
if (mode & 0x2)
{
const int eye = nRadius/4;
@ -1010,6 +1020,11 @@ void draw_spider(WINDOW w, int mode, const PNT& mouse)
xvt_rect_set(&rct, p1.h-pupil+dx, p1.v-pupil+dy, p1.h+pupil+dx, p1.v+pupil+dy);
xvt_dwin_set_std_cbrush(w, TL_BRUSH_BLACK);
xvt_dwin_draw_oval(w, &rct);
xvt_dwin_set_std_cbrush(w, TL_BRUSH_WHITE);
xvt_rect_deflate(&rct, 3*pupil/2, 3*pupil/2);
xvt_rect_offset(&rct, -pupil/2, -pupil/2);
xvt_dwin_draw_oval(w, &rct);
}
// Disegno la boccuccia aperta se il mouse e' vicino
@ -1046,13 +1061,10 @@ void TSpidey_mask::on_firm_change()
WINDOW TSpidey_mask::dlg2win(short id) const
{
WINDOW w = NULL_WIN;
const int pos = id2pos(id);
if (pos >= 0)
{
const TMask_field& f = fld(pos);
if (f.is_kind_of(CLASS_WINDOWED_FIELD))
w = ((const TWindowed_field&)f).win().win();
}
TMask_field* f = find_by_id(id);
if (f && f->is_kind_of(CLASS_WINDOWED_FIELD))
w = ((const TWindowed_field*)f)->win().win();
return w;
}

View File

@ -1,135 +1,138 @@
#ifndef __BA0102_H
#define __BA0102_H
#ifndef __AUTOMASK_H
#include <automask.h>
#endif
#ifndef __TREECTRL_H
#include <treectrl.h>
#endif
#ifndef __TREE_H
#include <tree.h>
#endif
#ifndef __BA0101_H
#include "ba0101.h"
#endif
class TMenu_tree : public TBidirectional_tree
{
TMenu* _menu;
const TSubmenu* _submenu;
int _menuitem;
TString _root_id, _curr_id;
protected: // TTree
virtual void node2id(const TObject* node, TString& id) const;
public: // TTree
virtual bool goto_root();
virtual bool goto_firstson();
virtual bool goto_rbrother();
virtual bool goto_node(const TString &id);
virtual bool has_son() const;
virtual bool has_rbrother() const;
virtual TObject* curr_node() const;
virtual bool has_root() const;
virtual bool has_father() const;
virtual bool has_lbrother() const;
virtual bool goto_father();
virtual bool goto_lbrother();
virtual void curr_id(TString& id) const { id = _curr_id; }
virtual bool get_description(TString& desc) const;
virtual TImage* image(bool selected) const;
virtual bool enabled() const;
virtual bool marked() const;
public:
const TSubmenu& curr_submenu() const;
const TMenuitem& curr_item() const;
bool find_leaf(const TString& str);
bool find_string(const TString& str);
long find_node(const TString& id);
void change_root(const char* id);
void set_menu(TMenu& menu);
TMenu_tree(TMenu& menu);
virtual ~TMenu_tree() { }
};
///////////////////////////////////////////////////////////
// TSpidey_mask Intended for internal use only :-)
///////////////////////////////////////////////////////////
class TSpidey_mask : public TAutomask
{
protected: // TMask
virtual void on_firm_change();
virtual bool stop_run(KEY k);
virtual bool on_key(KEY k);
protected:
WINDOW dlg2win(short id) const;
public:
TSpidey_mask();
};
///////////////////////////////////////////////////////////
// TMenulist_field
///////////////////////////////////////////////////////////
class TMenulist_field : public TWindowed_field
{
protected: // TWindowed_field
virtual TField_window* create_window(int x, int y, int dx, int dy, WINDOW parent);
public:
void set_menu(TMenu_tree& mt);
void create(short dlg, int x, int y, int dx, int dy, WINDOW parent);
void curr_item(TToken_string& id) const;
TMenulist_field(TMask* m) : TWindowed_field(m) { }
virtual ~TMenulist_field() { }
};
///////////////////////////////////////////////////////////
// TExplorer_mask
///////////////////////////////////////////////////////////
class TExplorer_mask : public TSpidey_mask
{
TMenu_tree _tree;
TString _last_search_string;
protected: // TMask
virtual void update();
virtual long handler(WINDOW win, EVENT* ep);
virtual bool on_key(KEY k);
virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
protected:
virtual void select_tree_current();
enum { DLG_TREE = 101, DLG_LIST,
DLG_SHRINK = 201, DLG_PREF, DLG_ADDPREF };
public:
TExplorer_mask(TMenu& menu);
};
// Utilities
void synchronize_tree_field(TTree_field& tf);
void enable_options_menu(bool on);
bool can_be_transparent(const TImage& i);
void draw_spider(WINDOW win, int mode, const PNT& mouse);
const TString& get_logo();
int fast_hypot(int x, int y);
#endif
#ifndef __BA0102_H
#define __BA0102_H
#ifndef __AUTOMASK_H
#include <automask.h>
#endif
#ifndef __TREECTRL_H
#include <treectrl.h>
#endif
#ifndef __TREE_H
#include <tree.h>
#endif
#ifndef __BA0101_H
#include "ba0101.h"
#endif
class TMenu_tree : public TBidirectional_tree
{
TMenu* _menu;
const TSubmenu* _submenu;
int _menuitem;
TString _root_id, _curr_id;
protected: // TTree
virtual void node2id(const TObject* node, TString& id) const;
public: // TTree
virtual bool goto_root();
virtual bool goto_firstson();
virtual bool goto_rbrother();
virtual bool goto_node(const TString &id);
virtual bool has_son() const;
virtual bool has_rbrother() const;
virtual TObject* curr_node() const;
virtual bool has_root() const;
virtual bool has_father() const;
virtual bool has_lbrother() const;
virtual bool goto_father();
virtual bool goto_lbrother();
virtual void curr_id(TString& id) const { id = _curr_id; }
virtual bool get_description(TString& desc) const;
virtual TImage* image(bool selected) const;
virtual bool enabled() const;
virtual bool marked() const;
public:
const TSubmenu& curr_submenu() const;
const TMenuitem& curr_item() const;
bool find_leaf(const TString& str);
bool find_string(const TString& str);
long find_node(const TString& id);
void change_root(const char* id);
void set_menu(TMenu& menu);
const TMenu& get_menu() const { CHECK(_menu, "Null menu"); return *_menu; }
TMenu_tree(TMenu& menu);
virtual ~TMenu_tree() { }
};
///////////////////////////////////////////////////////////
// TSpidey_mask Intended for internal use only :-)
///////////////////////////////////////////////////////////
class TSpidey_mask : public TAutomask
{
protected: // TMask
virtual void on_firm_change();
virtual bool stop_run(KEY k);
virtual bool on_key(KEY k);
protected:
WINDOW dlg2win(short id) const;
public:
TSpidey_mask();
};
///////////////////////////////////////////////////////////
// TMenulist_field
///////////////////////////////////////////////////////////
class TMenulist_field : public TWindowed_field
{
protected: // TWindowed_field
virtual TField_window* create_window(int x, int y, int dx, int dy, WINDOW parent);
public:
void set_menu(TMenu_tree& mt);
void create(short dlg, int x, int y, int dx, int dy, WINDOW parent);
void curr_item(TToken_string& id) const;
TMenulist_field(TMask* m) : TWindowed_field(m) { }
virtual ~TMenulist_field() { }
};
///////////////////////////////////////////////////////////
// TExplorer_mask
///////////////////////////////////////////////////////////
class TExplorer_mask : public TSpidey_mask
{
TMenu_tree _tree;
TString _last_search_string;
protected: // TMask
virtual void update();
virtual long handler(WINDOW win, EVENT* ep);
virtual bool on_key(KEY k);
virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
protected:
virtual void select_tree_current();
enum { DLG_TREE = 101, DLG_LIST, DLG_SHRINK = 201, DLG_PREF, DLG_ADDPREF };
public:
TExplorer_mask(TMenu& menu);
};
///////////////////////////////////////////////////////////
// Utilities
///////////////////////////////////////////////////////////
void synchronize_tree_field(TTree_field& tf);
void enable_options_menu(bool on);
bool can_be_transparent(const TImage& i);
void draw_spider(WINDOW win, int mode, const PNT& mouse);
const TString& get_logo();
int fast_hypot(int x, int y);
#endif

View File

@ -118,7 +118,6 @@ void TBook_window::update()
if (_ctrl == NULL_WIN)
{
clear(NORMAL_BACK_COLOR);
if (ADVANCED_GRAPHICS)
{
WINDOW w = win();
@ -127,19 +126,14 @@ void TBook_window::update()
{
if (_back.ok())
_back.draw(w, rctw, 'L', 'T', '*'); // Disegna sfondo in alto
if (!_logo.ok())
set_logo(get_logo());
if (_logo.ok())
{
const RCT& r = _logo.draw(w, rctw, 'R', 'B', '-'); // Disegna logo in basso
/* if (_back.ok() && r.top >= 64)
{
rctw.bottom = r.top;
_back.draw(w, rctw, 'R', 'T', '*'); // Disegna sfondo in alto
}
*/
}
_logo.draw(w, rctw, 'R', 'B', '-'); // Disegna logo in basso
const PNT pnt = { 0, 0 };
draw_spider(w, 0x3, pnt);
const PNT mouse = { 0, 0 };
draw_spider(w, 0x3, mouse);
}
}
}
@ -177,6 +171,10 @@ long TBook_window::handler(WINDOW win, EVENT* ep)
{
switch (ep->type)
{
case E_UPDATE:
if (_ctrl == NULL_WIN)
update();
return _ctrl ? -1 : 0;
case E_MOUSE_MOVE:
if (_ctrl == NULL_WIN)
draw_spider(win, 0x3, ep->v.mouse.where);
@ -198,7 +196,7 @@ long TBook_window::handler(WINDOW win, EVENT* ep)
TString8 pid; pid << ep->v.process.pid;
switch (ep->v.process.msg_id)
{
case 0:
case E_CREATE:
{
TString16 pg; pg << (long)page_win(pages()-1);
_alfano.add(pid, pg); // Memorizza la pagina che ospita il processo
@ -260,9 +258,10 @@ short TBook_window::add_page(const TMenuitem& mi)
wd.v.ctl.font_id = xvtil_default_font();
wd.v.ctl.flags = CTL_FLAG_TAB_BOTTOM; // should be wxCHECK_VERSION(2,8,9)
wd.v.ctl.flags |= CTL_FLAG_CENTER_JUST; // old compatibility flags
if (!CAMPI_SCAVATI) // metro style
wd.v.ctl.flags |= WSF_NO_TASKBAR;
xvt_vobj_get_client_rect(win(), &wd.rct);
_ctrl = xvt_ctl_create_def(&wd, win(), 0L);
_ctrl = xvt_ctl_create_def(&wd, win(), (long)this); // Metro Style or 3D style
// Blocca le dimensioni del pannello (Non va micca!)
xvt_pane_set_size_range(win(), wd.rct.right, wd.rct.right, wd.rct.right);
enable_options_menu(false); // Disabilita le opzioni
@ -352,12 +351,9 @@ void TBook_window::set_logo(const char* logo)
if (_logo.ok())
{
/*
if (is_power_reseller(true))
{
#ifdef DBG
const clock_t start = clock();
#endif
const short w = _logo.width();
const short h = _logo.height();
const short h2 = h/4;
@ -372,21 +368,6 @@ void TBook_window::set_logo(const char* logo)
short tw, th; xvt_image_get_dimensions(tile, &tw, &th);
if (tw > 0 && th > 0)
{
// Elegante ma lento
/* RCT src; xvt_rect_set(&src, 0, 0, tw, th);
for (short y = 0; y < h2; y += th)
{
for (short x = 0; x < w; x += tw)
{
RCT dst; xvt_rect_set(&dst, x, y+h, x+tw, y+th+h);
xvt_image_transfer(big, tile, &dst, &src);
}
}
*/
#ifdef DBG
// #pragma omp parallel for
#endif
// Bovino ma veloce
for (short y = 0; y < h2; y++)
{
for (short x = 0; x < w; x++)
@ -399,9 +380,6 @@ void TBook_window::set_logo(const char* logo)
}
// Copia tutti i pixel non neri/grigi/bianchi
#ifdef DBG
#pragma omp parallel for
#endif
for (short y = 0; y < h2; y++)
{
const double weight = 0.5+double(y)/double(2*h2);
@ -424,13 +402,11 @@ void TBook_window::set_logo(const char* logo)
}
}
}
#ifdef DBG
const clock_t tot = clock() - start;
#endif
_logo.set(big);
}
else
*/
{
if (can_be_transparent(_logo))
_logo.convert_transparent_color(NORMAL_BACK_COLOR);
@ -494,7 +470,6 @@ TBook_window::TBook_window(int x, int y, int dx, int dy,
WINDOW parent, TWindowed_field* owner)
: TControl_host_window(x, y, dx, dy, parent, owner), _logo(""), _back("")
{
set_logo(get_logo());
}
TBook_window::~TBook_window()
@ -724,6 +699,58 @@ void TOutlook_mask::on_firm_change()
TSpidey_mask::on_firm_change();
}
bool TOutlook_mask::run_child(const TMenuitem& mi)
{
bool ok = false;
// ba1 e ba2 sono programmi di manutenzione da eseguire in modo esclusivo
if (mi.run_modal())
{
if (book_field().pages() > 0)
return warning_box(TR("Questa applicazione richiede che vengano chiuse tutte le altre!"));
ok = mi.perform(); // Esegui in sincrono e a tutto schermo
if (installing()) // when ba1 -6
stop_run(K_FORCE_CLOSE);
} else
if (mi.run_fullscreen())
{
ok = mi.perform(); // Esegui in asincrono a pieno schermo
}
else
{
// Crea una pagina per accogliere la nuova applicazione asincrona
const short pg = add_page(mi);
if (pg >= 0)
{
TBook_field& bf = book_field();
ok = mi.perform();
if (ok) // Esegui in asincrono in pagina nuova
{
for (int i = 0; i < 20; i++)
{
xvt_sys_sleep(500);
if (xvt_win_get_children_count(bf.page_win(pg)) != 0)
break;
}
int ico = mi.icon();
if (ico <= 0 || ico == ICON_RSRC)
{
const int area = get_int(DLG_LOOK);
if (area > 0 && area < _icon.items())
ico = _icon.get_int(area);
else
ico = ICON_RSRC;
}
set_page_caption(pg, mi.caption(), ico);
}
else
bf.remove_page(pg); // Rimuovi pagina in caso d'errore
}
}
return ok;
}
bool TOutlook_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
{
switch (o.dlg())
@ -740,55 +767,9 @@ bool TOutlook_mask::on_field_event(TOperable_field& o, TField_event e, long joll
mi.perform();
}
else
{
TBook_field& bf = book_field();
// ba1 e ba2 sono programmi di manutenzione da eseguire in modo esclusivo
if (mi.run_modal())
{
if (bf.pages() > 0)
return warning_box(TR("Questa applicazione richiede che vengano chiuse tutte le altre!"));
mi.perform(); // Esegui in sincrono e a tutto schermo
if (installing()) // when ba1 -6
stop_run(K_FORCE_CLOSE);
} else
if (mi.run_fullscreen())
{
mi.perform(); // Esegui in asincrono a pieno schermo
}
else
{
// Crea una pagina per accogliere la nuova applicazione asincrona
const short pg = add_page(mi);
if (pg >= 0)
{
if (mi.perform()) // Esegui in asincrono in pagina nuova
{
for (int i = 0; i < 20; i++)
{
xvt_sys_sleep(500);
if (xvt_win_get_children_count(bf.page_win(pg)) != 0)
break;
}
int ico = mi.icon();
if (ico <= 0 || ico == ICON_RSRC)
{
const int area = get_int(DLG_LOOK);
if (area > 0 && area < _icon.items())
ico = _icon.get_int(area);
else
ico = ICON_RSRC;
}
set_page_caption(pg, mi.caption(), ico);
}
else
book_field().remove_page(pg); // Rimuovi pagina inm caso d'errore
}
}
}
run_child(mi);
}
}
} else
if (e == fe_modify)
{
// Permette l'aggiunta ai preferiti per i non NON radice
@ -833,7 +814,7 @@ bool TOutlook_mask::on_field_event(TOperable_field& o, TField_event e, long joll
of.clear();
TString caption;
int ico = 10219;
const int ico = 10219;
of.add_item(ico, TR("Menu principale"), 0);
_icon.add_long(ico);
TToken_string id("MENU_000", '/');
@ -877,7 +858,7 @@ bool TOutlook_mask::on_field_event(TOperable_field& o, TField_event e, long joll
return true;
}
TOutlook_mask::TOutlook_mask(TMenu& menu) : _tree(menu), _locked(false)
TOutlook_mask::TOutlook_mask(TMenu& menu, bool metro) : _tree(menu), _locked(false)
{
xvtil_statbar_destroy(); // Ammazza status bar "inutile"
RCT rct; xvt_vobj_get_client_rect(TASK_WIN, &rct);
@ -885,7 +866,7 @@ TOutlook_mask::TOutlook_mask(TMenu& menu) : _tree(menu), _locked(false)
WINDOW panel = page_win(0);
xvt_vobj_move(panel, &rct); // Resiza la maschera in modo da occupare lo spazio liberato
menu.set_mask_mode(3); // Outlook mode
menu.set_mask_mode(metro ? 4 : 3); // Outlook mode
const int w = 24;
const int h = rows() / 2;
@ -893,7 +874,11 @@ TOutlook_mask::TOutlook_mask(TMenu& menu) : _tree(menu), _locked(false)
TTree_field& trifola = add_tree(DLG_TREE, 0, 0, 0, w, h);
trifola.set_tree(&_tree);
TOutlook_field* of = new TOutlook_field(this);
TOutlook_field* of = NULL;
if (metro)
of = new TMetrolist_field(this);
else
of = new TOutlook_field(this);
of->create(DLG_LOOK, 0, h, w, h, panel);
add_field(of);
@ -904,6 +889,7 @@ TOutlook_mask::TOutlook_mask(TMenu& menu) : _tree(menu), _locked(false)
xvt_pane_add(panel, dlg2win(DLG_TREE), "Menu", 1, 0); // Left upper pane
xvt_pane_add(panel, dlg2win(DLG_LOOK), "Aree", 1, 0); // Left lower pane
xvt_pane_add(panel, dlg2win(DLG_MAIN), "Main", 0, 0); // Main pane
save_perspective(0); // Salva default
load_perspective(1); // Carica custom
set_handlers();

View File

@ -33,12 +33,21 @@ protected:
void save_perspective(int per);
void load_perspective(int per);
const TMenu& get_menu() const { return _tree.get_menu(); }
public:
virtual long handler(WINDOW w, EVENT* ep); // Used by E_PROCESS
bool run_child(const TMenuitem& mi); // Used by metro mask
TOutlook_mask(TMenu& menu);
TOutlook_mask(TMenu& menu, bool metro = false);
~TOutlook_mask();
};
class TMetro_mask : public TOutlook_mask
{
public:
TMetro_mask(TMenu& menu);
~TMetro_mask();
};
#endif

696
ba/ba0105.cpp Normal file
View File

@ -0,0 +1,696 @@
#include "ba0103.h"
#include <applicat.h>
#include <config.h>
#include <dongle.h>
#include <image.h>
#include <isamrpc.h>
#include <reprint.h>
#include <isamrpc.h>
///////////////////////////////////////////////////////////
// Utilities
///////////////////////////////////////////////////////////
static int draw_text(WINDOW win, const char* txt, RCT& rct, char halign='L', char valign='T')
{
const int max_row_width = xvt_rect_get_width(&rct);
int lines = 0;
if (xvt_dwin_get_text_width(win, txt, -1) < max_row_width)
{
advanced_draw_text_line(win, txt,rct, halign, valign);
lines = 1;
}
else
{
TString_array para;
TToken_string p(txt, '\n');
para.destroy();
FOR_EACH_TOKEN(p, line)
para.add(line);
for (int i = 0; i < para.items(); i++)
{
TString& row = para.row(i);
int pix = xvt_dwin_get_text_width(win, row, -1);
if (pix > max_row_width)
{
int good_len = 0;
const int first_space = row.find(' ');
if (first_space >= 0)
{
// Linea con almeno uno spazio
for (int i = first_space; row[i]; i++) if (row[i] == ' ')
{
pix = xvt_dwin_get_text_width(win, row, i);
if (pix <= max_row_width)
good_len = i;
else
break;
}
}
if (good_len == 0) // Puo' succedere per linee senza spazi o con parole lunghissime
{
for (good_len = row.len(); good_len > 0; good_len--)
{
const int pix = xvt_dwin_get_text_width(win, row, good_len);
if (pix < max_row_width)
break;
}
}
TString next_row = row.mid(good_len);
next_row.ltrim();
para.insert(next_row, i+1);
row.cut(good_len);
}
}
advanced_draw_paragraph(win, para, rct, halign, valign, CHARY);
lines = para.items();
}
return lines;
}
///////////////////////////////////////////////////////////
// TMetro_menu
///////////////////////////////////////////////////////////
static TOutlook_mask* _main_mask = NULL;
class TMetro_item : public TSortable
{
RCT _rct;
protected:
virtual int compare(const TSortable& s) const
{
const TMetro_item& mi = (const TMetro_item&)s;
return mi.score() - score();
}
virtual COLOR back() const { return REQUIRED_BACK_COLOR; }
virtual COLOR fore() const { return NORMAL_COLOR; }
virtual int icon() const { return 0; }
virtual const TString& caption() const pure { return EMPTY_STRING; }
virtual const TMetro_item& item(int) const { return *this; }
public:
virtual void sort() { }
virtual int score() const { return 0; }
virtual const TString& code() const pure { return EMPTY_STRING; }
virtual PNT size_min() const { PNT p = { 32+2*CHARY, 16*CHARX }; return p; }
virtual void draw(WINDOW win, const RCT& rct);
virtual bool on_click(const PNT& pnt) { return xvt_rect_has_point(&_rct, pnt) != 0; }
const RCT& rect() const { return _rct; }
TMetro_item() { memset(&_rct, 0, sizeof(_rct)); }
};
void TMetro_item::draw(WINDOW win, const RCT& rct)
{
_rct = rct; // store for hit test
xvt_dwin_set_std_cpen(win, TL_PEN_HOLLOW);
CBRUSH brush;
brush.color = back();
brush.pat = PAT_SOLID;
xvt_dwin_set_cbrush(win, &brush);
xvt_dwin_draw_rect(win, &rct);
if (caption().full())
{
xvt_dwin_set_back_color(win, back());
xvt_dwin_set_fore_color(win, fore());
}
}
class TMetro_cell : public TMetro_item
{
const TMenuitem* _mi;
int _count; // usage count
TDate _last; // last run
protected:
virtual int score() const { return _count; }
virtual int compare(const TSortable& s) const;
virtual const TDate& last_run() const { return _last; }
virtual const TString& code() const { return _mi->action(); }
virtual const TString& caption() const { return _mi->caption(); }
virtual const TString& message() const { return EMPTY_STRING; }
virtual int icon() const { return _mi->icon(); }
virtual bool on_click(const PNT& pnt);
virtual void draw(WINDOW win, const RCT& rct);
public:
TMetro_cell(const TMenuitem& mi, int cnt, const TDate& last) : _mi(&mi), _count(cnt), _last(last) {}
};
int TMetro_cell::compare(const TSortable& s) const
{
const TMetro_cell& mi = (const TMetro_cell&)s;
int cmp = TMetro_item::compare(mi);
if (cmp == 0)
cmp = mi._last - _last;
return cmp;
}
void TMetro_cell::draw(WINDOW win, const RCT& rct)
{
TMetro_item::draw(win, rct); // store for hit test
const int margin = 2;
RCT area = rct; xvt_rect_deflate(&area, margin, margin);
if (caption().full())
{
draw_text(win, caption(), area, 'L', 'B');
area.bottom -= CHARY;
if (xvt_rect_get_height(&area) > 32)
{
int ico = icon();
if (ico <= 0) ico = ICON_RSRC;
xvt_dwin_draw_icon(win, area.left, area.top, ico);
area.top += 32+margin;
}
}
if (xvt_rect_get_height(&area) >= CHARY)
draw_text(win, message(), area, 'C', 'C');
}
bool TMetro_cell::on_click(const PNT& pnt)
{
bool go = TMetro_item::on_click(pnt);
if (go && _main_mask)
{
go = _main_mask->run_child(*_mi);
if (go)
{
_count++;
_last = TODAY;
}
}
return go;
}
///////////////////////////////////////////////////////////
// TMetro_setup_cell
///////////////////////////////////////////////////////////
class TMetro_setup_cell : public TMetro_cell
{
int _updates;
protected:
virtual COLOR back() const { return _updates > 0 ? FOCUS_BACK_COLOR : TMetro_cell::back(); }
virtual const TString& message() const;
public:
TMetro_setup_cell(const TMenuitem& mi, int cnt, const TDate& last);
};
const TString& TMetro_setup_cell::message() const
{
TString& tmp = get_tmp_string();
tmp.format(FR("%d aggiornamenti disponibili"), _updates);
return tmp;
}
TMetro_setup_cell::TMetro_setup_cell(const TMenuitem& mi, int cnt, const TDate& last) : TMetro_cell(mi, cnt, last), _updates(0)
{
const TDongle& don = dongle();
if (don.administrator() && ini_get_int(CONFIG_INSTALL, "Main", "Type") != 2 && xvt_net_get_status()>=2)
{
int y,r,t,p;
main_app().get_version_info(y, r, t, p);
TString dir; dir.format("/release%02d0/*a.ini", r);
TString_array patches;
http_dir("http://93.146.247.172", dir, patches);
TArray modules;
FOR_EACH_ARRAY_ROW(patches, i, row)
{
const TString& mod = row->left(2);
const word aut = don.module_name2code(mod);
if (don.active(aut))
{
TToken_string* p = (TToken_string*)modules.objptr(aut);
if (p == NULL)
{
p = new TToken_string;
p->add(ini_get_int(CONFIG_GENERAL, mod, "Patch"));
modules.add(p);
}
if (p->items() == 1)
{
const int local_patch = p->get_int(0);
const int remote_patch = atoi(row->mid(2));
if (remote_patch > local_patch)
{
p->add(remote_patch, 1);
_updates++;
}
}
}
}
}
}
///////////////////////////////////////////////////////////
// TMetro_dbase_cell
///////////////////////////////////////////////////////////
class TMetro_dbase_cell : public TMetro_cell
{
clock_t _next_update;
int _users;
protected:
int users() const;
virtual COLOR back() const { return users() > 1 ? FOCUS_BACK_COLOR : TMetro_cell::back(); }
virtual const TString& message() const;
public:
TMetro_dbase_cell(const TMenuitem& mi, int cnt, const TDate& last) : TMetro_cell(mi, cnt, last), _users(0) {}
};
int TMetro_dbase_cell::users() const
{
const clock_t now = clock();
if (_users <= 0 || now > _next_update)
{
TRelation users(LF_USER);
TCursor connections(&users, "CONNECTED=\"X\"");
(int&)_users = max(1, connections.items());
(clock_t&)_next_update = clock() + 15*CLOCKS_PER_SEC;
}
return _users;
}
const TString& TMetro_dbase_cell::message() const
{
TString& tmp = get_tmp_string();
const int u = users();
if (u > 1)
tmp.format(FR("%d utenti connessi"), u);
else
tmp.format(FR("Un utente connesso"));
return tmp;
}
///////////////////////////////////////////////////////////
// TMetro_backup_cell
///////////////////////////////////////////////////////////
class TMetro_backup_cell : public TMetro_cell
{
long days() const { return TDate(TODAY) - last_run(); }
protected:
virtual COLOR back() const { return days() > 7 ? FOCUS_BACK_COLOR : TMetro_cell::back(); }
virtual const TString& message() const;
public:
TMetro_backup_cell(const TMenuitem& mi, int cnt, const TDate& last) : TMetro_cell(mi, cnt, last) {}
};
const TString& TMetro_backup_cell::message() const
{
TString& tmp = get_tmp_string();
const int d = days();
if (d > 0)
tmp.format(FR("%d giorni dall'ultimo backup"), d);
return tmp;
}
///////////////////////////////////////////////////////////
// TMetro_panel
///////////////////////////////////////////////////////////
class TMetro_panel : public TMetro_item
{
TString _name;
int _icon;
TArray _child;
protected:
virtual int score() const;
virtual const TString& code() const { return _name; }
virtual const TString& caption() const { return _name; }
virtual int icon() const { return _icon; }
virtual COLOR fore() const { return PROMPT_COLOR; }
virtual COLOR back() const { return _name.full() ? MASK_BACK_COLOR : NORMAL_BACK_COLOR; }
virtual PNT size_min() const { PNT p = TMetro_item::size_min(); p.v = p.v * 2 + 32; p.h *= 3; return p; }
virtual const TMetro_item& item(int i) const { return (const TMetro_item&)_child[i]; }
public:
virtual void sort();
virtual void draw(WINDOW win, const RCT& rct);
virtual bool on_click(const PNT& pnt);
TMetro_cell* add_item(const TMenuitem& item, int cnt, const TDate& last);
TMetro_panel* add_panel(const TString& name, int icon);
bool is_empty() const { return _child.empty(); }
TMetro_panel(const TString& name, int icon) : _name(name), _icon(icon) {}
};
#define FOR_EACH_CHILD(i) TMetro_item* i; for (int _r##i = 0; (i = (TMetro_item*)_child.objptr(_r##i)) != NULL; _r##i++)
int TMetro_panel::score() const
{
int max_score = 0;
FOR_EACH_CHILD(i)
{
const int s = i->score();
if (s > max_score)
max_score = s;
}
return max_score;
}
void TMetro_panel::sort()
{
_child.sort();
FOR_EACH_CHILD(i)
i->sort();
}
TMetro_cell* TMetro_panel::add_item(const TMenuitem& mi, int cnt, const TDate& last)
{
// check for duplicates
FOR_EACH_CHILD(i)
if (mi.action() == i->code())
return (TMetro_cell*)i;
TMetro_cell* mir = NULL;
if (mi.action() == "ba1 -0")
mir = new TMetro_dbase_cell(mi, cnt, last); else
if (mi.action() == "ba1 -6")
mir = new TMetro_setup_cell(mi, cnt, last); else
if (mi.action() == "ba2 -1")
mir = new TMetro_backup_cell(mi, cnt, last);
else
mir = new TMetro_cell(mi, cnt, last);
_child.add(mir);
return mir;
}
TMetro_panel* TMetro_panel::add_panel(const TString& name, int icon)
{
// check for duplicates
FOR_EACH_CHILD(i)
if (i->code() == name)
return (TMetro_panel*)i;
TMetro_panel* mp = new TMetro_panel(name, icon);
_child.add(mp);
return mp;
}
void TMetro_panel::draw(WINDOW win, const RCT& rct)
{
TMetro_item::draw(win, rct);
const int tot = _child.items();
const int margin = 4;
RCT area = rct;
area.left += margin; area.top += margin;
if (caption().full())
{
RCT txt = area; txt.bottom = area.top + 36;
if (icon())
{
xvt_dwin_draw_icon(win, txt.left, txt.top, icon());
txt.left += 36;
}
advanced_draw_text_line(win, caption(), txt, 'L', 'C');
area.top = txt.bottom;
}
const TMetro_item& mi = item(0);
const int width = xvt_rect_get_width(&area);
const int height = xvt_rect_get_height(&area);
const int cols = width / mi.size_min().h;
const int rows = height / mi.size_min().v;
const int drawables = rows * cols;
for (int i = 0; i < tot && i < drawables; i++)
{
const int x = i % cols, y = i / cols;
RCT r;
r.left = area.left + width * x / cols;
r.right = area.left + width * (x+1) / cols - margin;
r.top = area.top + height * y / rows;
r.bottom = area.top + height * (y+1) / rows - margin;
TMetro_item& mi = *(TMetro_item*)_child.objptr(i);
mi.draw(win, r);
}
}
bool TMetro_panel::on_click(const PNT& pnt)
{
const bool go = TMetro_item::on_click(pnt);
if (go)
{
FOR_EACH_CHILD(i)
if (i->on_click(pnt))
{
sort();
break;
}
}
return go;
}
///////////////////////////////////////////////////////////
// TMetro_menu
///////////////////////////////////////////////////////////
class TMetro_menu : public TMetro_panel
{
TWindow* _book;
TImage* _logo;
protected:
int find_icon(const TMenuitem& mi, const TSubmenu& node, TAssoc_array& visited) const;
bool add_item(const TMenuitem& mi, int cnt, const TDate& d);
void find_actions(const TSubmenu& sm, const TArray& actions) const;
virtual void draw(WINDOW win, RCT& rct);
static long handler(WINDOW win, EVENT* ep);
public:
void create(TWindow* book_win, const TMenu& menu);
TWindow* book() const { return _book; }
TMetro_menu() : TMetro_panel(EMPTY_STRING, 0), _book(NULL), _logo(NULL) {}
};
static TMetro_menu _metro_menu;
void TMetro_menu::draw(WINDOW win, RCT& rct)
{
TMetro_panel::draw(win,rct);
if (_logo == NULL)
_logo = new TImage(get_logo());
if (_logo->ok())
{
RCT child = item(0).rect();
const int dx = rct.right - child.right;
const int dy = rct.bottom - child.bottom;
xvt_rect_offset(&child, dx, dy);
xvt_dwin_set_std_cbrush(win, TL_BRUSH_WHITE);
xvt_dwin_draw_rect(win, &child);
_logo->draw(win, child, 'C', 'C', '*');
}
}
long TMetro_menu::handler(WINDOW win, EVENT* ep)
{
if (ep->type == E_UPDATE)
{
if (xvt_win_get_children_count(win) == 0) // Visibility test
{
RCT rct; xvt_vobj_get_client_rect(win, &rct);
rct.bottom = ep->v.update.rct.bottom;
_metro_menu.draw(win, rct);
}
return 0;
}
if (ep->type == E_MOUSE_DOWN)
{
if (_metro_menu.on_click(ep->v.mouse.where))
return 0;
}
return _metro_menu.book()->handler(win, ep);
}
// 0 = not found; -1 = no icon; >0 = icon
int TMetro_menu::find_icon(const TMenuitem& mi, const TSubmenu& node, TAssoc_array& visited) const
{
int ico = 0;
for (int i = 0; ico == 0 && i < node.items(); i++)
{
const TMenuitem& sm = node.item(i);
if (sm.is_program())
{
if (mi.action() == sm.action())
{
ico = -1;
break;
}
} else
if (sm.is_submenu())
{
const TSubmenu* sub = sm.child_submenu();
if (sub && !visited.is_key(sub->name()))
{
visited.add(sub->name());
ico = find_icon(mi, *sub, visited);
if (ico < 0 && sm.icon() > 0)
ico = sm.icon();
}
}
}
return ico;
}
bool TMetro_menu::add_item(const TMenuitem& mi, int cnt, const TDate& last)
{
const TString& action = mi.action();
TString4 mod = action.left(2);
TString desc;
int ico = 0;
if ((mod == "ba" && action[2]<='2') || action.find("iewer")>= 0)
{
if (!dongle().administrator())
return false;
mod = "sy";
ico = 10210;
desc = TR("Sistema");
}
else
{
const word idx = dongle().module_name2code(mod);
desc = dongle().module_code2desc(idx);
TMenu& menu = mi.menu();
const TSubmenu* root = menu.find("MENU_000");
if (root)
{
TAssoc_array visited;
visited.add(root->name());
visited.add("MENU_PREFERITI)");
ico = find_icon(mi, *root, visited);
}
if (ico <= 0)
ico = ICON_RSRC;
}
TMetro_panel* a = add_panel(desc, ico);
return a ? (a->add_item(mi, cnt, last) != NULL) : false;
}
struct TFreq_info : public TString
{
const TMenuitem* _mi;
int _freq;
TDate _last;
double _score;
TFreq_info(const TString& cmd, int f, const TDate& last) : TString(cmd), _mi(NULL), _freq(f), _last(last), _score(0.8) {}
};
void TMetro_menu::find_actions(const TSubmenu& sm, const TArray& actions) const
{
if (sm.enabled() && sm.name() != "MENU_PREFERITI")
{
for (int i = 0; i < sm.items(); i++)
{
const TMenuitem& mi = sm[i];
if (mi.enabled() && mi.is_program())
{
FOR_EACH_ARRAY_ITEM(actions, a, itm)
{
TFreq_info& fi = *(TFreq_info*)itm;
if (fi._score < 1.0)
{
const double score = xvt_str_fuzzy_compare_ignoring_case(fi, mi.action());
if (score > fi._score)
{
fi._score = score;
fi._mi = &mi;
}
}
}
}
}
}
}
void TMetro_menu::create(TWindow* book, const TMenu& menu)
{
const int def_cnt = 999999;
const TDate def_dat(TODAY);
/*
const TSubmenu* pref = menu.find("MENU_PREFERITI");
if (pref)
{
for (int i = 0; i < pref->items(); i++)
add_item(pref->item(i), def_cnt, def_dat);
}
*/
TArray freq;
TConfig gui(CONFIG_GUI, "Counters");
TAssoc_array& cmds = gui.list_variables();
TToken_string pair;
FOR_EACH_ASSOC_OBJECT(cmds, obj, cmd, cnt)
{
pair = *(TString*)cnt;
freq.add(new TFreq_info(cmd, pair.get_int(0), TDate(pair.get_long(1))));
}
if (dongle().administrator())
{
const char* cmd[] = { "ba1 -0", "ba1 -6", "ba2 -1",
"setup/TeamviewerQS_it.exe", NULL };
for (int i = 0; cmd[i]; i++)
{
TFreq_info* fi = new TFreq_info(cmd[i], def_cnt-i, def_dat);
freq.add(fi);
}
}
TAssoc_array& am = (TAssoc_array&)menu; // cheating :-)
FOR_EACH_ASSOC_OBJECT(am, obj, name, sub)
find_actions(*(const TSubmenu*)sub, freq);
FOR_EACH_ARRAY_ITEM(freq, i, itm)
{
const TFreq_info& fi = *(const TFreq_info*)itm;
if (fi._mi != NULL)
add_item(*fi._mi, fi._freq, fi._last);
}
sort();
_book = book;
xvt_win_set_handler(book->win(), handler); // Nasty code injection
}
///////////////////////////////////////////////////////////
// TMetro_mask
///////////////////////////////////////////////////////////
TMetro_mask::TMetro_mask(TMenu& menu) : TOutlook_mask(menu, true)
{
TWindow& bw = ((TWindowed_field&)book_field()).win();
_metro_menu.create(&bw, menu);
_main_mask = this;
}
TMetro_mask::~TMetro_mask()
{
_main_mask = NULL;
}

View File

@ -62,12 +62,13 @@ BEGIN
//ITEM "1|Albero" **ATTENZIONE!!**Dalla 10.0 in avanti lasciare commentato!!!
ITEM "2|Explorer"
ITEM "3|Outlook"
ITEM "4|Metro"
FIELD TreeView
END
RADIOBUTTON 217 1 16
BEGIN
PROMPT 44 5 "Interlinea "
PROMPT 44 6 "Interlinea "
ITEM "-1|Automatica"
ITEM "0|Minima"
ITEM "4|Normale"

View File

@ -82,9 +82,9 @@ TRec_sheet::TRec_sheet(int logicnum, const char * tab)
_descfname.format("%s/d%s.des", DESCDIR, (const char *) _tab);
else
_descfname.format("%s/d%d.des", DESCDIR, _dir.num());
FILE * fd = NULL;
if (!fexist(_descfname) && (fd = fopen(_descfname, "w")) == NULL)
if (!fexist(_descfname) && fopen_s(&fd, _descfname, "w") != 0)
error_box(TR("Impossibile creare il file delle descrizioni"));
else
{
@ -100,9 +100,11 @@ TRec_sheet::TRec_sheet(TExternisamfile* file) : _descr(NULL)
_external = TRUE;
_mask = new TMask("ba1100d");
const FileDes& d = prefix().get_filedes(file->num());
//const FileDes& d = prefix().get_filedes(file->num());
//_dir.filedesc() = d;
_dir.get_ext(file->num());
const RecDes& r = prefix().get_recdes(file->num());
_dir.filedesc() = d;
_rec.rec() = r;
if (_dir.len() == 0)
_rec.zero();

View File

@ -3,6 +3,7 @@
#include <applicat.h>
#include <automask.h>
#include <browfile.h>
#include <config.h>
#include <defmask.h>
#include <dongle.h>
#include <execp.h>

View File

@ -1,5 +1,6 @@
#include <applicat.h>
#include <automask.h>
#include <config.h>
#include <execp.h>
#include <prefix.h>
#include <postman.h>

View File

@ -1,4 +1,5 @@
#include <applicat.h>
#include <config.h>
#include <execp.h>
#include <relation.h>
#include <sheet.h>

View File

@ -1,5 +1,6 @@
#include <applicat.h>
#include <automask.h>
#include <config.h>
#include <defmask.h>
#include <execp.h>
#include <prefix.h>

View File

@ -1,4 +1,5 @@
#include <applicat.h>
#include <config.h>
#include <extcdecl.h>
#include <mailbox.h>
#include <progind.h>

View File

@ -118,7 +118,7 @@ Item_09 = "Gestione dizionario", "ba2 -6", ""
Item_10 = "Query e Report", [MENU_014], "", 10217
Item_11 = "Firma digitale", "ba8 -6", ""
Item_12 = "Postino", "ba7 -0", ""
Item_13 = "Teleassistenza", "setup/TeamviewerQS_it.exe", "F", 10231
Item_13 = "Teleassistenza", "setup/TeamviewerQS_it.exe", "F", 10236
[MENU_016]
Caption = "Procedure speciali"