1
0
Fork 0
flightgear/utils/fgadmin/src/fgadmin_funcs.cxx

283 lines
7.4 KiB
C++
Raw Normal View History

2004-02-15 04:00:48 +00:00
// fgadmin_funcs.cxx -- FG Admin UI functions.
//
// Written by Curtis Olson, started February 2004.
//
// Copyright (c) 2004 Curtis L. Olson - curt@flightgear.org
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// 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.
//
// $Id$
#include <iostream>
#include <string>
#include <vector>
#ifdef _MSC_VER
# include <direct.h>
#endif
2004-02-15 04:00:48 +00:00
#include <FL/Fl_File_Chooser.H>
#include <plib/ul.h>
#include <simgear/misc/sg_path.hxx>
#include "fgadmin.h"
#include "untarka.h"
2004-02-15 04:00:48 +00:00
using std::cout;
using std::endl;
using std::vector;
using std::string;
// destructor
FGAdminUI::~FGAdminUI() {
delete prefs;
}
// initialize additional class elements
void FGAdminUI::init() {
prefs = new Fl_Preferences( Fl_Preferences::USER,
"flightgear.org",
"fgadmin" );
char buf[FL_PATH_MAX];
prefs->get( "install-source", buf, "", FL_PATH_MAX );
source_text->value( buf );
source = buf;
prefs->get( "scenery-dest", buf, "", FL_PATH_MAX );
dest_text->value( buf );
dest = buf;
refresh_lists();
}
// show our UI
void FGAdminUI::show() {
main_window->show();
}
// refresh the check box lists
void FGAdminUI::refresh_lists() {
update_install_box();
update_remove_box();
}
// scan the source directory and update the install_box contents
// quit
void FGAdminUI::quit() {
main_window->hide();
}
// select the install source
void FGAdminUI::select_install_source() {
char* p = fl_dir_chooser( "Select Scenery Source Directory",
source.c_str(),
0 );
if ( p != 0 ) {
source = p;
source_text->value( p );
prefs->set( "install-source", p );
prefs->flush();
}
}
// select the install source
void FGAdminUI::select_install_dest() {
char* p = fl_dir_chooser( "Select Scenery Install Directory",
dest.c_str(),
0 );
if ( p != 0 ) {
dest = p;
dest_text->value( p );
prefs->set( "scenery-dest", p );
prefs->flush();
}
}
// Like strcmp, but for strings
static int stringCompare(const void *string1, const void *string2)
{
const string *s1 = (const string *)string1;
const string *s2 = (const string *)string2;
// Compare name first, and then index.
return strcmp(s1->c_str(), s2->c_str());
}
void FGAdminUI::update_install_box() {
int i;
vector<string> file_list;
file_list.clear();
install_box->clear();
if ( source.length() ) {
ulDir *dir = ulOpenDir( source.c_str() ) ;
ulDirEnt *ent;
while ( 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;
if ( strcmp( p, ".gz" ) == 0 ) {
offset = p - base;
base[offset] = '\0';
p = fl_filename_ext( base );
if ( strcmp( p, ".tar" ) == 0 ) {
offset = p - base;
base[offset] = '\0';
}
} else if ( strcmp( p, ".zip" ) == 0 ) {
offset = p - base;
base[offset] = '\0';
}
// add to list if not installed
SGPath install( dest );
install.append( base );
if ( ! fl_filename_isdir( install.c_str() ) ) {
// cout << install.str() << " install candidate." << endl;
file_list.push_back( 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() );
}
delete [] sort_list;
}
}
// 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 ( strcmp(ent->d_name, ".") && strcmp(ent->d_name, "..") ) {
dir_list.push_back( ent->d_name );
}
}
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() );
}
// 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() );
}
delete [] sort_list;
}
}
// install selected files
void FGAdminUI::install_selected() {
char *f;
// traverse install box and install each item
for ( int i = 0; i <= install_box->nitems(); ++i ) {
2004-02-15 04:00:48 +00:00
if ( install_box->checked( i ) ) {
f = install_box->text( i );
SGPath file( source );
file.append( f );
cout << "installing " << file.str() << endl;
tarextract( (char *)file.c_str(), (char *)dest.c_str(), true, 0 );
2004-02-15 04:00:48 +00:00
}
}
refresh_lists();
}
static void remove_dir( const char *dir_name ) {
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() );
} else {
SGPath child( dir_name );
child.append( ent->d_name );
unlink( child.c_str() );
}
}
ulCloseDir( dir );
rmdir( dir_name );
}
// remove selected files
void FGAdminUI::remove_selected() {
char *f;
// traverse remove box and recursively remove each item
for ( int i = 0; i <= remove_box->nitems(); ++i ) {
2004-02-15 04:00:48 +00:00
if ( remove_box->checked( i ) ) {
f = remove_box->text( i );
SGPath dir( dest );
dir.append( f );
cout << "removing " << dir.str() << endl;
remove_dir( dir.c_str() );
}
}
refresh_lists();
}