Files correlati : Ricompilazione Demo : [ ] Commento : Aggiunte utili per gestione dizionario assoc.cpp Aggiunta possibilita' di selezionare un elemento causale di un assoc controls.cpp Corretta gestione scrollbar dei listbox diction.cpp Migliorata selezione caratteri da trimmare dalle traduzioni isam.cpp Corretto azzeramento dei memo (non azzerava il TString_array corrispondente) msksheet.cpp Resa personalizzabile la larghezza della colonna col numero di riga netsock.cpp Migliorata gestione "a capo" in protocollo soap progind.cpp Corretto posizionamento progind sovrapposte relapp.cpp Cambiato un messaggio di richiesta annullamento git-svn-id: svn://10.65.10.50/trunk@11651 c028cbd2-c16b-5b4b-a496-9718f37d4682
365 lines
8.0 KiB
C++
Executable File
365 lines
8.0 KiB
C++
Executable File
#include "xvt.h"
|
|
#include "xinclude.h"
|
|
|
|
#include <colors.h>
|
|
#include <diction.h>
|
|
#include <progind.h>
|
|
#include <controls.h>
|
|
#include <urldefid.h>
|
|
|
|
int TIndwin::_indwin_count = 0;
|
|
|
|
word TIndwin::measure_text(TToken_string& s, word& maxlen) const
|
|
{
|
|
word lines = 0;
|
|
for(const char* t = s.get(0); t; t = s.get())
|
|
{
|
|
const word l = strlen(t);
|
|
if (l > maxlen) maxlen = l;
|
|
lines++;
|
|
}
|
|
return lines;
|
|
}
|
|
|
|
// Certified 70%
|
|
TIndwin::TIndwin(long max, const char* txt, bool cancel, bool bar, int div)
|
|
: _text(NULL), _cancel(NULL), _bar(0),
|
|
_status(0L), _max(max), _flags(0x0)
|
|
{
|
|
if (_max <= 0)
|
|
_max = 1;
|
|
|
|
TToken_string testo(txt, '\n');
|
|
word maxlen = div;
|
|
const word lines = measure_text(testo, maxlen);
|
|
|
|
const int hor = min(maxlen+3, 78);
|
|
const int ver = lines+1 + (bar ? 2 : 0) + (cancel ? 2: 0);
|
|
|
|
const int y = _indwin_count == 0 ? 3 : 12;
|
|
|
|
set_win(create_interface(TASK_WIN, -1, y, hor, ver, TR("Elaborazione in corso"), this, FALSE));
|
|
|
|
_text = new TMultiline_control(win(), DLG_NULL, 1, 0, hor-2, lines+1, 512, "CD", "");
|
|
_text->set_read_only();
|
|
set_text(testo);
|
|
|
|
if (bar)
|
|
{
|
|
RCT r; _text->get_rect(r);
|
|
_bar = r.bottom + CHARY;
|
|
}
|
|
|
|
if (cancel)
|
|
_cancel = new TPushbutton_control(win(), DLG_CANCEL, -11, -1, 12, 2, "", "", BMP_CANCEL);
|
|
|
|
open_modal();
|
|
do_events();
|
|
|
|
_indwin_count++;
|
|
_start_time = clock();
|
|
}
|
|
|
|
// @doc EXTERNAL
|
|
|
|
// @mfunc Setta il testo della finestra
|
|
void TIndwin::set_text(
|
|
const char* t) // @parm Testo della finestra
|
|
|
|
// @comm Si puo' chiamare questa funzione per cambiare il testo, ma
|
|
// le dimensioni della finestra sono calcolate sul primo testo
|
|
// passato, quindi occorre dimensionare correttamente il primo passato
|
|
// (es. inserire degli spazi) quando se ne prevede uno piu' lungo.
|
|
{
|
|
#ifdef XI_R4
|
|
_text->set_caption(t);
|
|
#else
|
|
TString testo(t);
|
|
testo.replace('\n', '\r');
|
|
_text->set_caption(testo);
|
|
#endif
|
|
|
|
if (_bar)
|
|
{
|
|
RCT r; get_bar_rct(r);
|
|
xvt_dwin_invalidate_rect(win(), &r);
|
|
}
|
|
}
|
|
|
|
TIndwin::~TIndwin()
|
|
{
|
|
if (is_open())
|
|
close_modal();
|
|
|
|
if (_cancel) delete _cancel;
|
|
if (_text) delete _text;
|
|
_indwin_count--;
|
|
}
|
|
|
|
bool TIndwin::can_be_closed() const
|
|
{
|
|
const bool ok = (_flags & IND_FINISHED) || (_flags & IND_CANCELLED);
|
|
if (!ok) error_box(TR("Attendere la fine dell'operazione prima di chiudere l'applicazione"));
|
|
return ok;
|
|
}
|
|
|
|
KEY TIndwin::check_stop()
|
|
{
|
|
KEY k = 0;
|
|
if ((_flags & IND_FINISHED) || (_flags & IND_CANCELLED))
|
|
{
|
|
k = (_flags & IND_FINISHED) ? K_ENTER : K_ESC;
|
|
stop_run(k);
|
|
}
|
|
return k;
|
|
}
|
|
|
|
RCT* TIndwin::get_bar_rct(RCT& r) const
|
|
{
|
|
xvt_vobj_get_client_rect(win(), &r);
|
|
r.left += CHARX;
|
|
r.right -= CHARX;
|
|
r.top = _bar;
|
|
r.bottom = r.top + ROWY;
|
|
return &r;
|
|
}
|
|
|
|
void TIndwin::update_bar()
|
|
{
|
|
if (_status >= _max)
|
|
{
|
|
_status = _max;
|
|
_flags |= IND_FINISHED;
|
|
}
|
|
|
|
// Percentuale raggiunta finora
|
|
const double prc = (double)_status / (double)_max;
|
|
|
|
// Rettangolo contenente l'intera barra
|
|
RCT r; get_bar_rct(r);
|
|
|
|
set_font();
|
|
if (ADVANCED_GRAPHICS)
|
|
{
|
|
const WINDOW w = win();
|
|
RCT b = r;
|
|
// Rettangolo scavato
|
|
xi_draw_3d_rect((XinWindow)w, (XinRect*)&b, TRUE, 2,
|
|
MASK_LIGHT_COLOR, MASK_BACK_COLOR, MASK_DARK_COLOR);
|
|
b.left += 2; b.right -= 2;
|
|
b.top += 2; b.bottom -= 2;
|
|
b.right = b.left + int((b.right-b.left)*prc + 0.5);
|
|
|
|
const int lasti = (b.bottom-b.top)/2;
|
|
for (int i = 0; i <= lasti; i++)
|
|
{
|
|
set_pen(blend_colors(FOCUS_BACK_COLOR, MASK_BACK_COLOR, double(i) / double(lasti)));
|
|
PNT pt = { b.top+i, b.left };
|
|
xvt_dwin_draw_set_pos(w, pt);
|
|
pt.h = b.right;
|
|
xvt_dwin_draw_line(w, pt);
|
|
|
|
pt.h = b.left;
|
|
pt.v = b.bottom-i-1;
|
|
xvt_dwin_draw_set_pos(w, pt);
|
|
pt.h = b.right;
|
|
xvt_dwin_draw_line(w, pt);
|
|
}
|
|
|
|
if (prc > 0)
|
|
{
|
|
const unsigned long elapsed_time = (clock() - _start_time)/CLOCKS_PER_SEC;
|
|
const unsigned long total_time = (unsigned long)(elapsed_time / prc);
|
|
unsigned long ss = total_time - elapsed_time;
|
|
const unsigned long hh = ss / 3600;
|
|
ss -= hh*3600;
|
|
const unsigned long mm = ss / 60;
|
|
ss -= mm *60;
|
|
TString80 n;
|
|
n.format(FR("%d%% - Tempo residuo stimato %02lu:%02lu:%02lu"), int(prc*100.0+0.5), hh, mm, ss);
|
|
|
|
b = r;
|
|
b.top = b.bottom+2;
|
|
b.bottom = b.top + CHARY;
|
|
|
|
CBRUSH brush; brush.pat = PAT_SOLID; brush.color = MASK_BACK_COLOR;
|
|
xvt_dwin_set_cbrush(w, &brush);
|
|
xvt_dwin_set_std_cpen(w, TL_PEN_HOLLOW);
|
|
xvt_dwin_draw_rect(w, &b);
|
|
xvt_dwin_draw_text(w, r.left, r.bottom+CHARY, n, -1);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Rettangolo in rilievo
|
|
RCT b = r;
|
|
b.right = b.left + int((r.right-r.left)*prc);
|
|
xi_draw_3d_rect((XinWindow)win(), (XinRect*)&b, FALSE, 2,
|
|
BTN_LIGHT_COLOR, BTN_BACK_COLOR, BTN_DARK_COLOR);
|
|
// Rettangolo scavato
|
|
b.left = b.right; b.right = r.right;
|
|
xi_draw_3d_rect((XinWindow)win(), (XinRect*)&b, TRUE, 2,
|
|
BTN_LIGHT_COLOR, BTN_BACK_COLOR, BTN_DARK_COLOR);
|
|
|
|
char n[8]; sprintf(n, "%d%%", int(prc * 100.0 + 0.5));
|
|
xvt_dwin_draw_text(win(), r.left+r.right/2-CHARX, (r.bottom+r.top+CHARY)/2-3, n, -1);
|
|
}
|
|
|
|
check_stop();
|
|
}
|
|
|
|
void TIndwin::update()
|
|
{
|
|
if (_bar)
|
|
update_bar();
|
|
}
|
|
|
|
bool TIndwin::on_key(KEY k)
|
|
{
|
|
if (k == K_ESC && _cancel)
|
|
{
|
|
_flags |= IND_CANCELLED;
|
|
check_stop();
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
void TIndwin::on_button(short id)
|
|
{
|
|
if (id == DLG_CANCEL)
|
|
on_key(K_ESC);
|
|
}
|
|
|
|
|
|
// TProgind --------------------------------------------------------------
|
|
|
|
TProgind::TProgind(long max, const char* txt, bool cancel, bool bar, int div)
|
|
: TIndwin(max, txt, cancel, bar, div)
|
|
{}
|
|
|
|
bool TProgind::setstatus(long l)
|
|
{
|
|
if (l < 0)
|
|
{
|
|
NFCHECK("Negative progind status");
|
|
l = 0;
|
|
}
|
|
const long old_perc = _status * 100L / _max;
|
|
_status = l > _max ? _max : l;
|
|
const long new_perc = _status * 100L / _max;
|
|
const bool tictac = new_perc != old_perc;
|
|
if (tictac)
|
|
{
|
|
update();
|
|
do_events();
|
|
}
|
|
return tictac;
|
|
}
|
|
|
|
// TTimerind ------------------------------------------------------------
|
|
|
|
long TTimerind::_timer_id = 0L;
|
|
|
|
void TTimerind::handler(WINDOW w, EVENT* e)
|
|
{
|
|
switch(e->type)
|
|
{
|
|
case E_CREATE:
|
|
case E_UPDATE:
|
|
if (_status == 0L)
|
|
_timer_id = xvt_timer_create(w, _interval);
|
|
break;
|
|
case E_TIMER:
|
|
if (e->v.timer.id == _timer_id)
|
|
{
|
|
_status += _interval;
|
|
force_update();
|
|
xvt_timer_create(w, _interval);
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
TIndwin::handler(w,e);
|
|
}
|
|
|
|
TTimerind::TTimerind(long msec, const char* txt,
|
|
bool cancel, bool bar, int div, int i) :
|
|
TIndwin(msec, txt, cancel, bar, div)
|
|
{
|
|
_interval = i;
|
|
_timer_id = 0L;
|
|
}
|
|
|
|
TTimerind::~TTimerind()
|
|
{
|
|
if (_timer_id != 0L)
|
|
xvt_timer_destroy(_timer_id);
|
|
}
|
|
|
|
// C-style binding
|
|
// uses static pointer for single instance of TIndwin
|
|
|
|
static TIndwin* __indwin__p = NULL;
|
|
|
|
void progind_create(long m, const char* t, bool b, bool c, int n)
|
|
{
|
|
CHECK(__indwin__p == NULL, "Cannot have more than one progress indicator");
|
|
__indwin__p = new TProgind(m,t,b,c,n);
|
|
}
|
|
|
|
void progind_set_status(long l)
|
|
{
|
|
((TProgind*)__indwin__p)->setstatus(l);
|
|
}
|
|
|
|
void progind_cancel()
|
|
{
|
|
__indwin__p->cancel();
|
|
}
|
|
|
|
bool progind_iscancelled()
|
|
{
|
|
return __indwin__p->iscancelled();
|
|
}
|
|
|
|
bool progind_isfinished()
|
|
{
|
|
return __indwin__p->isfinished();
|
|
}
|
|
|
|
void progind_destroy()
|
|
{
|
|
delete __indwin__p;
|
|
__indwin__p = NULL;
|
|
}
|
|
|
|
void timerind_create(long l, const char* title, bool bar, bool cancel,
|
|
int divisions, int interval)
|
|
{
|
|
CHECK(__indwin__p == NULL, "Cannot have more than one progress indicator");
|
|
__indwin__p = new TTimerind(l,title,bar,cancel,divisions,interval);
|
|
}
|
|
|
|
void timerind_cancel()
|
|
{
|
|
__indwin__p->cancel();
|
|
}
|
|
|
|
bool timerind_iscancelled()
|
|
{
|
|
return __indwin__p->iscancelled();
|
|
}
|
|
|
|
bool timerind_isfinished()
|
|
{
|
|
return __indwin__p->isfinished();
|
|
}
|
|
|
|
void timerind_destroy()
|
|
{
|
|
delete __indwin__p;
|
|
__indwin__p = NULL;
|
|
}
|
|
|