PORTING alla versione 4.56 di XVT piu' altre f...te

applicat.cpp  Aggiornata alla 4.5 la gestione dei 3d controls,
              corretto routing di certi E_COMMAND
              corretta gestione title di XVT_CONFIG
controls.cpp  Intercettati eventi XIE_COLMOVE e XIE_COLSIZE
              intrappolato bottone sinistro del mouse e ignorati gli altri
config.cpp    Migliorata gestione paragrafi con righe vuote
              probabile ottimizzazione del reperimento delle variabili
config.h      Tolto un CAZZ di Ferdinando
colors.cpp    Creato per gestire scelta colori
colors.h      Aggiunta funzione di conversione colori
mask.cpp      Gestione popup menu
sheet.cpp     Salvataggio colonne
msksheet.cpp  Salvataggio colonne e colorazione righe
printer.cpp   Migliorato riconoscimento fax e calcolo dimensioni foglio
tabapp.cpp    Ora prima creo la relazione e poi la maschera principale
xvtility.cpp  Aggiornata la gestione dei controlli 3D di Windows
mask.h        Aggiunto metodo per avere il numero della sottomaschera


git-svn-id: svn://10.65.10.50/trunk@3890 c028cbd2-c16b-5b4b-a496-9718f37d4682
This commit is contained in:
guy 1996-11-12 14:53:09 +00:00
parent a1095f6e04
commit bf819df0be
19 changed files with 1078 additions and 368 deletions

View File

