]> git.mxchange.org Git - flightgear.git/blobdiff - utils/fgadmin/src/fgadmin_funcs.cxx
Remove carrier wire and catapult configuration from the scenario file.
[flightgear.git] / utils / fgadmin / src / fgadmin_funcs.cxx
index cc04f0c976969df4780b9156a15c4c670bc84894..c8530a4c88a922562049b1d5c0dff6c818d0c6b8 100644 (file)
@@ -2,7 +2,7 @@
 //
 // 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;
 
@@ -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
@@ -131,21 +137,19 @@ static int stringCompare(const void *string1, const void *string2)
 
 
 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';
@@ -153,14 +157,20 @@ void FGAdminUI::update_install_box() {
                 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' ) {
@@ -171,29 +181,18 @@ void FGAdminUI::update_install_box() {
                 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();
     }
 }
@@ -201,43 +200,40 @@ void FGAdminUI::update_install_box() {
 
 // 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();
     }
 }
@@ -249,6 +245,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 +253,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,27 +277,70 @@ 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, 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 );
 }
 
 
@@ -301,20 +350,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 +379,6 @@ void FGAdminUI::remove_selected() {
    
 }
 
-
 void FGAdminUI::step(void *data)
 {
    Fl_Progress *p = ((FGAdminUI*)data)->progress;
@@ -338,3 +394,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();
+}