1
0
Fork 0

Frederic Bouvier:

I made some changes to current CVS :

 - the window is gently resizable, keeping the buttons' height
   unchanged, with a minimun size,
 - the current activity ( installation or removal ) is displayed
   in the progress bar,
 - the progress status is exact. For installation, I am
   using the total bytes read vs the file size. I had to hack
   untarka somehow and bzip2 and Z methods needs to be implemented.
   For removal, I am counting files by in-depth traversal, in the
   same way remove_dir is working. This seems very quick and
   the overhead is unnoticable.
 - the Quit button is the only way to quit the program, and it is
   deactivated during work. Otherwise, we can get the window hidden
   but the program still running in background.
 - cleanup on start options that seemed to be copied from fgrun.
   Valid options are now :
     --silent
            to write fgadmin.prefs and stop immediately
     --install-source=<DIR>
     --scenery-dest=<DIR>
This commit is contained in:
curt 2004-03-15 20:34:38 +00:00
parent 00002357b3
commit c16feaa963
6 changed files with 146 additions and 46 deletions

View file

@ -1,6 +1,14 @@
// generated by Fast Light User Interface Designer (fluid) version 1.0104 // generated by Fast Light User Interface Designer (fluid) version 1.0104
#include "fgadmin.h" #include "fgadmin.h"
#include <FL/fl_ask.H>
inline void FGAdminUI::cb_main_window_i(Fl_Double_Window*, void*) {
fl_alert("Use the Quit button to exit fgadmin");
}
void FGAdminUI::cb_main_window(Fl_Double_Window* o, void* v) {
((FGAdminUI*)(o->user_data()))->cb_main_window_i(o,v);
}
inline void FGAdminUI::cb_quit_b_i(Fl_Button*, void*) { inline void FGAdminUI::cb_quit_b_i(Fl_Button*, void*) {
quit(); quit();
@ -46,7 +54,7 @@ FGAdminUI::FGAdminUI() {
Fl_Double_Window* w; Fl_Double_Window* w;
{ Fl_Double_Window* o = main_window = new Fl_Double_Window(465, 435, "FlightGear Admin Wizard"); { Fl_Double_Window* o = main_window = new Fl_Double_Window(465, 435, "FlightGear Admin Wizard");
w = o; w = o;
o->user_data((void*)(this)); o->callback((Fl_Callback*)cb_main_window, (void*)(this));
{ Fl_Button* o = quit_b = new Fl_Button(360, 405, 85, 25, "Quit"); { Fl_Button* o = quit_b = new Fl_Button(360, 405, 85, 25, "Quit");
o->callback((Fl_Callback*)cb_quit_b); o->callback((Fl_Callback*)cb_quit_b);
} }
@ -58,8 +66,12 @@ FGAdminUI::FGAdminUI() {
o->callback((Fl_Callback*)cb_dest_b); o->callback((Fl_Callback*)cb_dest_b);
} }
dest_text = new Fl_Input(235, 35, 225, 25); dest_text = new Fl_Input(235, 35, 225, 25);
install_box = new Fl_Check_Browser(5, 65, 225, 270, "Select Files to Install"); { Fl_Group* o = new Fl_Group(5, 65, 455, 270);
remove_box = new Fl_Check_Browser(235, 65, 225, 270, "Select Files to Remove"); install_box = new Fl_Check_Browser(5, 65, 225, 270, "Select Files to Install");
remove_box = new Fl_Check_Browser(235, 65, 225, 270, "Select Files to Remove");
o->end();
Fl_Group::current()->resizable(o);
}
{ Fl_Button* o = install_b = new Fl_Button(20, 360, 195, 35, "Install Selected Files"); { Fl_Button* o = install_b = new Fl_Button(20, 360, 195, 35, "Install Selected Files");
o->labelfont(1); o->labelfont(1);
o->callback((Fl_Callback*)cb_install_b); o->callback((Fl_Callback*)cb_install_b);
@ -68,7 +80,7 @@ FGAdminUI::FGAdminUI() {
o->labelfont(1); o->labelfont(1);
o->callback((Fl_Callback*)cb_remove_b); o->callback((Fl_Callback*)cb_remove_b);
} }
{ Fl_Progress* o = progress = new Fl_Progress(20, 405, 195, 25); { Fl_Progress* o = progress = new Fl_Progress(5, 405, 345, 25);
o->color(FL_BACKGROUND_COLOR); o->color(FL_BACKGROUND_COLOR);
o->selection_color((Fl_Color)175); o->selection_color((Fl_Color)175);
} }

View file

@ -8,6 +8,8 @@ decl {\#include <string>} {public
decl {\#include <FL/Fl_Preferences.H>} {public decl {\#include <FL/Fl_Preferences.H>} {public
} }
decl {\#include <FL/fl_ask.H>} {}
decl {using std::string;} {public decl {using std::string;} {public
} }
@ -19,8 +21,9 @@ class FGAdminUI {open
Function {FGAdminUI()} {open Function {FGAdminUI()} {open
} { } {
Fl_Window main_window { Fl_Window main_window {
label {FlightGear Admin Wizard} open label {FlightGear Admin Wizard}
xywh {294 195 465 435} type Double visible callback {fl_alert("Use the Quit button to exit fgadmin");} open
xywh {500 247 465 435} type Double resizable visible
} { } {
Fl_Button quit_b { Fl_Button quit_b {
label Quit label Quit
@ -45,13 +48,17 @@ refresh_lists();}
Fl_Input dest_text { Fl_Input dest_text {
xywh {235 35 225 25} xywh {235 35 225 25}
} }
Fl_Check_Browser install_box { Fl_Group {} {open
label {Select Files to Install} xywh {5 65 455 270} resizable
xywh {5 65 225 270} } {
} Fl_Check_Browser install_box {
Fl_Check_Browser remove_box { label {Select Files to Install}
label {Select Files to Remove} xywh {5 65 225 270}
xywh {235 65 225 270} }
Fl_Check_Browser remove_box {
label {Select Files to Remove}
xywh {235 65 225 270}
}
} }
Fl_Button install_b { Fl_Button install_b {
label {Install Selected Files} label {Install Selected Files}
@ -63,8 +70,8 @@ refresh_lists();}
callback {remove_selected();} callback {remove_selected();}
xywh {250 360 195 35} labelfont 1 xywh {250 360 195 35} labelfont 1
} }
Fl_Progress progress {selected Fl_Progress progress {
xywh {20 405 195 25} color 49 selection_color 175 xywh {5 405 345 25} color 49 selection_color 175
} }
} }
} }
@ -74,7 +81,9 @@ refresh_lists();}
} }
decl {void show();} {public decl {void show();} {public
} }
decl {static void step( void * );} {public decl {static void step( void * );} {selected public
}
decl {static void step( void *, int );} {public
} }
decl {void refresh_lists();} {} decl {void refresh_lists();} {}
decl {void quit();} {} decl {void quit();} {}
@ -87,4 +96,5 @@ refresh_lists();}
decl {Fl_Preferences *prefs;} {} decl {Fl_Preferences *prefs;} {}
decl {string source;} {} decl {string source;} {}
decl {string dest;} {} decl {string dest;} {}
decl {string progress_label;} {}
} }

View file

@ -9,6 +9,7 @@ using std::string;
#include <FL/Fl_Double_Window.H> #include <FL/Fl_Double_Window.H>
#include <FL/Fl_Button.H> #include <FL/Fl_Button.H>
#include <FL/Fl_Input.H> #include <FL/Fl_Input.H>
#include <FL/Fl_Group.H>
#include <FL/Fl_Check_Browser.H> #include <FL/Fl_Check_Browser.H>
#include <FL/Fl_Progress.H> #include <FL/Fl_Progress.H>
@ -16,6 +17,10 @@ class FGAdminUI {
public: public:
FGAdminUI(); FGAdminUI();
Fl_Double_Window *main_window; Fl_Double_Window *main_window;
private:
inline void cb_main_window_i(Fl_Double_Window*, void*);
static void cb_main_window(Fl_Double_Window*, void*);
public:
Fl_Button *quit_b; Fl_Button *quit_b;
private: private:
inline void cb_quit_b_i(Fl_Button*, void*); inline void cb_quit_b_i(Fl_Button*, void*);
@ -50,6 +55,7 @@ public:
void init(); void init();
void show(); void show();
static void step( void * ); static void step( void * );
static void step( void *, int );
private: private:
void refresh_lists(); void refresh_lists();
void quit(); void quit();
@ -62,5 +68,6 @@ private:
Fl_Preferences *prefs; Fl_Preferences *prefs;
string source; string source;
string dest; string dest;
string progress_label;
}; };
#endif #endif