@ -7,7 +7,7 @@
#include <stdlib.h>
#if XVT_OS == XVT_OS_WIN
# include <toolhelp.h>
#include <toolhelp.h>
#endif
#include <applicat.h>
@ -230,11 +230,20 @@ long TApplication::handler(WINDOW win, EVENT* ep)
about();
break;
default:
if (ep->v.cmd.tag > MAX_MENU_TAG)
{
WINDOW w = cur_win();
if (w != NULL_WIN && w != win)
::dispatch_e_menu(w, ep->v.cmd.tag);
}
else
{
if (ep->v.cmd.tag >= BAR_ITEM(1))
{
if(!menu(ep->v.cmd.tag))
stop_run();
}
}
break;
}
break;
@ -320,13 +329,12 @@ void TApplication::terminate()
if (_create_ok)
{
destroy(); // Distruzione files e maschere
#if XVT_OS == XVT_OS_WIN || XVT_OS == XVT_OS_NT
const word WM_WAKEUP = RegisterWindowMessage("WAKEUP");
const HTASK ht = GetCurrentTask();
SendMessage(HWND_BROADCAST, WM_WAKEUP, (unsigned int)ht, 0L);
#endif
#if XVT_OS == XVT_OS_WIN || XVT_OS == XVT_OS_NT
if (fexist("prassi.hlp"))
{
HWND hwnd = (HWND)xvt_vobj_get_attr(TASK_WIN, ATTR_NATIVE_WINDOW);
@ -440,11 +448,6 @@ void TApplication::check_parameters(
else user() = "PRASSI";
#endif
}
#if XVT_OS == XVT_OS_WIN || XVT_OS == XVT_OS_NT
const long twin_style = WSF_ICONIZABLE | WSF_SIZE | WSF_CLOSE | WSF_MAXIMIZED;
xvt_vobj_set_attr(NULL_WIN,ATTR_WIN_PM_TWIN_STARTUP_STYLE, twin_style);
#endif
}
// @doc EXTERNAL
@ -500,14 +503,24 @@ void TApplication::run(
TString caption; caption << "PRASSI S.p.A. - " << mod;
XVT_CONFIG cfg;
cfg.base_appl_name = (char*)base.name();
cfg.appl_name = (char*)(const char*)_title;
cfg.taskwin_title = (char*)(const char*)caption;
cfg.menu_bar_ID = TASK_MENUBAR+addbar;
cfg.about_box_ID = 0;
cfg.base_appl_name = (char*)base.name();
cfg.appl_name = (char*)(const char*)title;
cfg.taskwin_title = (char*)(const char*)caption;
xvt_vobj_set_attr(NULL_WIN,ATTR_WIN_PM_DRAWABLE_TWIN, TRUE);
#if XVT_OS == XVT_OS_WIN || XVT_OS == XVT_OS_NT
const long twin_style = WSF_ICONIZABLE | WSF_SIZE | WSF_CLOSE | WSF_MAXIMIZED;
xvt_vobj_set_attr(NULL_WIN,ATTR_WIN_PM_TWIN_STARTUP_STYLE, twin_style);
#ifdef ATTR_WIN_USE_CTL3D
xvt_vobj_set_attr(NULL_WIN, ATTR_WIN_USE_CTL3D, TRUE);
#endif
#endif
_application = this;
xvt_app_create(argc, argv, 0L, task_eh, &cfg);
}

98
include/colors.cpp Executable file
View File

@ -0,0 +1,98 @@
#if XVT_OS == XVT_OS_WIN
#define STRICT
#include <windows.h>
#include <commdlg.h>
#endif
#include <colors.h>
COLOR RGB2COLOR(unsigned char red, unsigned char green, unsigned char blue)
{
COLOR def = MAKE_COLOR(red, green, blue);
// Se nel colore non compare l'indice cerca di calcolarlo
const unsigned char color_index = (unsigned char)(def >> 12);
if (color_index <= 0x0 || color_index > 0xF)
{
const COLOR native_color[11] = { COLOR_RED, COLOR_GREEN, COLOR_BLUE, COLOR_CYAN,
COLOR_MAGENTA, COLOR_YELLOW, COLOR_BLACK, COLOR_DKGRAY,
COLOR_GRAY, COLOR_LTGRAY, COLOR_WHITE };
def &= 0x00FFFFFF;
for (int c = 0; c < 11; c++)
{
// Confronta solo la terna R,G,B
if (def == (native_color[c] & 0x00FFFFFF))
{
def = native_color[c];
break;
}
}
}
return def;
}
COLOR choose_color(COLOR col, WINDOW win)
{
int ok = FALSE;
#if XVT_OS == XVT_OS_WIN
CHOOSECOLOR cc;
memset(&cc, 0, sizeof(cc)); // Azzera struttura
if (win == NULL_WIN) win = TASK_WIN; // Sceglie una finestra valida
HWND hwnd = (HWND)xvt_vobj_get_attr(win, ATTR_NATIVE_WINDOW);
HDC hdc = GetDC(hwnd);
// Legge la palette di sistema
PALETTEENTRY* pe = NULL;
int max_entries = 0;
if (GetDeviceCaps(hdc, RASTERCAPS) & RC_PALETTE)
{
max_entries = GetDeviceCaps(hdc, SIZEPALETTE);
pe = new PALETTEENTRY[max_entries];
GetSystemPaletteEntries(hdc, 0, max_entries, pe);
}
ReleaseDC(hwnd, hdc);
// Definisce i 16 colori customizzabili
unsigned long custom_colors[16];
for (int c = 0; c < 16; c++)
{
if (pe)
{
const PALETTEENTRY& e = pe[c < 8 ? c : max_entries - 16 + c];
custom_colors[c] = RGB(e.peRed, e.peGreen, e.peBlue);
}
else
{
const unsigned char val = (c & 0x8) ? 255 : 127;
const unsigned char red = (c & 0x1) ? val : 0;
const unsigned char green = (c & 0x2) ? val : 0;
const unsigned char blue = (c & 0x4) ? val : 0;
custom_colors[c] = RGB(red, green, blue);
}
}
if (pe)
{
delete pe;
pe = NULL;
}
cc.lStructSize = sizeof(cc); // Setta dimensioni
cc.hwndOwner = hwnd; // Setta finestra padre
cc.rgbResult = RGB(XVT_COLOR_GET_RED(c), XVT_COLOR_GET_GREEN(c), XVT_COLOR_GET_BLUE(c));
cc.lpCustColors = custom_colors; // Fissa colori custom
cc.Flags = CC_RGBINIT; // Usa col come primo colore
ok = ChooseColor(&cc) != 0;
#endif
if (ok)
col = RGB2COLOR(GetRValue(cc.rgbResult), GetGValue(cc.rgbResult), GetBValue(cc.rgbResult));
else
col = COLOR_INVALID;
return col;
}

View File

@ -5,6 +5,9 @@
#include <xvt.h>
#endif
COLOR RGB2COLOR(unsigned char red, unsigned char green, unsigned char blue);
COLOR choose_color(COLOR col = COLOR_BLACK, WINDOW win = NULL_WIN);
extern COLOR MASK_BACK_COLOR;
extern COLOR MASK_LIGHT_COLOR;
extern COLOR MASK_DARK_COLOR;

View File

@ -1,22 +1,12 @@
#include <xvt.h>
#if XVT_OS == XVT_OS_WIN || XVT_OS == XVT_OS_NT
#include <io.h>
#else
#include <stdio.h>
#endif
#include <stdlib.h>
#include <applicat.h>
#include <colors.h>
#include <config.h>
#include <date.h>
#include <scanner.h>
#include <prefix.h>
#include <utility.h>
extern "C"
{
int rename(const char*, const char*);
};
extern "C" { int rename(const char*, const char*); };
// @doc EXTERNAL
@ -73,17 +63,18 @@ bool TConfig::_read_paragraph()
void TConfig::_write_paragraph(
ofstream& out) // @parm Indirizzo dell'utput sul quale scrivere il paragrafo
// @comm Scrive le variabili del paragrafo attivo. Nel caso il paragrafo non
// era presente viene aggiunto nel file.
// @comm Scrive sullo stream <p>out le variabili del paragrafo attivo.
{
_data.restart();
out << '[' << _paragraph << ']' << endl;
for (int i = 0; i < _data.items(); i++)
if (_data.items() > 0) // Inutile scrivere paragrafi vuoti!
{
THash_object* o = _data.get_hashobj();
out << o->key() << "\t= " << (TString&)(o->obj()) << '\n';
}
out << '[' << _paragraph << ']' << endl;
_data.restart();
for (THash_object* o = _data.get_hashobj(); o; o = _data.get_hashobj())
out << o->key() << " = " << (TString&)(o->obj()) << '\n';
out << endl;
}
}
void TConfig::_write_file()
@ -95,25 +86,32 @@ void TConfig::_write_file()
ofstream out(temp);
TString l(1024);
TString80 cnf; cnf << '[' << _paragraph << ']';
TString cnf; cnf << '[' << _paragraph << ']';
bool skip = FALSE, done = FALSE;
bool skip = FALSE, done = FALSE, skip_empty = TRUE;
while (!in.eof())
{
in.getline((char *) (const char *) l, l.size());
in.getline((char*)(const char*)l, l.size());
l.trim();
if (cnf == l)
{
// write paragraph and all variables
_write_paragraph(out);
skip = TRUE; done = TRUE;
skip = skip_empty = done = TRUE;
}
else
{
if (skip) skip = l[0] != '[';
if (!skip) out << l << '\n';
if (skip)
skip = l[0] != '[';
if (!skip)
{
const bool empty = l.empty();
if (!empty || !skip_empty)
out << l << endl;
skip_empty = empty;
}
}
}
// new paragraph
@ -132,9 +130,10 @@ void TConfig::_write_file()
void TConfig::set_paragraph(const char* section)
{
if (section != NULL && section != _paragraph)
if (section != NULL && _paragraph != section)
{
if (_dirty) _write_file();
if (_dirty)
_write_file();
_paragraph = section;
_dirty = FALSE;
_read_paragraph();
@ -159,15 +158,39 @@ bool TConfig::exist(
{
if (index >= 0)
{
TString80 vvar(var);
vvar << '(' << index << ')';
return _data.is_key(vvar);
TString key(80);
key << var << '(' << index << ')';
return _data.is_key(key);
}
return _data.is_key(var);
}
// @doc EXTERNAL
// @mfunc Elimina una variabile dal paragrafo corrente
//
// @rdesc Ritorna i seguenti valori:
//
// @flag TRUE | Se la variabile esiteva
// @flag FALSE | Se la variabile non esiteva
bool TConfig::remove(
const char* var, // @parm Nome della variabile
int index) // @parm Indice dell'elemento dell'array (default -1)
// @comm Se <p index> e' <gt>= 0 viene costruito il nome dell'elemento
// dell'array da cercare, diversamente viene cercata la variabile
// normale passata in <p var>.
{
TString key(var);
if (index >= 0)
key << '(' << index << ')';
const bool ok = _data.remove(key);
if (ok) _dirty = TRUE;
return ok;
}
// @doc EXTERNAL
// @mfunc Ritorna il valore della variabile nella sezione corrente o in
// quella specificata
//
@ -187,27 +210,26 @@ TString& TConfig::get(
// @xref <mf TConfig::get_long> <mf TConfig::get_int> <mf TConfig::get_bool>
// <mf TConfig::get_color>
{
HIDDEN TString256 s;
const char* v = var;
if (index >= 0) // Mette indice tra parentesi
{
s = var;
s << '(' << index << ')';
v = s;
}
if (section) // Cambia paragrafo se necessario
set_paragraph(section);
if (_data.is_key(v))
s = (TString&)_data[v];
else
TString* val;
if (index >= 0)
{
s = def;
if (s.not_empty())
set(var, def, section, TRUE, index);
TString v(80);
v << var << '(' << index << ')';
val = (TString*)_data.objptr(v);
}
return s;
else
val = (TString*)_data.objptr(var);
if (val == NULL) // Se non la trova inserisci il default
{
set(var, def, section, TRUE, index);
val = &get(var, NULL, index);
}
return *val;
}
// @doc EXTERNAL
@ -329,38 +351,6 @@ bool TConfig::get_bool(
return s != "" && (s == "X" || s == "ON" || s == "YES" || s == "OK" || s == "TRUE");
}
HIDDEN void RGB_COLOR(COLOR c, int& r, int& g, int& b)
{
r = int(c >> 16) & 0xFF;
g = int(c >> 8) & 0xFF;
b = int(c) & 0xFF;
}
COLOR RGB2COLOR(unsigned char red, unsigned char green, unsigned char blue)
{
COLOR def = MAKE_COLOR(red, green, blue);
// Se nel colore non compare l'indice cerca di calcolarlo
const byte color_index = byte(def >> 12);
if (color_index < 0x1 || color_index > 0xF)
{
const COLOR native_color[11] = { COLOR_RED, COLOR_GREEN, COLOR_BLUE, COLOR_CYAN,
COLOR_MAGENTA, COLOR_YELLOW, COLOR_BLACK, COLOR_DKGRAY,
COLOR_GRAY, COLOR_LTGRAY, COLOR_WHITE };
for (int c = 0; c < 11; c++)
{
if (def == (native_color[c] & 0x00FFFFFF)) // Confronta solo la terna R,G,B
{
def = native_color[c];
break;
}
}
}
return def;
}
// @doc EXTERNAL
// @mfunc Ritorna il valore del colore settato nella variabile nella
@ -389,8 +379,9 @@ COLOR TConfig::get_color(
}
else
{
int r, g, b; RGB_COLOR(def, r, g, b);
TString16 d; d.format("%d,%d,%d", r, g, b);
TString16 d;
d.format("%d,%d,%d",
XVT_COLOR_GET_RED(def), XVT_COLOR_GET_GREEN(def), XVT_COLOR_GET_BLUE(def));
set(var, d, section, TRUE, index);
}
@ -422,17 +413,18 @@ bool TConfig::set(
// implementare un array.
// <nl>Il paragrafo passato in <p section> diventa quello attivo.
if (section)
set_paragraph(section);
TString vvar(var); if (index != -1) vvar << '(' << index << ')';
bool itwas = _data.is_key(vvar);
const bool itwas = exist(var, index);
if (itwas && !force)
warning_box("Tentativo di ridefinizione simbolo: %s", (const char*)vvar);
warning_box("Tentativo di ridefinizione simbolo: %s(%d)", var, index);
else
{
_dirty = TRUE;
TString256 vvar(var); if (index >= 0) vvar << '(' << index << ')';
_data.add(vvar, new TString(value), force);
_dirty = TRUE;
}
return itwas;
}
@ -444,6 +436,15 @@ bool TConfig::set(const char* var, long value, const char* section,
return set(var,t,section,force,index);
}
bool TConfig::set_color(const char* var, COLOR col, const char* section,
bool force, int index)
{
TString16 t;
t.format("%d,%d,%d", XVT_COLOR_GET_RED(col), XVT_COLOR_GET_GREEN(col), XVT_COLOR_GET_BLUE(col));
return set(var,t,section,force,index);
}
// @doc EXTERNAL
// @mfunc Ritorna quanti elementi dell'array nominato sono presenti nella
@ -455,14 +456,8 @@ word TConfig::items(
// @comm Il paragrafo passato in <p section> diventa quello attivo.
// <nl>Possono esserci dei "buchi" causati da set() errate
{
set_paragraph(section);
TString vvar(16);
for (int cnt = 0; /* uncazzo */ ;cnt++)
{
vvar = var; vvar << '(' << cnt << ')';
if (!_data.is_key(var))
break;
}
if (section) set_paragraph(section);
for (int cnt = 0; exist(var, cnt); cnt++);
return cnt;
}
@ -487,11 +482,12 @@ void TConfig::init(
c.close();
}
if (_paragraph.empty())
if (_paragraph.blank())
{
_paragraph = main_app().name();
_paragraph.cut(2);
}
_ispresent = _read_paragraph();
}
@ -500,13 +496,14 @@ int TConfig::list_paragraphs(TString_array& pl)
TScanner s(_file);
pl.destroy();
while (s.line().not_empty())
{
if (s.token()[0] == '[')
{
TToken_string* p = new TToken_string(s.token());
p->strip("[]");
pl.add(p);
}
}
return pl.items();
}
@ -540,21 +537,23 @@ TConfig::TConfig(int which_config, const char* paragraph)
{
case CONFIG_DITTA:
_file << main_app().get_firm_dir() << '/' << "prassid.ini";
if (!fexist(_file)) fcopy("prassid.ini", _file);
if (!fexist(_file))
fcopy("prassid.ini", _file);
break;
case CONFIG_STUDIO:
case CONFIG_USER:
case CONFIG_STAMPE:
_file = firm2dir(-1); // Directory dati
_file.add("config");
if (!fexist(_file))
_file.add("config"); // Directory config
if (!fexist(_file)) // Creala se becessario
make_dir(_file);
switch (which_config)
{
case CONFIG_STUDIO:
_file.add("prassis.ini");
if (!fexist(_file)) fcopy("prassis.ini", _file);
if (!fexist(_file))
fcopy("prassis.ini", _file);
break;
case CONFIG_STAMPE:
_file.add("print.ini");

View File

@ -100,6 +100,9 @@ public:
// sezione corrente o in quella specificata
COLOR get_color(const char* var, const char* section = NULL, int index = -1, COLOR def = 0);
// @cmember Setta il colore nella sezione corrente o specificata
bool set_color(const char* var, COLOR col, const char* section = NULL, bool force = TRUE, int index = -1);
// @cmember Setta la variabile nella sezione corrente o specificata
bool set(const char* var, const char* value, const char* section = NULL, bool force = TRUE, int index = -1);
// @cmember Setta la variabile nella sezione corrente o specificata
@ -108,6 +111,9 @@ public:
// @cmember Controlla se esite una variabile nel paragrafo attivo
bool exist(const char* var, int index = -1);
// @cmember Elimina una variabile nel paragrafo attivo
bool remove(const char* var, int index = -1);
// @cmember Controlla se il paragrafo corrente e' nuovo (TRUE se nuovo)
bool new_paragraph()
{ return !_ispresent; }
@ -125,7 +131,7 @@ public:
// @cmember Riempie <p vl> con la lista dei nomi delle variabili
// nella sezione corrente o in quella indicata; se
// add_value e' TRUE ci mette "variabile<pipe>valore"
// ACHTUNG: l'array e' in ordine HASH (CAZZ)
// ACHTUNG: l'array e' in ordine HASH
int list_variables(TString_array& vl, bool add_value = FALSE, const char* section = NULL);
// @cmember Ritorna l'intero array delle variabili della sezione
@ -146,6 +152,4 @@ public:
virtual ~TConfig();
};
COLOR RGB2COLOR(unsigned char red, unsigned char green, unsigned char blue);
#endif

View File

@ -39,6 +39,7 @@ typedef struct _stx_data
#endif
HIDDEN bool _button_blocked = FALSE;
HIDDEN int _last_mouse_button = 0;
short get_focus_id(WINDOW win)
{
@ -315,8 +316,8 @@ void init_controls()
event_map[XIE_SELECT] = a_select;
event_map[XIE_UPDATE] = a_update;
event_map[XIE_COL_DELETE] = a_ignore;
event_map[XIE_COL_MOVE] = a_ignore;
event_map[XIE_COL_SIZE] = a_ignore;
event_map[XIE_COL_MOVE] = a_obj;
event_map[XIE_COL_SIZE] = a_obj;
event_map[XIE_POST_NAVIGATION]= a_post;
if (_picture == NULL)
@ -508,15 +509,14 @@ HIDDEN void xi_event_handler(XI_OBJ* itf, XI_EVENT* xiev)
case a_xvt:
switch (xiev->v.xvte.type)
{
case E_MOUSE_DOWN:
_last_mouse_button = xiev->v.xvte.v.mouse.button;
break;
case E_CHAR:
{
XI_OBJ* fo = xi_get_focus(itf);
if (fo != NULL && fo->type == XIT_CELL)
ctl = (TControl*)xi_get_app_data(fo->parent);
#ifdef DBG
if (xiev->v.xvte.v.chr.ch == K_DOWN || xiev->v.xvte.v.chr.ch == K_UP)
break;
#endif
}
break;
default:
@ -1301,7 +1301,7 @@ bool TButton_control::event_handler(XI_OBJ* itf, XI_EVENT* xiev)
if (xiev->type == XIE_BUTTON)
{
if (xi_move_focus(_obj))
if (_last_mouse_button == 0 && xi_move_focus(_obj))
{
switch (_obj->v.btn->type)
{
@ -1314,8 +1314,6 @@ bool TButton_control::event_handler(XI_OBJ* itf, XI_EVENT* xiev)
}
ok = notify_key(K_SPACE);
}
else
ok = FALSE;
}
else
if (xiev->type == XIE_POST_NAVIGATION)

View File

@ -65,8 +65,13 @@ ITEM M_EDIT_DELETE "Cerca il prossimo\tF8" DISABLED
MENUBAR BROWSE_BAR
MENU BROWSE_BAR
SUBMENU BROWSE_BAR+1 "~Proprieta'"
MENU BROWSE_BAR+1
ITEM M_EDIT_COPY "~Salva impostazioni colonne"
ITEM M_EDIT_UNDO "~Ripristina impostazioni colonne"
SEPARATOR
ITEM M_EDIT_SEARCH "~Informazioni"
ACCEL MENU_FILE "f" alt

View File

@ -91,6 +91,7 @@ void TMask::init_mask()
TMask::TMask(const char* title, int pages, int cols, int rows,
int xpos, int ypos)
: _mask_num(0)
{
init_mask();
for (_pages = 0; _pages < pages; _pages++)
@ -194,6 +195,7 @@ void TMask::add_default_tag_buttons()
}
TMask::TMask(const char* maskname, int num, int max)
: _mask_num(num)
{
if (maskname && *maskname)
read_mask(maskname, num, max);
@ -601,6 +603,85 @@ void TMask::on_button(short)
/* Non devo fare niente !!! non essendo una TWindow */
}
void TMask::handler(WINDOW win, EVENT* ep)
{
static TSheet_field* _last_sheet = NULL;
if (ep->type == E_MOUSE_DOWN && ep->v.mouse.button == 1)
{
_last_sheet = NULL;
for (int f = fields()-1; f >= 0; f--)
{
TMask_field& cur_fld = fld(f);
if (cur_fld.parent() == win)
{
RCT rct; cur_fld.get_rect(rct);
if (xvt_rect_has_point(&rct, ep->v.mouse.where))
{
if (cur_fld.is_kind_of(CLASS_SHEET_FIELD))
_last_sheet = (TSheet_field*)&cur_fld;
else
cur_fld.on_key(K_F11);
break;
}
}
}
if (_last_sheet)
{
TSheet_field& sht = (TSheet_field&)*_last_sheet;
#if (XVT_PTK_VERSION_MAJOR > 4) || (XVT_PTK_VERSION_MAJOR == 4 && XVT_PTK_VERSION_MINOR >= 50)
MENU_ITEM* menu = xvt_res_get_menu(BROWSE_BAR);
if (menu)
{
const PNT& p = ep->v.mouse.where;
RCT cr; xvt_vobj_get_client_rect(win, &cr);
XVT_POPUP_ALIGNMENT pa = XVT_POPUP_CENTER;
if (p.h < cr.right / 3)
pa = XVT_POPUP_LEFT_ALIGN;
else
if (p.h > 2 * cr.right / 3)
pa = XVT_POPUP_RIGHT_ALIGN;
xvt_menu_popup(menu->child, win, p, pa, NULL);
xvt_res_free_menu_tree(menu);
}
#else
ASK_RESPONSE r = xvt_dm_post_ask("Annulla", "Ripristina", "Salva",
"Ordinamento delle colonne");
if (r == RESP_2)
sht.reset_columns_order();
if (r == RESP_2 || r == RESP_3)
sht.save_columns_order();
#endif
}
return;
}
if (ep->type == E_COMMAND)
{
if (_last_sheet)
{
switch (ep->v.cmd.tag)
{
case M_EDIT_UNDO:
_last_sheet->reset_columns_order();
case M_EDIT_COPY:
_last_sheet->save_columns_order();
break;
case M_EDIT_SEARCH:
_last_sheet->on_key(K_F11);
break;
default:
break;
}
return;
}
}
TWindow::handler(win, ep);
}
// @doc EXTERNAL
// @mfunc Assegna una azione al tasto non standard

View File

@ -43,12 +43,18 @@ class TMask : public TWindow
// @ccost:(INTERNAL) MAX_PAGES | 16 | Massimo numero di pagine nella maschera
enum { MAX_PAGES = 16 };
// @cmember Gestisce gli eventi della finestra
virtual void handler(WINDOW win, EVENT* ep);
// @access:(INTERNAL) Private Member
private:
// @cmember:(INTERNAL) Windows delle pagine
WINDOW _pagewin[MAX_PAGES+1];
// @cmember:(INTERNAL) Numero della maschera all'interno del file sorgente
int _mask_num;
// @cmember:(INTERNAL) Numero di pagine della maschera
int _pages;
// @cmember:(INTERNAL) Pagina corrente
@ -64,6 +70,7 @@ class TMask : public TWindow
// @cmember:(INTERNAL) Primo controllo che deve ricevere il focus
int _first_focus;
// @cmember:(INTERNAL) Numero del controllo con il focus
int _focus;
// @cmember:(INTERNAL) Puntatore allo sheet che contiene la maschera (puo' essere NULL)
@ -166,6 +173,10 @@ public:
const TFilename& source_file() const
{ return _source_file; }
// @cmember Ritorna il numero della maschera nel file (> 0 se spreadsheet)
int number() const
{ return _mask_num; }
// @cmember Aggiunge alla maschera tutti i bottoni Pag. n
void add_default_tag_buttons();

View File

@ -399,8 +399,11 @@ bool TMask_field::active() const
void TMask_field::set_dirty(bool d)
{
if (_flags.dirty == 3 && d == FALSE)
if (_flags.dirty == 3)
{
if (d == FALSE) // Non permette di annullare il dirty dei campi errati
return;
}
_flags.dirty = d;
set_focusdirty(d);
}
@ -684,10 +687,10 @@ bool TOperable_field::on_key(
case K_F11:
{
TString msg(80);
msg = "State utilizzando il campo ";
msg << dlg() << " della maschera " << mask().source_file();
msg << "Identificatore: " << dlg() << '\n'
<< "Maschera: " << mask().source_file() << '\n';
if (field() != NULL)
msg << "\ncorrispondente al campo su record " << *field();
msg << "Campo: " << *field();
message_box(msg);
}
break;
@ -1979,12 +1982,33 @@ int TBrowse::do_input(
void TBrowse::do_output(CheckTime t)
{
static TBit_array _checked;
static short _checking = 0;
if (t == FINAL_CHECK)
return;
bool master;
if (_checking == 0)
{
master = TRUE;
_checking = field().dlg();
_checked.reset();
// Rendo intoccabili i campi del MIO output
for (const char* fld = _out_id.get(0); fld && *fld; fld = _out_id.get())
{
const short id = field().atodlg(fld);
_checked.set(id);
}
}
else
master = FALSE;
TString sum;
TToken_string flds(24, '+');
const TRelation& relation = *_cursor->relation();
_out_fn.restart();
for (const char* fld = _out_id.get(0); fld && *fld; fld = _out_id.get())
{
@ -2005,20 +2029,39 @@ void TBrowse::do_output(CheckTime t)
else
{
const TFieldref fld(fr, 0);
sum << fld.read(*_cursor->relation());
sum << fld.read(relation);
}
}
const bool hit = f.get() != sum;
f.set(sum);
if (field().dlg() != id && hit)
const bool changing = f.get() != sum;
if (changing)
{
bool hit = FALSE;
if (master)
{
f.set(sum);
hit = id != _checking; // Il mio handler viene fatto nella on_key
}
else
{
if (!_checked[id])
{
f.set(sum);
_checked.set(id);
hit = TRUE;
}
}
if (hit)
{
f.on_hit();
if (t == RUNNING_CHECK)
f.check();
f.on_hit();
}
}
}
}
if (master)
_checking = 0;
}
@ -2217,9 +2260,8 @@ KEY TBrowse::run()
KEY k = K_ESC;
long selected = 0;
TToken_string siblings;
TToken_string siblings, vals;
create_siblings(siblings);
TToken_string vals;
{
byte buttons = 0;
@ -2239,6 +2281,7 @@ KEY TBrowse::run()
}
}
}
for (const char* i = _inp_id.get(0); i; i = _inp_id.get())
{
if (*i != '"' && strchr(i, '@') == NULL)
@ -2254,7 +2297,6 @@ KEY TBrowse::run()
}
}
TBrowse_sheet s(_cursor, _items, caption, _head, buttons, &field(), siblings);
k = s.run();
selected = s.selected();
@ -2431,8 +2473,6 @@ const TBrowse* TEdit_field::parse_browse(TScanner& scanner) const
const int id = scanner.integer();
const TEdit_field& f = mask().efield(id);
const TBrowse* b = f.browse();
if (b == NULL)
NFCHECK("La USE del campo %d e' nulla e non puo' essere copiata nel campo %d", id, dlg());
return b;
}
@ -2476,7 +2516,11 @@ bool TEdit_field::parse_item(TScanner& scanner)
TString16 tabmaskname;
if (logicnum > 0)
{
TDir d; d.get(logicnum);
if (fexist(d.filename())) // Controlla l'esistenza del file
r = new TRelation(logicnum);
}
else
{
tabmaskname = scanner.pop();
@ -2492,7 +2536,7 @@ bool TEdit_field::parse_item(TScanner& scanner)
{
key = scanner.integer();
#ifdef DBG
if (key < 1 || key > 15)
if (key < 1 || key > MAX_KEYS)
{
yesnofatal_box("Chiave %d non valida nella USE del campo %d", key, dlg());
key = 1;
@ -2507,6 +2551,8 @@ bool TEdit_field::parse_item(TScanner& scanner)
else
scanner.push();
if (r != NULL)
{
_browse = new TBrowse(this, r, key, filter);
if (tabmaskname.not_empty())
@ -2514,8 +2560,9 @@ bool TEdit_field::parse_item(TScanner& scanner)
tabmaskname.insert("MBATB", 0);
browse()->set_insert(tabmaskname);
}
_check_enabled = TRUE;
}
return TRUE;
}
@ -2535,19 +2582,14 @@ bool TEdit_field::parse_item(TScanner& scanner)
return browse()->parse_copy(what, *b);
}
}
#ifdef DBG
return yesnofatal_box("Impossibile COPY senza USE nel campo %d", dlg());
#endif
}
if (scanner.key() == "JO")
{
#ifdef DBG
if(browse() == NULL)
return yesnofatal_box("JOIN senza USE nel campo %d", dlg());
else
#endif
if (browse())
browse()->parse_join(scanner);
else
scanner.line();
return TRUE;
}
@ -2577,21 +2619,17 @@ bool TEdit_field::parse_item(TScanner& scanner)
{
if (_browse)
_browse->parse_input(scanner);
#ifdef DBG
else
yesnofatal_box("INPUT senza USE o SHEET nel campo %d", _ctl_data._dlg);
#endif
scanner.line();
return TRUE;
}
if (scanner.key() == "DI")
{
#ifdef DBG
if(!browse())
return yesnofatal_box("DISPLAY senza USE nel campo %d", _ctl_data._dlg);
else
#endif
if (browse())
browse()->parse_display(scanner);
else
scanner.line();
return TRUE;
}
@ -2599,21 +2637,17 @@ bool TEdit_field::parse_item(TScanner& scanner)
{
if (_browse)
_browse->parse_output(scanner);
#ifdef DBG
else
return yesnofatal_box("OUTPUT senza USE nel campo %d", dlg());
#endif
scanner.line();
return TRUE;
}
if (scanner.key() == "AD")
{
#ifdef DBG
if(browse() == NULL)
return yesnofatal_box("ADD senza USE nel campo %d", dlg());
else
#endif
if (browse())
browse()->parse_insert(scanner);
else
scanner.line();
return TRUE;
}

