//
// Written by Curtis Olson, started February 2004.
//
-// Copyright (c) 2004 Curtis L. Olson - curt@flightgear.org
+// Copyright (c) 2004 Curtis L. Olson - http://www.flightgear.org/~curt
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
-// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
// $Id$
#include <iostream>
#include <string>
-#include <vector>
+#include <set>
+#include <sys/stat.h>
#ifdef _MSC_VER
# include <direct.h>
using std::cout;
using std::endl;
-using std::vector;
+using std::set;
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;
"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;
progress->minimum( min_progress );
progress->maximum( max_progress );
+
+ main_window->size_range( 465, 435 );
}
// show our UI
void FGAdminUI::update_install_box() {
- int i;
- vector<string> file_list;
- file_list.clear();
+ set<string> file_list;
install_box->clear();
- if ( source.length() && fl_filename_isdir(source.c_str()) ) {
+ if ( source.length() ) {
ulDir *dir = ulOpenDir( source.c_str() ) ;
ulDirEnt *ent;
- while ( ent = ulReadDir( dir ) ) {
+ while ( dir != 0 && ( ent = ulReadDir( dir ) ) ) {
// find base name of archive file
char base[FL_PATH_MAX];
strncpy( base, ent->d_name, FL_PATH_MAX );
const char *p = fl_filename_ext( base );
- int offset;
+ int offset, expected_length = 0;
if ( strcmp( p, ".gz" ) == 0 ) {
offset = p - base;
base[offset] = '\0';
if ( strcmp( p, ".tar" ) == 0 ) {
offset = p - base;
base[offset] = '\0';
+ expected_length = 14;
}
+ } else if ( strcmp( p, ".tgz" ) == 0 ) {
+ offset = p - base;
+ base[offset] = '\0';
+ expected_length = 11;
} else if ( strcmp( p, ".zip" ) == 0 ) {
offset = p - base;
base[offset] = '\0';
+ expected_length = 11;
}
- if ( strlen(ent->d_name) != 14 ) {
- // simple heuristic to ingore non-scenery files
+ if ( strlen(ent->d_name) != expected_length ) {
+ // simple heuristic to ignore non-scenery files
} else if ( ent->d_name[0] != 'e' && ent->d_name[0] != 'w' ) {
// further sanity checks on name
} else if ( ent->d_name[4] != 'n' && ent->d_name[4] != 's' ) {
install.append( base );
if ( ! fl_filename_isdir( install.c_str() ) ) {
// cout << install.str() << " install candidate." << endl;
- file_list.push_back( ent->d_name );
+ file_list.insert( ent->d_name );
} else {
// cout << install.str() << " exists." << endl;
}
}
}
- ulCloseDir( dir );
-
- // convert to a qsort()'able array
- string *sort_list = new string[file_list.size()];
- for ( i = 0; i < file_list.size(); ++i ) {
- sort_list[i] = fl_filename_name( file_list[i].c_str() );
- }
-
- // Sort the file list into display order
- qsort(sort_list, file_list.size(), sizeof(string), stringCompare);
- for ( int i = 0; i < file_list.size(); ++i ) {
- install_box->add( sort_list[i].c_str() );
+ ulCloseDir( dir );
+ for ( set<string>::iterator it = file_list.begin(); it != file_list.end(); ++it ) {
+ install_box->add( it->c_str() );
}
- delete [] sort_list;
-
install_box->redraw();
}
}
// scan the source directory and update the install_box contents
void FGAdminUI::update_remove_box() {
- int i;
- vector<string> dir_list;
- dir_list.clear();
remove_box->clear();
if ( dest.length() ) {
- ulDir *dir = ulOpenDir( dest.c_str() ) ;
- ulDirEnt *ent;
- while ( ent = ulReadDir( dir ) ) {
- if ( strlen(ent->d_name) != 7 ) {
- // simple heuristic to ingore non-scenery directories
- } else if ( ent->d_name[0] != 'e' && ent->d_name[0] != 'w' ) {
- // further sanity checks on name
- } else if ( ent->d_name[4] != 'n' && ent->d_name[4] != 's' ) {
- // further sanity checks on name
- } else {
- dir_list.push_back( ent->d_name );
- }
+ string path[2];
+ path[0] = dest + "/Terrain";
+ path[1] = dest + "/Objects";
+ if ( !fl_filename_isdir( path[0].c_str() ) ) {
+ path[0] = dest;
+ path[1] = "";
+ } else if ( !fl_filename_isdir( path[1].c_str() ) ) {
+ path[1] = "";
}
- ulCloseDir( dir );
- // convert to a qsort()'able array
- string *sort_list = new string[dir_list.size()];
- for ( i = 0; i < dir_list.size(); ++i ) {
- sort_list[i] = fl_filename_name( dir_list[i].c_str() );
+ set<string> dir_list;
+ for ( int i = 0; i < 2; i++ ) {
+ if ( !path[i].empty() ) {
+ ulDir *dir = ulOpenDir( path[i].c_str() ) ;
+ ulDirEnt *ent;
+ while ( dir != 0 && ( ent = ulReadDir( dir ) ) ) {
+ if ( strlen(ent->d_name) == 7 &&
+ ( ent->d_name[0] == 'e' || ent->d_name[0] == 'w' ) &&
+ ( ent->d_name[4] == 'n' || ent->d_name[4] == 's' ) ) {
+ dir_list.insert( ent->d_name );
+ }
+ }
+ ulCloseDir( dir );
+ }
}
- // Sort the file list into display order
- qsort(sort_list, dir_list.size(), sizeof(string), stringCompare);
-
- for ( int i = 0; i < dir_list.size(); ++i ) {
- remove_box->add( sort_list[i].c_str() );
+ for ( set<string>::iterator it = dir_list.begin(); it != dir_list.end(); ++it ) {
+ remove_box->add( it->c_str() );
}
- delete [] sort_list;
-
remove_box->redraw();
}
}
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 ) {
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();
}
-static void remove_dir( const char *dir_name, void (*step)(void*), void *data ) {
+static unsigned long count_dir( const char *dir_name, bool top = true ) {
+ unsigned long cnt = 0L;
ulDir *dir = ulOpenDir( dir_name ) ;
- ulDirEnt *ent;
- 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 );
- remove_dir( child.c_str(), step, data );
- } else {
- SGPath child( dir_name );
- child.append( ent->d_name );
- unlink( child.c_str() );
- if (step) step( data );
+ if ( dir ) {
+ ulDirEnt *ent;
+ 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(), false );
+ } else {
+ cnt += 1;
+ }
+ }
+ ulCloseDir( dir );
+ } else if ( top ) {
+ string base = dir_name;
+ size_t pos = base.rfind('/');
+ string file = base.substr( pos );
+ base.erase( pos );
+ string path = base + "/Terrain" + file;
+ cnt = count_dir( path.c_str(), false );
+ path = base + "/Objects" + file;
+ cnt += count_dir( path.c_str(), false );
+ }
+ return cnt;
+}
+
+static void remove_dir( const char *dir_name, void (*step)(void*,int), void *data, bool top = true ) {
+ ulDir *dir = ulOpenDir( dir_name ) ;
+ if ( dir ) {
+ ulDirEnt *ent;
+ 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 );
+ remove_dir( child.c_str(), step, data, false );
+ } else {
+ SGPath child( dir_name );
+ child.append( ent->d_name );
+ unlink( child.c_str() );
+ if (step) step( data, 1 );
+ }
}
+ ulCloseDir( dir );
+ rmdir( dir_name );
+ } else if ( top ) {
+ string base = dir_name;
+ size_t pos = base.rfind('/');
+ string file = base.substr( pos );
+ base.erase( pos );
+ string path = base + "/Terrain" + file;
+ remove_dir( path.c_str(), step, data, false );
+ path = base + "/Objects" + file;
+ remove_dir( path.c_str(), step, data, false );
}
- ulCloseDir( dir );
- rmdir( dir_name );
}
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();
}
-
void FGAdminUI::step(void *data)
{
Fl_Progress *p = ((FGAdminUI*)data)->progress;
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();
+}