View file

@ -24,6 +24,7 @@
#include <iostream> #include <iostream>
#include <string> #include <string>
#include <vector> #include <vector>
#include <sys/stat.h>
#ifdef _MSC_VER #ifdef _MSC_VER
# include <direct.h> # include <direct.h>
@ -42,6 +43,9 @@ using std::endl;
using std::vector; using std::vector;
using std::string; using std::string;
extern string def_install_source;
extern string def_scenery_dest;
static const float min_progress = 0.0; static const float min_progress = 0.0;
static const float max_progress = 5000.0; static const float max_progress = 5000.0;
@ -57,11 +61,11 @@ void FGAdminUI::init() {
"flightgear.org", "flightgear.org",
"fgadmin" ); "fgadmin" );
char buf[FL_PATH_MAX]; char buf[FL_PATH_MAX];
prefs->get( "install-source", buf, "", FL_PATH_MAX ); prefs->get( "install-source", buf, def_install_source.c_str(), FL_PATH_MAX );
source_text->value( buf ); source_text->value( buf );
source = buf; source = buf;
prefs->get( "scenery-dest", buf, "", FL_PATH_MAX ); prefs->get( "scenery-dest", buf, def_scenery_dest.c_str(), FL_PATH_MAX );
dest_text->value( buf ); dest_text->value( buf );
dest = buf; dest = buf;
@ -69,6 +73,8 @@ void FGAdminUI::init() {
progress->minimum( min_progress ); progress->minimum( min_progress );
progress->maximum( max_progress ); progress->maximum( max_progress );
main_window->size_range( 465, 435 );
} }
// show our UI // show our UI
@ -249,6 +255,7 @@ void FGAdminUI::install_selected() {
install_b->deactivate(); install_b->deactivate();
remove_b->deactivate(); remove_b->deactivate();
quit_b->deactivate();
// traverse install box and install each item // traverse install box and install each item
for ( int i = 0; i <= install_box->nitems(); ++i ) { for ( int i = 0; i <= install_box->nitems(); ++i ) {
@ -256,14 +263,23 @@ void FGAdminUI::install_selected() {
f = install_box->text( i ); f = install_box->text( i );
SGPath file( source ); SGPath file( source );
file.append( f ); file.append( f );
cout << "installing " << file.str() << endl; struct stat info;
stat( file.str().c_str(), &info );
float old_max = progress->maximum();
progress->maximum( info.st_size );
progress_label = "Installing ";
progress_label += f;
progress->label( progress_label.c_str() );
progress->value( min_progress ); progress->value( min_progress );
main_window->cursor( FL_CURSOR_WAIT ); main_window->cursor( FL_CURSOR_WAIT );
tarextract( (char *)file.c_str(), (char *)dest.c_str(), true, &FGAdminUI::step, this ); tarextract( (char *)file.c_str(), (char *)dest.c_str(), true, &FGAdminUI::step, this );
progress->value( min_progress ); progress->value( min_progress );
main_window->cursor( FL_CURSOR_DEFAULT ); main_window->cursor( FL_CURSOR_DEFAULT );
progress->label( "" );
progress->maximum( old_max );
} }
} }
quit_b->activate();
install_b->activate(); install_b->activate();
remove_b->activate(); remove_b->activate();
@ -271,7 +287,28 @@ void FGAdminUI::install_selected() {
} }
static void remove_dir( const char *dir_name, void (*step)(void*), void *data ) { static unsigned long count_dir( const char *dir_name ) {
ulDir *dir = ulOpenDir( dir_name ) ;
ulDirEnt *ent;
unsigned long cnt = 0L;
while ( ent = ulReadDir( dir ) ) {
if ( strcmp( ent->d_name, "." ) == 0 ) {
// ignore "."
} else if ( strcmp( ent->d_name, ".." ) == 0 ) {
// ignore ".."
} else if ( ent->d_isdir ) {
SGPath child( dir_name );
child.append( ent->d_name );
cnt += count_dir( child.c_str() );
} else {
cnt += 1;
}
}
ulCloseDir( dir );
return cnt;
}
static void remove_dir( const char *dir_name, void (*step)(void*,int), void *data ) {
ulDir *dir = ulOpenDir( dir_name ) ; ulDir *dir = ulOpenDir( dir_name ) ;
ulDirEnt *ent; ulDirEnt *ent;
while ( ent = ulReadDir( dir ) ) { while ( ent = ulReadDir( dir ) ) {
@ -287,7 +324,7 @@ static void remove_dir( const char *dir_name, void (*step)(void*), void *data )
SGPath child( dir_name ); SGPath child( dir_name );
child.append( ent->d_name ); child.append( ent->d_name );
unlink( child.c_str() ); unlink( child.c_str() );
if (step) step( data ); if (step) step( data, 1 );
} }
} }
ulCloseDir( dir ); ulCloseDir( dir );
@ -301,20 +338,28 @@ void FGAdminUI::remove_selected() {
install_b->deactivate(); install_b->deactivate();
remove_b->deactivate(); remove_b->deactivate();
quit_b->deactivate();
// traverse remove box and recursively remove each item // traverse remove box and recursively remove each item
for ( int i = 0; i <= remove_box->nitems(); ++i ) { for ( int i = 0; i <= remove_box->nitems(); ++i ) {
if ( remove_box->checked( i ) ) { if ( remove_box->checked( i ) ) {
f = remove_box->text( i ); f = remove_box->text( i );
SGPath dir( dest ); SGPath dir( dest );
dir.append( f ); dir.append( f );
float old_max = progress->maximum();
progress_label = "Removing ";
progress_label += f;
progress->label( progress_label.c_str() );
progress->value( min_progress ); progress->value( min_progress );
main_window->cursor( FL_CURSOR_WAIT ); main_window->cursor( FL_CURSOR_WAIT );
cout << "removing " << dir.str() << endl; progress->maximum( count_dir( dir.c_str() ) );
remove_dir( dir.c_str(), &FGAdminUI::step, this ); remove_dir( dir.c_str(), &FGAdminUI::step, this );
progress->value( min_progress ); progress->value( min_progress );
main_window->cursor( FL_CURSOR_DEFAULT ); main_window->cursor( FL_CURSOR_DEFAULT );
progress->label( "" );
progress->maximum( old_max );
} }
} }
quit_b->activate();
install_b->activate(); install_b->activate();
remove_b->activate(); remove_b->activate();
@ -322,7 +367,6 @@ void FGAdminUI::remove_selected() {
} }
void FGAdminUI::step(void *data) void FGAdminUI::step(void *data)
{ {
Fl_Progress *p = ((FGAdminUI*)data)->progress; Fl_Progress *p = ((FGAdminUI*)data)->progress;
@ -338,3 +382,13 @@ void FGAdminUI::step(void *data)
Fl::check(); Fl::check();
} }
void FGAdminUI::step(void *data, int n)
{
Fl_Progress *p = ((FGAdminUI*)data)->progress;
float tmp = p->value() + n;
p->value( tmp );
Fl::check();
}

