diff --git a/utils/fgadmin/src/fgadmin.cxx b/utils/fgadmin/src/fgadmin.cxx index e9e55524b..db4368b69 100644 --- a/utils/fgadmin/src/fgadmin.cxx +++ b/utils/fgadmin/src/fgadmin.cxx @@ -1,6 +1,14 @@ // generated by Fast Light User Interface Designer (fluid) version 1.0104 #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*) { quit(); @@ -46,7 +54,7 @@ FGAdminUI::FGAdminUI() { Fl_Double_Window* w; { Fl_Double_Window* o = main_window = new Fl_Double_Window(465, 435, "FlightGear Admin Wizard"); 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"); o->callback((Fl_Callback*)cb_quit_b); } @@ -58,8 +66,12 @@ FGAdminUI::FGAdminUI() { o->callback((Fl_Callback*)cb_dest_b); } dest_text = new Fl_Input(235, 35, 225, 25); - 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"); + { Fl_Group* o = new Fl_Group(5, 65, 455, 270); + 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"); o->labelfont(1); o->callback((Fl_Callback*)cb_install_b); @@ -68,7 +80,7 @@ FGAdminUI::FGAdminUI() { o->labelfont(1); 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->selection_color((Fl_Color)175); } diff --git a/utils/fgadmin/src/fgadmin.fl b/utils/fgadmin/src/fgadmin.fl index afb2b62fc..d752a46c7 100644 --- a/utils/fgadmin/src/fgadmin.fl +++ b/utils/fgadmin/src/fgadmin.fl @@ -8,6 +8,8 @@ decl {\#include <string>} {public decl {\#include <FL/Fl_Preferences.H>} {public } +decl {\#include <FL/fl_ask.H>} {} + decl {using std::string;} {public } @@ -19,8 +21,9 @@ class FGAdminUI {open Function {FGAdminUI()} {open } { Fl_Window main_window { - label {FlightGear Admin Wizard} open - xywh {294 195 465 435} type Double visible + label {FlightGear Admin Wizard} + callback {fl_alert("Use the Quit button to exit fgadmin");} open + xywh {500 247 465 435} type Double resizable visible } { Fl_Button quit_b { label Quit @@ -45,13 +48,17 @@ refresh_lists();} Fl_Input dest_text { xywh {235 35 225 25} } - Fl_Check_Browser install_box { - label {Select Files to Install} - xywh {5 65 225 270} - } - Fl_Check_Browser remove_box { - label {Select Files to Remove} - xywh {235 65 225 270} + Fl_Group {} {open + xywh {5 65 455 270} resizable + } { + Fl_Check_Browser install_box { + label {Select Files to Install} + xywh {5 65 225 270} + } + Fl_Check_Browser remove_box { + label {Select Files to Remove} + xywh {235 65 225 270} + } } Fl_Button install_b { label {Install Selected Files} @@ -63,8 +70,8 @@ refresh_lists();} callback {remove_selected();} xywh {250 360 195 35} labelfont 1 } - Fl_Progress progress {selected - xywh {20 405 195 25} color 49 selection_color 175 + Fl_Progress progress { + xywh {5 405 345 25} color 49 selection_color 175 } } } @@ -74,7 +81,9 @@ refresh_lists();} } 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 quit();} {} @@ -87,4 +96,5 @@ refresh_lists();} decl {Fl_Preferences *prefs;} {} decl {string source;} {} decl {string dest;} {} + decl {string progress_label;} {} } diff --git a/utils/fgadmin/src/fgadmin.h b/utils/fgadmin/src/fgadmin.h index 42926f263..cff861278 100644 --- a/utils/fgadmin/src/fgadmin.h +++ b/utils/fgadmin/src/fgadmin.h @@ -9,6 +9,7 @@ using std::string; #include <FL/Fl_Double_Window.H> #include <FL/Fl_Button.H> #include <FL/Fl_Input.H> +#include <FL/Fl_Group.H> #include <FL/Fl_Check_Browser.H> #include <FL/Fl_Progress.H> @@ -16,6 +17,10 @@ class FGAdminUI { public: FGAdminUI(); 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; private: inline void cb_quit_b_i(Fl_Button*, void*); @@ -50,6 +55,7 @@ public: void init(); void show(); static void step( void * ); + static void step( void *, int ); private: void refresh_lists(); void quit(); @@ -62,5 +68,6 @@ private: Fl_Preferences *prefs; string source; string dest; + string progress_label; }; #endif diff --git a/utils/fgadmin/src/fgadmin_funcs.cxx b/utils/fgadmin/src/fgadmin_funcs.cxx index 261c16cad..ba52467d2 100644 --- a/utils/fgadmin/src/fgadmin_funcs.cxx +++ b/utils/fgadmin/src/fgadmin_funcs.cxx @@ -24,6 +24,7 @@ #include <iostream> #include <string> #include <vector> +#include <sys/stat.h> #ifdef _MSC_VER # include <direct.h> @@ -42,6 +43,9 @@ using std::endl; using std::vector; using std::string; +extern string def_install_source; +extern string def_scenery_dest; + static const float min_progress = 0.0; static const float max_progress = 5000.0; @@ -57,11 +61,11 @@ void FGAdminUI::init() { "flightgear.org", "fgadmin" ); 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 = 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 = buf; @@ -69,6 +73,8 @@ void FGAdminUI::init() { progress->minimum( min_progress ); progress->maximum( max_progress ); + + main_window->size_range( 465, 435 ); } // show our UI @@ -249,6 +255,7 @@ void FGAdminUI::install_selected() { install_b->deactivate(); remove_b->deactivate(); + quit_b->deactivate(); // traverse install box and install each item for ( int i = 0; i <= install_box->nitems(); ++i ) { @@ -256,14 +263,23 @@ void FGAdminUI::install_selected() { f = install_box->text( i ); SGPath file( source ); 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 ); main_window->cursor( FL_CURSOR_WAIT ); tarextract( (char *)file.c_str(), (char *)dest.c_str(), true, &FGAdminUI::step, this ); progress->value( min_progress ); main_window->cursor( FL_CURSOR_DEFAULT ); + progress->label( "" ); + progress->maximum( old_max ); } } + quit_b->activate(); install_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 ) ; ulDirEnt *ent; 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 ); child.append( ent->d_name ); unlink( child.c_str() ); - if (step) step( data ); + if (step) step( data, 1 ); } } ulCloseDir( dir ); @@ -301,20 +338,28 @@ void FGAdminUI::remove_selected() { install_b->deactivate(); remove_b->deactivate(); + quit_b->deactivate(); // traverse remove box and recursively remove each item for ( int i = 0; i <= remove_box->nitems(); ++i ) { if ( remove_box->checked( i ) ) { f = remove_box->text( i ); SGPath dir( dest ); dir.append( f ); + float old_max = progress->maximum(); + progress_label = "Removing "; + progress_label += f; + progress->label( progress_label.c_str() ); progress->value( min_progress ); 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 ); progress->value( min_progress ); main_window->cursor( FL_CURSOR_DEFAULT ); + progress->label( "" ); + progress->maximum( old_max ); } } + quit_b->activate(); install_b->activate(); remove_b->activate(); @@ -322,7 +367,6 @@ void FGAdminUI::remove_selected() { } - void FGAdminUI::step(void *data) { Fl_Progress *p = ((FGAdminUI*)data)->progress; @@ -338,3 +382,13 @@ void FGAdminUI::step(void *data) 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(); +} diff --git a/utils/fgadmin/src/main.cxx b/utils/fgadmin/src/main.cxx index ae0821522..45ac1e14f 100644 --- a/utils/fgadmin/src/main.cxx +++ b/utils/fgadmin/src/main.cxx @@ -27,41 +27,39 @@ #include <string> #include <FL/Fl.H> +#include <FL/filename.H> #include "fgadmin.h" -std::string def_fg_exe = ""; -std::string def_fg_root = ""; -std::string def_fg_scenery = ""; +using std::string; + +string def_install_source; +string def_scenery_dest; +bool silent = false; /** - * --fg-exe=<PATH> - * --fg-root=<DIR> - * --fg-scenery=<DIR> + * --silent + * --install-source=<DIR> + * --scenery-dest=<DIR> */ static int 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; return 1; } - - if (strncmp( argv[i], "--fg-root=", 10 ) == 0) + else if (strncmp( argv[i], "--install-source=", 17 ) == 0) { - def_fg_root.assign( &argv[i][10] ); - def_fg_scenery = def_fg_root; - def_fg_scenery += "/Scenery"; - + def_install_source.assign( &argv[i][17] ); ++i; return 1; } - - if (strncmp( argv[i], "--fg-scenery=", 13 ) == 0) + else if (strncmp( argv[i], "--scenery-dest=", 15 ) == 0) { - def_fg_scenery.assign( &argv[i][13] ); + def_scenery_dest.assign( &argv[i][15] ); ++i; return 1; } @@ -75,7 +73,21 @@ main( int argc, char* argv[] ) int i = 0; 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; diff --git a/utils/fgadmin/src/untarka.c b/utils/fgadmin/src/untarka.c index f7f35bd89..8ca6b452a 100644 --- a/utils/fgadmin/src/untarka.c +++ b/utils/fgadmin/src/untarka.c @@ -101,6 +101,8 @@ static void error OF((const char *msg)); +static unsigned long total_read; + /* #define TAR_GZ 1 */ typedef struct Readable { @@ -117,10 +119,11 @@ typedef struct Readable { enum { FMT_U=1, FMT_Z=2, FMT_GZ=3, FMT_BZ2=4 }; /* #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 unsigned xU_Read(struct Readable* self, void* buf, unsigned len) { unsigned got=fread(buf,1,len,(FILE*)self->f); + total_read+=got; 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"; } @@ -154,9 +157,9 @@ static char const* xZ_Error(struct Readable* self, int *errnum_ret) { #if HAVE_ZLIB #include "zlib.h" /* #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 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); } #endif @@ -1166,7 +1169,7 @@ static int matchname (int arg,int argc,char **argv,char *fname) /* 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; int is_tar_ok=0; int len; @@ -1176,6 +1179,7 @@ static int tar (Readable* rin,int action,int arg,int argc,char **argv, char cons FILE *outfile = NULL; char fname[BLOCKSIZE]; time_t tartime; + unsigned long last_read; #if 0 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); #endif + last_read = 0; if (action == TGZ_LIST) printf(" day time size file\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); if (len+1 == 0) 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))) { fprintf(stderr, "%s: compressed file not tared: %s\n", prog, TGZfile); 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; utime(fname,&settime); #endif - if (step) step(data); } } }