View File

@ -12,12 +12,14 @@ extern "C" {
#endif
#include <colors.h>
#include <config.h>
#include <controls.h>
#include <keys.h>
#include <msksheet.h>
#include <urldefid.h>
#include <utility.h>
///////////////////////////////////////////////////////////
// TRow_property
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
// TSpreadsheet
@ -42,8 +44,18 @@ class TSpreadsheet : public TControl
TString_array _str;
// @cmember:(INTERNAL) Array delle colonne disattivate (solo visualizzazione)
TBit_array _column_disabled;
// @cmember:(INTERNAL) Array dell celle disattivate (solo visualizzazione)
TArray _disabled;
struct TRow_property : public TObject
{
TBit_array _disabled;
COLOR _back, _fore;
TRow_property();
virtual ~TRow_property() { }
};
// @cmember:(INTERNAL) Array delle proprieta' delle righe
TArray _property;
// @cmember:(INTERNAL) Maschera in cui e' contenuto lo spreadsheet
TMask _mask;
@ -74,6 +86,10 @@ class TSpreadsheet : public TControl
int _needs_update;
// @cmember:(INTERNAL) Numero della riga a cui saltare appena possibile
int _selection_posted;
// @cmember:(INTERNAL) Dimensioni delle colonne
int _default_width[32]; // 32 = MAX_COLS
// @cmember:(INTERNAL) Bisogna salvare l'ordien delle colonne
bool _save_columns_order;
// @cmember:(INTERNAL) Inizializza lo spreadsheet
void init();
@ -133,6 +149,9 @@ protected:
// @cmember Cerca la colonna col
XI_OBJ* find_column(int col) const;
// @cmember Cerca le proprieta' della riga r e volendo le crea pure
TRow_property* get_property(int r, bool create = FALSE);
TSheet_field& owner() const { return (TSheet_field&)*_fld; }
// @access Public Member
@ -182,6 +201,13 @@ public:
// @cmember Permette di invertire la posizione di due righe
void swap_rows(const int fromindex, const int toindex);
// @cmember Salva la disposizione delle colonne
void save_columns_order() const;
// @cmember Salva la disposizione delle colonne
void load_columns_order();
// @cmember Setta la disposizione delle colonne
void set_columns_order(TToken_string* order);
// @cmember Setta la larghezza della colonna
void set_column_width(const int col, const int width) const;
// @cmember Setta il titolo della colonna
@ -192,6 +218,10 @@ public:
void enable_cell(int row, int column, bool on = TRUE);
// @cmember Controlla se una cella e' disabilitata
bool cell_disabled(int row, int column) const;
// @cmember Setta i colori di una riga
void set_back_and_fore_color(COLOR back, COLOR fore, int row);
// @cmember Legge i colori di una riga
void get_back_and_fore_color(COLOR& back, COLOR& fore, int row);
// @cmember Ritorna la maschera che appartiene allo spreadsheet
TMask& sheet_mask() const;
@ -247,6 +277,12 @@ public:
virtual ~TSpreadsheet();
};
TSpreadsheet::TRow_property::TRow_property()
: _back(NORMAL_BACK_COLOR), _fore(NORMAL_COLOR)
{
}
// @doc INTERNAL
// @mfunc Costruttore
@ -265,7 +301,7 @@ TSpreadsheet::TSpreadsheet(
_mask(maskname, maskno), _notify(NULL),
_cur_row(0), _cur_col(1), _cur_rec(0), _edit_field(NULL), _active(TRUE),
_row_dirty(FALSE), _cell_dirty(FALSE), _check_enabled(TRUE),
_needs_update(-1), _selection_posted(-1)
_needs_update(-1), _selection_posted(-1), _save_columns_order(FALSE)
{
const int NUMBER_WIDTH = 3;
const int MAX_COL = 32;
@ -289,7 +325,6 @@ TSpreadsheet::TSpreadsheet(
const int cid = FIRST_FIELD+i; // Column & Field ID
const TOperable_field & f = (TOperable_field &) _mask.field(cid); // Field on mask
// CHECKD(f, "The spreadsheet mask needs ALSO field ", cid);
TString testa(h);
const int at = testa.find('@');
@ -423,6 +458,14 @@ TSpreadsheet::TSpreadsheet(
CHECKD(_obj, "Can't create spreadsheet ", owner().dlg());
update_tab_cid();
int num;
XI_OBJ** column = xi_get_member_list(_obj, &num);
for (i = 0; i < num; i++)
{
RCT rct; xi_get_rect(column[i], &rct);
_default_width[i] = rct.right - rct.left;
}
}
TSpreadsheet::~TSpreadsheet()
@ -434,7 +477,6 @@ TMask& TSpreadsheet::sheet_mask() const
return ((TSpreadsheet*)this)->_mask;
}
// Converts a row number in the correspondig record number
int TSpreadsheet::row2rec(int& row)
{
@ -455,7 +497,6 @@ int TSpreadsheet::row2rec(int& row)
return r;
}
// Converts a row number in the correspondig record number
int TSpreadsheet::rec2row(int record)
{
@ -659,7 +700,7 @@ int TSpreadsheet::insert(
const bool ok = notify(r, K_INS);
if (ok)
{
_disabled.insert(NULL, r);
_property.insert(NULL, r);
owner().post_insert(r);
xi_insert_row(_obj, INT_MAX);
@ -702,13 +743,13 @@ bool TSpreadsheet::destroy(
if (rec < 0)
{
_disabled.destroy();
_str.destroy();
_property.destroy();
set_dirty(_row_dirty = FALSE);
}
else
{
_disabled.destroy(rec, TRUE); // Destroy enable info
_property.destroy(rec, TRUE); // Destroy line info
ok = _str.destroy(rec, TRUE); // Destroy line
}
@ -821,6 +862,7 @@ bool TSpreadsheet::test_focus_change()
bool TSpreadsheet::event_handler(XI_OBJ* itf, XI_EVENT *xiev)
{
static KEY _lastab = K_TAB;
static char tmp[16];
BOOLEAN& refused = xiev->refused;
@ -886,6 +928,11 @@ bool TSpreadsheet::event_handler(XI_OBJ* itf, XI_EVENT *xiev)
xiev->v.cell_request.back_color = DISABLED_BACK_COLOR;
xiev->v.cell_request.attrib &= ~XI_ATR_ENABLED;
}
else
{
get_back_and_fore_color(xiev->v.cell_request.back_color,
xiev->v.cell_request.color, rec);
}
if (e->has_query_button())
{
@ -899,7 +946,8 @@ bool TSpreadsheet::event_handler(XI_OBJ* itf, XI_EVENT *xiev)
}
else
{
src = format("%d", rec+1);
sprintf(tmp, "%d", rec+1);
src = tmp;
}
char* dst = xiev->v.cell_request.s;
@ -1132,6 +1180,16 @@ bool TSpreadsheet::event_handler(XI_OBJ* itf, XI_EVENT *xiev)
_check_enabled = TRUE;
}
break;
case XIE_COL_MOVE:
if (xiev->v.column.in_fixed ||
xiev->v.column.col_nbr < xi_get_fixed_columns(xiev->v.column.list))
refused = TRUE;
else
_save_columns_order = TRUE;
break;
case XIE_COL_SIZE:
_save_columns_order = TRUE;
break;
case XIE_GET_PERCENT:
{
const long rec = xiev->v.get_percent.record;
@ -1463,19 +1521,12 @@ XI_OBJ* TSpreadsheet::find_column(
int num;
XI_OBJ** columns = xi_get_member_list(_obj, &num);
for (int c = num-1; c > 0; c--)
for (int c = num-1; c >= 0; c--)
{
if (columns[c]->cid == col)
break;
}
if (c <= 0)
{
yesnofatal_box("Can't find column with id=%d", col);
c = 1;
}
return columns[c];
return c >= 0 ? columns[c] : NULL;
}
@ -1525,30 +1576,55 @@ void TSpreadsheet::enable_cell(
{
if (column >= FIRST_FIELD)
column = cid2index(column);
TBit_array* ba = (TBit_array*)_disabled.objptr(row);
if (ba == NULL)
TRow_property* prop = get_property(row);
if (prop == NULL)
{
if (on) return; // Don't waste time and memory
ba = new TBit_array(column);
_disabled.add(ba, row);
prop = get_property(row, TRUE);
}
TBit_array& ba = prop->_disabled;
if (column >= 0)
{
ba->set(column, !on);
ba.set(column, !on);
}
else
{
if (on)
_disabled.destroy(row, FALSE); // Let's save some memory!
ba.reset();
else
{
ba->set(_columns); // Force right array size
ba->set(); // Set all bits
ba.set(_columns); // Force right array size
ba.set(); // Set all bits
}
}
}
void TSpreadsheet::set_back_and_fore_color(COLOR back, COLOR fore, int row)
{
TRow_property* prop = get_property(row, TRUE);
if (back != COLOR_INVALID)
prop->_back = back;
if (fore != COLOR_INVALID)
prop->_fore = fore;
}
void TSpreadsheet::get_back_and_fore_color(COLOR& back, COLOR& fore, int row)
{
TRow_property* prop = get_property(row, FALSE);
if (prop)
{
back = prop->_back;
fore = prop->_fore;
}
else
{
back = NORMAL_BACK_COLOR;
fore = NORMAL_COLOR;
}
}
// @doc INTERNAL
// @mfunc Permette di abilitare/disabiltare una colonna
@ -1568,19 +1644,21 @@ void TSpreadsheet::enable_column(
if (change)
{
XI_OBJ* column = find_column(col);
if (column)
{
dword attr = xi_get_attrib(column);
if (on) attr |= XI_ATR_ENABLED;
else attr &= ~XI_ATR_ENABLED;
xi_set_attrib(column, attr); // Set new attributes
// update(-1); // Guy: Meno andi e rivieni
}
}
}
void TSpreadsheet::delete_column( const int col ) const
{
XI_OBJ* column = find_column(col);
xi_delete( column );
if (column)
xi_delete(column);
}
@ -1627,26 +1705,32 @@ void TSpreadsheet::swap_columns(const int fromid, const int toid) const
void TSpreadsheet::swap_rows( const int fromindex, const int toindex)
{
_str.swap(fromindex, toindex);
_disabled.swap(fromindex, toindex);
_property.swap(fromindex, toindex);
}
void TSpreadsheet::set_column_width(const int col, const int width) const
{
XI_OBJ* column = find_column(col);
if (column)
xi_set_column_width(column, width); // Force redraw
}
void TSpreadsheet::set_column_header(const int col, const TString& header) const
{
XI_OBJ* column = find_column(col);
if (column)
{
xi_set_text(column, (char *)(const char *)header );
RCT r; xi_get_rect(column, &r);
xi_set_column_width(column, (r.right-r.left+1) / CHARX); // Force redraw
}
}
void TSpreadsheet::set_column_justify(int col, bool right)
{
XI_OBJ* column = find_column(col);
if (column)
{
dword attr = xi_get_attrib(column);
if (right)
attr |= XI_ATR_RJUST;
@ -1654,6 +1738,127 @@ void TSpreadsheet::set_column_justify(int col, bool right)
attr &= ~XI_ATR_RJUST;
xi_set_attrib(column, attr); // Set new attribute
update(-1);
}
}
TSpreadsheet::TRow_property* TSpreadsheet::get_property(int row, bool create)
{
TRow_property* p = (TRow_property*)_property.objptr(row);
if (p == NULL && create)
{
p = new TRow_property;
_property.add(p, row);
}
return p;
}
// Costruisce l'identificatore del paragrafo contenente la disposizione
// delle colonne del campo f
HIDDEN TFilename& field2parag(const TMask_field& f, TFilename& name)
{
const TMask& m = f.mask();
name = m.source_file();
name.ext(""); // Nome della maschera senza estensione
if (m.number() > 0) // Aggiunge l'eventuale numero di sotto-maschera
name << '(' << m.number() << ')';
return name;
}
void TSpreadsheet::save_columns_order() const
{
if (_save_columns_order)
{
TFilename parag; field2parag(owner(), parag);
TConfig config(CONFIG_USER, parag); // Apre il file di configurazione
if (_save_columns_order == TRUE) // Se vale 3 devo solo resettare
{
int num;
XI_OBJ** column = xi_get_member_list(_obj, &num);
TToken_string order(127); // Nuovo ordine delle colonne
for (int i = 0; i < num; i++) // Scorre le colonne
{
order.add(column[i]->cid);
RCT rct; xi_get_rect(column[i], &rct);
order << ',' << rct.right - rct.left;
}
config.set("Browse", order, NULL, TRUE, owner().dlg());
}
else
config.remove("Browse", owner().dlg());
}
}
void TSpreadsheet::load_columns_order()
{
TFilename parag; field2parag(owner(), parag);
TConfig config(CONFIG_USER, parag);
const int index = owner().dlg();
TToken_string order = config.get("Browse", NULL, index);
if (order.empty_items())
config.remove("Browse", index);
else
set_columns_order(&order);
}
void TSpreadsheet::set_columns_order(TToken_string* order)
{
XI_OBJ* itf = get_interface();
XI_OBJ* focus = xi_get_focus(itf);
xi_set_focus(itf);
int num_cols;
XI_OBJ** column = xi_get_member_list(_obj, &num_cols);
// Costante da sottrarre nella xi_column_set_pixel_width altrimenti la somma due volte!
const int offset = 2 * (int)xi_get_pref(XI_PREF_COLUMN_OFFSET);
const int fixed = xi_get_fixed_columns(_obj);
if (fixed > 1)
xi_set_fixed_columns(_obj, 1);
if (order == NULL)
{
for (int index = 0; index < num_cols; index++)
{
const short cid = index ? FIRST_FIELD + index - 1 : 0;
XI_OBJ* col = find_column(cid);
if (col)
{
if (index >= fixed)
xi_move_column(col, index);
RCT rct; xi_get_rect(col, &rct);
if (_default_width[index] != rct.right - rct.left)
xi_column_set_pixel_width(col, _default_width[index]-offset);
}
}
_save_columns_order = 0x3;
}
else
{
TToken_string col(8, ',');
int pos = 0;
for (col = order->get(0); !col.blank(); col = order->get(), pos++)
{
const int cid = col.get_int(0);
const int width = col.get_int();
XI_OBJ* column = find_column(cid);
if (column) // Controlla che esista ancora
{
if (pos >= fixed && pos < num_cols)
xi_move_column(column, pos); // Sposta la colonna
if (width > XI_FU_MULTIPLE) // Se ha una larghezza valida
xi_column_set_pixel_width(column, width - offset);
}
}
_save_columns_order = FALSE;
}
if (fixed > 1)
xi_set_fixed_columns(_obj, fixed);
if (focus)
xi_set_focus(focus);
}
// Certified 99%
@ -1668,15 +1873,15 @@ void TSpreadsheet::set_column_justify(int col, bool right)
// @flag FALSE| Se la cella e' abilitata
bool TSpreadsheet::cell_disabled(int row, int column) const
{
TBit_array* ba = (TBit_array*)_disabled.objptr(row);
const TRow_property* prop = ((TSpreadsheet*)this)->get_property(row);
bool d;
if (column < 0)
d = (ba == NULL) ? FALSE : (ba->ones() >= columns()-1);
d = (prop == NULL) ? FALSE : (prop->_disabled.ones() >= columns()-1);
else
{
d = _column_disabled[column]; // Controlla la colonna
if (d == FALSE && ba != NULL) // Se la colonna e' disabilitata e' inutile proseguire
d = (*ba)[column]; // Controlla la cella
if (d == FALSE && prop != NULL) // Se la colonna e' disabilitata e' inutile proseguire
d = prop->_disabled[column]; // Controlla la cella
}
return d;
}
@ -1828,6 +2033,8 @@ void TSheet_field::create(WINDOW parent)
for (short id = FIRST_FIELD; ; id++)
if (s.id2pos(id) < 0) break;
_last_column_id = id - 1;
((TSpreadsheet*)_ctl)->load_columns_order();
}
@ -2224,3 +2431,24 @@ void TSheet_field::row2mask(int n, TToken_string & r)
val.format("Riga %d", n+1);
m.set_caption(val);
}
void TSheet_field::set_back_and_fore_color(COLOR back, COLOR fore, int row)
{
TSpreadsheet& s = (TSpreadsheet&)*_ctl;
s.set_back_and_fore_color(back, fore, row);
}
void TSheet_field::reset_columns_order()
{
TSpreadsheet& s = (TSpreadsheet&)*_ctl;
s.set_columns_order(NULL);
}
void TSheet_field::save_columns_order()
{
const TSpreadsheet& s = (const TSpreadsheet&)*_ctl;
s.save_columns_order();
}

View File

@ -45,8 +45,6 @@ protected:
// @cmember Gestisce la chiamata all'handler del campo
virtual bool on_hit();
// @cmember Gestisce la pressione del tasto (TRUE se la gestione ha avuto successo)
virtual bool on_key(KEY k);
// @cmember Legge la testata dello spreadsheet da <p scanner>
virtual void parse_head(TScanner& scanner);
@ -66,6 +64,9 @@ protected:
// @access Public Member
public:
// @cmember Gestisce la pressione del tasto (TRUE se la gestione ha avuto successo)
virtual bool on_key(KEY k);
// @cmember Ritorna una riga dello spreadsheet
TToken_string& row(int n);
// @cmember Ritorna un array con tutte le righe dello spreadsheet
@ -139,7 +140,12 @@ public:
void set_column_header( const int col, const TString& header ) const;
// @cmember Setta l'allineamento della colonna
void set_column_justify(int col, bool right);
// @cmember Setta il colore dello sfondo e del testo di una o tutte le righe
void set_back_and_fore_color(COLOR back, COLOR fore, int row);
// @cmember Memorizza la disposizione delle colonne
void save_columns_order();
// @cmember Dispone le colonne come all'atto del caricamento
void reset_columns_order();
// @cmember Setta il member <p _append> con il valore di <p on>
void set_append(bool on = TRUE)
{ _append = on;}

View File

@ -914,13 +914,19 @@ void TPrinter::set_win_formlen(
if (prwin != NULL_WIN)
{
TString256 spc; spc.spaces(256); // Compute maximun number of chars per line
TString spc; // Compute maximum number of chars per line
// spc.spaces(256);
spc.fill('M', 256);
int w = 0;
for (_formwidth = 256; _formwidth >= 80; _formwidth--)
for (_formwidth = spc.len(); _formwidth >= 80; _formwidth--)
{
w = xvt_dwin_get_text_width(prwin, (char*)(const char*)spc, _formwidth);
if (w < pw) break;
}
if (isfax())
_horz_offset = 56;
else
_horz_offset = (_formwidth > 80) ? (int)(pw - w)/2 : 0;
}
else
@ -1113,11 +1119,15 @@ bool TPrinter::isfax() const
if (fax)
{
const char* name = (const char*)((TPrinter*)this)->get_printrcd() + 4;
fax = strncmp(name, "FaxMan", 6) == 0;
if (!fax)
{
TToken_string p(256, ',');
GetProfileString ("devices", name, "", (char*)(const char*)p, p.size());
const char * driver = p.get(1);
fax = driver != NULL && stricmp(driver, "EASYFAX") == 0;
}
}
return fax;
}
@ -1802,14 +1812,13 @@ bool TPrinter::set()
else
mask.set (MSK_TYPE, "0");
KEY k;
int oldprn = _curprn;
const int oldprn = _curprn;
s_printrcd * rcd = get_printrcd();
TString oldrcd(_print_rcd_size);
TString oldrcd(_print_rcd_size);
memcpy((char *) (const char *) oldrcd, rcd, _print_rcd_size);
KEY k;
while ((k = mask.run ()) != K_ESC && k != K_ENTER && k != K_INS)
{
if (k == DLG_SETPRINT)
@ -1822,9 +1831,14 @@ bool TPrinter::set()
// determine index of currently selected printer
// ACTHUNG! Deep hacking of XVT internals! NON PORTABLE!
const char* name = (const char *)(_print_rcd + 4);
const char* name = (const char *)(get_printrcd() + 4);
_curprn = pn2.get_pos(name);
CHECKS(_curprn >= 0, "Can't find printer ", name);
if (_curprn < 0)
{
NFCHECK("Can't find printer %s", name);
_curprn = oldprn;
}
mask.set(MSK_PRINTERS, pn1.get(_curprn));
// set_win_formlen(); // Update dimensions
}
@ -2067,7 +2081,6 @@ TFile_printer::TFile_printer (const char *ffile, const char *label, int len_rec,
_nome_file_fissato = TRUE;
_formatta = FALSE;
_label_fissata = TRUE;
}
void TFile_printer::open()

View File

@ -30,6 +30,11 @@ class TSheet_control : public TControl
// @cmember:(INTERNAL) Array di righe disabilitate
TBit_array _disabled;
// @cmember:(INTERNAL) Array delle largezze standard
int _default_width[MAX_COL];
bool _save_columns_order;
protected: // TControl
//@cmember Gestisce gli eventi delle celle
virtual bool event_handler(XI_OBJ* itf, XI_EVENT* xiev);
@ -43,6 +48,7 @@ protected:
void make_current(long rec);
XI_OBJ* find_column(int col) const;
XI_OBJ* find_column(const char* head) const;
public: // TControl
virtual void set_rect(const RCT& r);
@ -69,6 +75,10 @@ public:
byte& column_type(int c) { CHECKD(c >= 0 && c < MAX_COL, "Bad column ", c); return _type[c]; }
void set_columns_order(TToken_string* order);
void save_columns_order(const TMask_field& f) const;
void load_columns_order(const TMask_field& f);
void update(long n = -1);
TSheet_control(WINDOW sheet, short cid,
@ -87,7 +97,8 @@ TSheet_control::TSheet_control(
short dy, // @parm Lunghezza (in caratteri) dello spreasheet
const char* flags, // @parm Flags di abilitazione
const char* head) // @parm Titolo delle colonne
: _sheet(NULL), _cur_rec(0), _check_enabled(FALSE)
: _sheet(NULL), _cur_rec(0), _check_enabled(FALSE),
_save_columns_order(FALSE)
{
const int NUMBER_WIDTH = 7;
@ -148,7 +159,6 @@ TSheet_control::TSheet_control(
new_header.add(testa);
}
const int _columns = i;
// Calcola rettangolo massimo per lo sheet
XI_RCT rct; coord2rct(parent, x, y, dx, dy, rct);
@ -182,7 +192,7 @@ TSheet_control::TSheet_control(
// Definizione della prima colonna (numero di riga)
const long attr = XI_ATR_VISIBLE | XI_ATR_RJUST | XI_ATR_SELECTABLE;
XI_OBJ_DEF* coldef = xi_add_column_def(listdef, FIRST_FIELD+1000-1, attr, 0,
/* NUMBER_WIDTH*/ 2 * XI_FU_MULTIPLE, NUMBER_WIDTH , "");
2 * XI_FU_MULTIPLE, NUMBER_WIDTH , "");
coldef->app_data = (long)this;
coldef->v.column->heading_platform = TRUE;
@ -238,6 +248,14 @@ TSheet_control::TSheet_control(
xvt_vobj_move(parent, &cli);
}
}
int num;
XI_OBJ** column = xi_get_member_list(_obj, &num);
for (i = 0; i < num; i++)
{
RCT rct; xi_get_rect(column[i], &rct);
_default_width[i] = rct.right - rct.left;
}
}
void TSheet_control::set_rect(const RCT& r)
@ -378,21 +396,30 @@ XI_OBJ* TSheet_control::find_column(
int num;
XI_OBJ** columns = xi_get_member_list(_obj, &num);
for (int c = num-1; c > 0; c--)
for (int c = num-1; c >= 0; c--)
{
if (columns[c]->cid == col)
break;
}
if (c <= 0)
{
yesnofatal_box("Can't find column with id=%d", col);
c = 1;
}
return columns[c];
return c >= 0 ? columns[c] : NULL;
}
XI_OBJ* TSheet_control::find_column(
const char* head) const // @parm testata colonna
{
int num;
XI_OBJ** column = xi_get_member_list(_obj, &num);
for (int c = num-1; c >= 0; c--)
{
char str[80];
xi_get_text(column[c], str, sizeof(str));
if (stricmp(str, head) == 0)
break;
}
return c >= 0 ? column[c] : NULL;
}
void TSheet_control::enable_check(bool on)
{
@ -400,6 +427,7 @@ void TSheet_control::enable_check(bool on)
if (_type[0] == 'C')
{
XI_OBJ* column = find_column(1101);
CHECK(column, "Can't find checkable column");
dword attr = xi_get_attrib(column);
if (_check_enabled) attr |= XI_ATR_ENABLED;
else attr &= ~XI_ATR_ENABLED;
@ -502,6 +530,113 @@ void TSheet_control::enable_row(
update(n);
}
// Costruisce l'identificatore del paragrafo contenente la disposizione
// delle colonne del campo f
HIDDEN TFilename& field2parag(const TMask_field& f, TFilename& name)
{
const TMask& m = f.mask();
name = m.source_file();
name.ext(""); // Nome della maschera senza estensione
const int index = m.number();
CHECKD(index >= 0 && index <= 8, "Bad mask index:", index);
if (index > 0) // Aggiunge l'eventuale numero di sotto-maschera
name << '(' << index << ')';
return name;
}
void TSheet_control::save_columns_order(const TMask_field& field) const
{
if (_save_columns_order)
{
TFilename parag; field2parag(field, parag);
TConfig config(CONFIG_USER, parag); // Apre il file di configurazione
TToken_string order(127); // Nuovo ordine delle colonne
if (_save_columns_order == TRUE) // Se vale 3 devo solo resettare
{
int num;
XI_OBJ** column = xi_get_member_list(_obj, &num);
for (int i = 0; i < num; i++) // Scorre tutte le colonne
{
char head[80];
xi_get_text(column[i], head, sizeof(head));
order.add(head);
RCT rct; xi_get_rect(column[i], &rct);
order << ',' << rct.right - rct.left;
}
config.set("Browse", order, NULL, TRUE, field.dlg());
}
else
config.remove("Browse", field.dlg());
}
}
void TSheet_control::load_columns_order(const TMask_field& field)
{
TFilename parag; field2parag(field, parag);
TConfig config(CONFIG_USER, parag);
const int index = field.dlg();
TToken_string order = config.get("Browse", NULL, index);
if (order.empty_items())
config.remove("Browse", index);
else
set_columns_order(&order);
_save_columns_order = FALSE;
}
void TSheet_control::set_columns_order(TToken_string* order)
{
XI_OBJ* itf = get_interface();
XI_OBJ* focus = xi_get_focus(itf);
xi_set_focus(itf);
int num_cols;
XI_OBJ** column = xi_get_member_list(_obj, &num_cols);
// Costante da sottrarre nella xi_column_set_pixel_width altrimenti la somma due volte!
const int offset = 2 * (int)xi_get_pref(XI_PREF_COLUMN_OFFSET);
if (order == NULL)
{
for (int index = 0; index < num_cols; index++)
{
const short cid = FIRST_FIELD + 1000 + index - 1;
XI_OBJ* col = find_column(cid);
if (col)
{
xi_move_column(col, index);
RCT rct; xi_get_rect(col, &rct);
if (_default_width[index] != rct.right - rct.left)
xi_column_set_pixel_width(col, _default_width[index]-offset);
}
}
_save_columns_order = 0x3;
}
else
{
TString head(23);
TToken_string col(8, ',');
int pos = 0;
for (col = order->get(0); !col.blank(); col = order->get(), pos++)
{
head = col.get(0);
const int width = col.get_int();
XI_OBJ* column = find_column(head);
if (column) // Controlla che esista ancora
{
if (pos > 0 && pos < num_cols)
xi_move_column(column, pos); // Sposta la colonna se possibile
if (width > XI_FU_MULTIPLE) // Se ha una larghezza valida
xi_column_set_pixel_width(column, width - offset);
}
}
}
if (focus)
xi_set_focus(focus);
}
HIDDEN long _rec_to_select = -1;
// Certified 75%
bool TSheet_control::event_handler(XI_OBJ* itf, XI_EVENT *xiev)
@ -663,6 +798,16 @@ bool TSheet_control::event_handler(XI_OBJ* itf, XI_EVENT *xiev)
}
refused = TRUE;
break;
case XIE_COL_MOVE:
if (xiev->v.column.in_fixed ||
xiev->v.column.col_nbr < xi_get_fixed_columns(xiev->v.column.list))
refused = TRUE;
else
_save_columns_order = TRUE;
break;
case XIE_COL_SIZE:
_save_columns_order = TRUE;
break;
case XIE_BUTTON:
if (xiev->v.xi_obj->type == XIT_LIST)
_sheet->on_key(K_CTRL+'N');
@ -1182,15 +1327,64 @@ void TBrowse_sheet::handler(
{
if (ep->type == E_MOUSE_DOWN)
{
TMask_field & f = fld(0);
RCT r; f.get_rect(r);
TSheet_control& sht = sheet();
switch (ep->v.mouse.button )
{
case 1:
{
#if (XVT_PTK_VERSION_MAJOR > 4) || (XVT_PTK_VERSION_MAJOR == 4 && XVT_PTK_VERSION_MINOR >= 50)
MENU_ITEM* menu = xvt_res_get_menu(BROWSE_BAR);
if (menu)
{
const PNT& p = ep->v.mouse.where;
RCT cr; xvt_vobj_get_client_rect(win, &cr);
XVT_POPUP_ALIGNMENT pa = XVT_POPUP_CENTER;
if (p.h < cr.right / 3)
pa = XVT_POPUP_LEFT_ALIGN;
else
if (p.h > 2 * cr.right / 3)
pa = XVT_POPUP_RIGHT_ALIGN;
xvt_menu_popup(menu, win, p, pa, NULL);
xvt_res_free_menu_tree(menu);
}
#else
ASK_RESPONSE r = xvt_dm_post_ask("Annulla", "Ripristina", "Salva",
"Disposizione delle colonne:");
if (r == RESP_2)
sht.set_columns_order(NULL);
if (r == RESP_2 || r == RESP_3)
sht.save_columns_order(field());
#endif
}
break;
default:
{
RCT r; sht.get_rect(r);
if (xvt_rect_has_point(&r, ep->v.mouse.where) && _rec_to_select >= 0)
{
post_select(_rec_to_select);
_rec_to_select = -1;
}
}
break;
}
}
else
if (ep->type == E_COMMAND)
{
switch (ep->v.cmd.tag)
{
case M_EDIT_UNDO:
sheet().set_columns_order(NULL);
case M_EDIT_COPY:
sheet().save_columns_order(field());
return;
default:
break;
}
}
TCursor_sheet::handler(win, ep);
}
@ -1291,6 +1485,8 @@ TBrowse_sheet::TBrowse_sheet(TCursor* cursor, const char* fields,
if (e != NULL)
e->set_handler(last_browse_field_handler);
sheet().load_columns_order(field());
}
bool TBrowse_sheet::on_key(KEY k)
@ -1313,3 +1509,4 @@ KEY TBrowse_sheet::run()
return key;
}

View File

@ -1,16 +1,41 @@
#include <stdtypes.h>
#include <tabutil.h>
#include <execp.h>
#include <utility.h>
#include <tabapp.h>
#include <tabutil.h>
#include <utility.h>
// @cmember Costruttore
Tab_application::Tab_application()
: _msk(NULL), _rel(NULL)
{ }
// @cmember Distruttore
Tab_application::~Tab_application()
{ }
// @cmember Indica se la futura <mf Tab_application::get_mask> ritornera' una maschera diversa
// dalla corrente.
bool Tab_application::changing_mask(int mode)
{ return FALSE; }
// @cmember Richiede la maschera da usare
TMask* Tab_application::get_mask(int mode)
{
CHECK(_msk, "Null mask");
return _msk;
}
// @cmember Ritorna la relazione da modificare
TRelation* Tab_application::get_relation() const
{
CHECK(_rel, "Null relation");
return _rel;
}
void Tab_application::print()
{
#if XVT_OS == XVT_OS_WIN
TExternal_app stampa(format("ba3a -1 %s", (const char *) _tabname));
#else
TExternal_app stampa(format("ba3 -1 %s", (const char *) _tabname));
#endif
TString16 cmd;
cmd << "ba3 -1 " << get_tabname();
TExternal_app stampa(cmd);
stampa.run();
}
@ -24,7 +49,6 @@ void Tab_application::init_modify_mode(TMask& m)
{
m.disable(-GR_MODIFY_PROTECTED);
const bool enable = !(_rel->curr().get_bool(FPC));
m.enable(-GR_RECORD_PROTECTED,enable);
}
@ -39,30 +63,31 @@ bool Tab_application::user_create()
return FALSE;
_tabname = argv(2);
if (_tabname.empty())
return FALSE;
_tabname.upper();
TString16 m, t(_tabname);
_rel = new TRelation(_tabname);
TString16 t(_tabname);
if (t[0] == '%') t.ltrim(1);
m << "BATB" << t;
TString16 m; m << "BATB" << t;
_msk = new TMask(m) ;
for (int i = 0; i < _msk->fields(); i++)
if (_msk->fld(i).in_group(GR_SEARCH))
const int campi = _msk->fields();
for (int i = 0; i < campi; i++)
{
set_search_field(_msk->fld(i).dlg());
const TMask_field& f = _msk->fld(i);
if (f.in_group(GR_SEARCH))
{
set_search_field(f.dlg());
break;
}
_rel = new TRelation(_tabname);
set_title(_msk->get_caption());
}
TFilename rpt("batb"); rpt << t << ".rpt";
if (fexist(rpt)) enable_menu_item(M_FILE_PRINT);
if (fexist(rpt))
enable_menu_item(M_FILE_PRINT);
const char* title = _msk->get_caption();
set_title(title);
return TRUE;
}
@ -71,6 +96,7 @@ bool Tab_application::user_destroy()
{
if (_msk) delete _msk;
if (_rel) delete _rel;
return TRUE;
}

View File

@ -34,15 +34,12 @@ protected:
// @cmember Richiede se il record corrente e' protetto (non cancellabile)
virtual bool protected_record(TRectype& rec);
// @cmember Richiede la maschera da usare
virtual TMask* get_mask(int mode = NO_MODE)
{ return _msk;}
virtual TMask* get_mask(int mode = MODE_QUERY);
// @cmember Indica se la futura <mf Tab_application::get_mask> ritornera' una maschera diversa
// dalla corrente.
virtual bool changing_mask(int mode)
{ return FALSE;}
virtual bool changing_mask(int mode);
// @cmember Ritorna la relazione da modificare
virtual TRelation* get_relation() const
{ return _rel;}
virtual TRelation* get_relation() const;
// @cmember Inizializza la maschera per il modo ricerca
virtual void init_query_mode(TMask& m);
// @cmember Inizializza la maschera per il modo modifica
@ -57,11 +54,9 @@ protected:
// @access Public Member
public:
// @cmember Costruttore
Tab_application() : _msk(NULL), _rel(NULL)
{}
Tab_application();
// @cmember Distruttore
virtual ~Tab_application()
{}
virtual ~Tab_application();
// @cmember Ritorna il nome della tabella
const TString& get_tabname() const
{ return _tabname; }

View File

@ -42,8 +42,6 @@ class TVariable_mask : public TMask
virtual TMask_field* parse_field(TScanner& scanner);
// @cmember Distruttore
virtual ~TVariable_mask() {}
};
// @doc EXTERNAL

View File

@ -1,21 +1,12 @@
#include <applicat.h>
#include <colors.h>
#include <config.h>
#include <date.h>
#include <controls.h>
#include <mask.h>
#include <urldefid.h>
#include <utility.h>
#include <mask.h>
#if XVT_OS == XVT_OS_WIN
#include <windows.h>
#include <string.h>
#include <ctype.h>
#pragma hdrstop
#include "prochook.h"
#define MAX_PATH 260 // This really should be in WINDOWS.H, but is
// inexplicably hard-coded into the data structures
int MungeModuleHeader( HINSTANCE hInstance, BOOL fMunge );
#endif
#include <statbar.h>
#if XVT_OS == XVT_OS_SCOUNIX
extern "C" { long nap(long period); }
@ -36,15 +27,20 @@ BOOLEAN error_hook(XVT_ERRMSG err, DATA_PTR)
#if XVT_OS == XVT_OS_WIN
#define STRICT
#include <windows.h>
#include <ctl3d.h>
extern "C" {
WINDOW xvtwi_hwnd_to_window(HWND);
#include <statbar.h>
}
#include <controls.h>
#ifndef ATTR_WIN_USE_CTL3D
#include <ctl3d.h>
#endif
#include <string.h>
#include <ctype.h>
#pragma hdrstop
#include "prochook.h"
#define MAX_PATH 260 // This really should be in WINDOWS.H, but is
// inexplicably hard-coded into the data structures
extern "C" { WINDOW xvtwi_hwnd_to_window(HWND); }
short CHARX = 8;
short ROWY = GetSystemMetrics(SM_CYSCREEN) / 25;
@ -215,9 +211,11 @@ static BOOLEAN event_hook(HWND hwnd,
{
switch(msg)
{
#ifndef ATTR_WIN_USE_CTL3D
case WM_SYSCOLORCHANGE:
Ctl3dColorChange();
break;
#endif
case WM_MENUCHAR:
if (wparam > ' ' && wparam <= 'z')
{
@ -601,10 +599,13 @@ void customize_controls(
xvt_vobj_set_attr(NULL_WIN,ATTR_EVENT_HOOK, (long)event_hook);
xvt_vobj_set_attr(NULL_WIN,ATTR_ERRMSG_HANDLER, (long)error_hook);
HInstance = (HINSTANCE)xvt_vobj_get_attr(NULL_WIN, ATTR_WIN_INSTANCE);
#ifndef ATTR_WIN_USE_CTL3D
HInstance = (HINSTANCE)xvt_vobj_get_attr(NULL_WIN, ATTR_WIN_INSTANCE);
Ctl3dRegister(HInstance);
Ctl3dAutoSubclass(HInstance);
#endif
#endif
customize_colors();
init_controls();
@ -612,8 +613,9 @@ void customize_controls(
else
{
#if XVT_OS == XVT_OS_WIN
// HINSTANCE _hInstance = (HINSTANCE)xvt_vobj_get_attr(NULL_WIN, ATTR_WIN_INSTANCE);
#ifndef ATTR_WIN_USE_CTL3D
Ctl3dUnregister(HInstance);
#endif
deny_another_instance();
#endif
free_controls();
@ -910,7 +912,7 @@ WINDOW xvt_create_statbar()
// @xref <f xvt_statbar_set> <f xvt_statbar_refresh>
{
CHECK(_statbar == NULL_WIN, "Onli uan stabar, plis");
CHECK(_statbar == NULL_WIN, "Onli uan statbar, plis");
#if XVT_OS == XVT_OS_WIN
const int prop_count = 4;
@ -945,14 +947,14 @@ void xvt_statbar_set(
//
// @xref <f xvt_create_statbar> <f xvt_statbar_refresh>
{
#if XVT_OS == XVT_OS_WIN
CHECK(_statbar, "NULL statbar");
const TDate oggi(TODAY);
TString256 t(text);
t << '\t' << oggi.string() << " - " << main_app().title();
TString t(31);
t << text << '\t' << oggi.string() << " - " << main_app().title();
if (def)
statbar_set_default_title(_statbar, (char*)(const char*)t);
statbar_set_title(_statbar, (char*)(const char*)t);
#endif
}
// @doc INTERNAL
@ -962,9 +964,8 @@ void xvt_statbar_refresh()
// @xref <f xvt_create_statbar> <f xvt_statbar_set>
{
#if XVT_OS == XVT_OS_WIN
CHECK(_statbar, "NULL statbar");
statbar_set_title(_statbar, NULL);
#endif
}
///////////////////////////////////////////////////////////