View file

@ -27,41 +27,39 @@
#include <string> #include <string>
#include <FL/Fl.H> #include <FL/Fl.H>
#include <FL/filename.H>
#include "fgadmin.h" #include "fgadmin.h"
std::string def_fg_exe = ""; using std::string;
std::string def_fg_root = "";
std::string def_fg_scenery = ""; string def_install_source;
string def_scenery_dest;
bool silent = false;
/** /**
* --fg-exe=<PATH> * --silent
* --fg-root=<DIR> * --install-source=<DIR>
* --fg-scenery=<DIR> * --scenery-dest=<DIR>
*/ */
static int static int
parse_args( int, char** argv, int& i ) parse_args( int, char** argv, int& i )
{ {
if (strncmp( argv[i], "--fg-exe=", 9 ) == 0) if (strcmp( argv[i], "--silent" ) == 0)
{ {
def_fg_exe.assign( &argv[i][9] ); silent = true;
++i; ++i;
return 1; return 1;
} }
else if (strncmp( argv[i], "--install-source=", 17 ) == 0)
if (strncmp( argv[i], "--fg-root=", 10 ) == 0)
{ {
def_fg_root.assign( &argv[i][10] ); def_install_source.assign( &argv[i][17] );
def_fg_scenery = def_fg_root;
def_fg_scenery += "/Scenery";
++i; ++i;
return 1; return 1;
} }
else if (strncmp( argv[i], "--scenery-dest=", 15 ) == 0)
if (strncmp( argv[i], "--fg-scenery=", 13 ) == 0)
{ {
def_fg_scenery.assign( &argv[i][13] ); def_scenery_dest.assign( &argv[i][15] );
++i; ++i;
return 1; return 1;
} }
@ -75,7 +73,21 @@ main( int argc, char* argv[] )
int i = 0; int i = 0;
if (Fl::args( argc, argv, i, parse_args ) < argc) if (Fl::args( argc, argv, i, parse_args ) < argc)
{ {
Fl::fatal("Options are:\n --fg-exe=<PATH>\n --fg-root=<DIR>\n --fg-scenery=<DIR>\n%s", Fl::help ); Fl::fatal("Options are:\n --silent\n --install-source=<DIR>\n --scenery-dest=<DIR>\n%s", Fl::help );
}
if ( silent )
{
Fl_Preferences prefs( Fl_Preferences::USER, "flightgear.org", "fgadmin" );
char abs_name[ FL_PATH_MAX ];
fl_filename_absolute( abs_name, def_install_source.c_str() );
prefs.set( "install-source", abs_name );
fl_filename_absolute( abs_name, def_scenery_dest.c_str() );
prefs.set( "scenery-dest", abs_name );
return 0;
} }
FGAdminUI ui; FGAdminUI ui;

View file

@ -101,6 +101,8 @@
static void error OF((const char *msg)); static void error OF((const char *msg));
static unsigned long total_read;
/* #define TAR_GZ 1 */ /* #define TAR_GZ 1 */
typedef struct Readable { typedef struct Readable {
@ -117,10 +119,11 @@ typedef struct Readable {
enum { FMT_U=1, FMT_Z=2, FMT_GZ=3, FMT_BZ2=4 }; enum { FMT_U=1, FMT_Z=2, FMT_GZ=3, FMT_BZ2=4 };
/* #define xFILE FILE* */ /* #define xFILE FILE* */
static int xU_Open4Read(struct Readable* self, char const* filename) { return NULL==(self->f=fopen(filename,"rb")); } static int xU_Open4Read(struct Readable* self, char const* filename) { total_read=0; return NULL==(self->f=fopen(filename,"rb")); }
static int xU_Close(struct Readable* self) { return fclose((FILE*)self->f); } static int xU_Close(struct Readable* self) { return fclose((FILE*)self->f); }
static unsigned xU_Read(struct Readable* self, void* buf, unsigned len) { static unsigned xU_Read(struct Readable* self, void* buf, unsigned len) {
unsigned got=fread(buf,1,len,(FILE*)self->f); unsigned got=fread(buf,1,len,(FILE*)self->f);
total_read+=got;
return got>0 ? got : ferror((FILE*)self->f) ? 0U-1 : 0; return got>0 ? got : ferror((FILE*)self->f) ? 0U-1 : 0;
} }
static char const* xU_Error(struct Readable* self, int *errnum_ret) { return (*errnum_ret=ferror((FILE*)self->f))?"I/O error":"OK"; } static char const* xU_Error(struct Readable* self, int *errnum_ret) { return (*errnum_ret=ferror((FILE*)self->f))?"I/O error":"OK"; }
@ -154,9 +157,9 @@ static char const* xZ_Error(struct Readable* self, int *errnum_ret) {
#if HAVE_ZLIB #if HAVE_ZLIB
#include "zlib.h" #include "zlib.h"
/* #define xFILE gzFile */ /* #define xFILE gzFile */
static int xGZ_Open4Read(struct Readable* self, char const* filename) { return NULL==(self->f=gzopen(filename,"rb")); } static int xGZ_Open4Read(struct Readable* self, char const* filename) { total_read=0; return NULL==(self->f=gzopen(filename,"rb")); }
static int xGZ_Close(struct Readable* self) { return gzclose((gzFile)self->f); } static int xGZ_Close(struct Readable* self) { return gzclose((gzFile)self->f); }
static unsigned xGZ_Read(struct Readable* self, void* buf, unsigned len) { return gzread((gzFile)self->f,buf,len); } static unsigned xGZ_Read(struct Readable* self, void* buf, unsigned len) { unsigned l=gzread((gzFile)self->f,buf,len); total_read=((z_streamp)self->f)->total_in; return l; }
static char const* xGZ_Error(struct Readable* self, int *errnum_ret) { return gzerror((gzFile)self->f, errnum_ret); } static char const* xGZ_Error(struct Readable* self, int *errnum_ret) { return gzerror((gzFile)self->f, errnum_ret); }
#endif #endif
@ -1166,7 +1169,7 @@ static int matchname (int arg,int argc,char **argv,char *fname)
/* Tar file list or extract */ /* Tar file list or extract */
static int tar (Readable* rin,int action,int arg,int argc,char **argv, char const* TGZfile, int verbose, void (*step)(void *), void *data) { static int tar (Readable* rin,int action,int arg,int argc,char **argv, char const* TGZfile, int verbose, void (*step)(void *,int), void *data) {
union tar_buffer buffer; union tar_buffer buffer;
int is_tar_ok=0; int is_tar_ok=0;
int len; int len;
@ -1176,6 +1179,7 @@ static int tar (Readable* rin,int action,int arg,int argc,char **argv, char cons
FILE *outfile = NULL; FILE *outfile = NULL;
char fname[BLOCKSIZE]; char fname[BLOCKSIZE];
time_t tartime; time_t tartime;
unsigned long last_read;
#if 0 #if 0
while (0<(len=rin->xRead(rin, &buffer, BLOCKSIZE))) { while (0<(len=rin->xRead(rin, &buffer, BLOCKSIZE))) {
@ -1184,6 +1188,7 @@ static int tar (Readable* rin,int action,int arg,int argc,char **argv, char cons
exit(0); exit(0);
#endif #endif
last_read = 0;
if (action == TGZ_LIST) if (action == TGZ_LIST)
printf(" day time size file\n" printf(" day time size file\n"
" ---------- -------- --------- -------------------------------------\n"); " ---------- -------- --------- -------------------------------------\n");
@ -1191,6 +1196,7 @@ static int tar (Readable* rin,int action,int arg,int argc,char **argv, char cons
len = rin->xRead(rin, &buffer, BLOCKSIZE); len = rin->xRead(rin, &buffer, BLOCKSIZE);
if (len+1 == 0) if (len+1 == 0)
error (rin->xError(rin, &err)); error (rin->xError(rin, &err));
if (step) { step(data,total_read - last_read); last_read = total_read; }
if (!is_tar_ok && !(is_tar_ok=is_tar(buffer.buffer, len))) { if (!is_tar_ok && !(is_tar_ok=is_tar(buffer.buffer, len))) {
fprintf(stderr, "%s: compressed file not tared: %s\n", prog, TGZfile); fprintf(stderr, "%s: compressed file not tared: %s\n", prog, TGZfile);
if (action == TGZ_EXTRACT) { if (action == TGZ_EXTRACT) {
@ -1341,7 +1347,6 @@ static int tar (Readable* rin,int action,int arg,int argc,char **argv, char cons
outfile = NULL; outfile = NULL;
utime(fname,&settime); utime(fname,&settime);
#endif #endif
if (step) step(data);
} }
} }
} }