]> git.mxchange.org Git - flightgear.git/blob - utils/fgadmin/src/fgadmin_funcs.cxx
Initial revision.
[flightgear.git] / utils / fgadmin / src / fgadmin_funcs.cxx
1 // fgadmin_funcs.cxx -- FG Admin UI functions.
2 //
3 // Written by Curtis Olson, started February 2004.
4 //
5 // Copyright (c) 2004  Curtis L. Olson - curt@flightgear.org
6 //
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License as
9 // published by the Free Software Foundation; either version 2 of the
10 // License, or (at your option) any later version.
11 //
12 // This program is distributed in the hope that it will be useful, but
13 // WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 // General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 //
21 // $Id$
22
23
24 #include <iostream>
25 #include <string>
26 #include <vector>
27
28 #include <FL/Fl_File_Chooser.H>
29 #include <plib/ul.h>
30
31 #include <simgear/misc/sg_path.hxx>
32
33 #include "fgadmin.h"
34 #include "tar_utils.hxx"
35
36 using std::cout;
37 using std::endl;
38 using std::vector;
39 using std::string;
40
41
42 // destructor
43 FGAdminUI::~FGAdminUI() {
44     delete prefs;
45 }
46
47
48 // initialize additional class elements
49 void FGAdminUI::init() {
50     prefs = new Fl_Preferences( Fl_Preferences::USER,
51                                 "flightgear.org",
52                                 "fgadmin" );
53     char buf[FL_PATH_MAX];
54     prefs->get( "install-source", buf, "", FL_PATH_MAX );
55     source_text->value( buf );
56     source = buf;
57
58     prefs->get( "scenery-dest", buf, "", FL_PATH_MAX );
59     dest_text->value( buf );
60     dest = buf;
61
62     refresh_lists();
63 }
64
65 // show our UI
66 void FGAdminUI::show() {
67     main_window->show();
68 }
69
70
71 // refresh the check box lists
72 void FGAdminUI::refresh_lists() {
73     update_install_box();
74     update_remove_box();
75 }
76
77
78 // scan the source directory and update the install_box contents
79 // quit
80 void FGAdminUI::quit() {
81     main_window->hide();
82 }
83
84
85 // select the install source
86 void FGAdminUI::select_install_source() {
87     char* p = fl_dir_chooser( "Select Scenery Source Directory",
88                               source.c_str(),
89                               0 );
90     if ( p != 0 ) {
91         source = p;
92         source_text->value( p );
93         prefs->set( "install-source", p );
94         prefs->flush();
95     }
96 }
97
98
99 // select the install source
100 void FGAdminUI::select_install_dest() {
101     char* p = fl_dir_chooser( "Select Scenery Install Directory",
102                               dest.c_str(),
103                               0 );
104     if ( p != 0 ) {
105         dest = p;
106         dest_text->value( p );
107         prefs->set( "scenery-dest", p );
108         prefs->flush();
109     }
110 }
111
112
113 // Like strcmp, but for strings
114 static int stringCompare(const void *string1, const void *string2)
115 {
116     const string *s1 = (const string *)string1;
117     const string *s2 = (const string *)string2;
118
119     // Compare name first, and then index.
120     return strcmp(s1->c_str(), s2->c_str());
121 }
122
123
124 void FGAdminUI::update_install_box() {
125     int i;
126     vector<string> file_list;
127     file_list.clear();
128
129     install_box->clear();
130
131     if ( source.length() ) {
132         ulDir *dir = ulOpenDir( source.c_str() ) ;
133         ulDirEnt *ent;
134         while ( ent = ulReadDir( dir ) ) {
135             // find base name of archive file
136             char base[FL_PATH_MAX];
137             strncpy( base, ent->d_name, FL_PATH_MAX );
138             const char *p = fl_filename_ext( base );
139             int offset;
140             if ( strcmp( p, ".gz" ) == 0 ) {
141                 offset = p - base;
142                 base[offset] = '\0';
143                 p = fl_filename_ext( base );
144                 if ( strcmp( p, ".tar" ) == 0 ) {
145                     offset = p - base;
146                     base[offset] = '\0';
147                 }
148             } else if ( strcmp( p, ".zip" ) == 0 ) {
149                 offset = p - base;
150                 base[offset] = '\0';
151             }
152
153             // add to list if not installed
154             SGPath install( dest );
155             install.append( base );
156             if ( ! fl_filename_isdir( install.c_str() ) ) {
157                 // cout << install.str() << " install candidate." << endl;
158                 file_list.push_back( ent->d_name );
159             } else {
160                 // cout << install.str() << " exists." << endl;
161             }
162         }
163         ulCloseDir( dir );
164
165         // convert to a qsort()'able array
166         string *sort_list = new string[file_list.size()];
167         for ( i = 0; i < file_list.size(); ++i ) {
168             sort_list[i] = fl_filename_name( file_list[i].c_str() );
169         }
170
171         // Sort the file list into display order
172         qsort(sort_list, file_list.size(), sizeof(string), stringCompare);
173
174         for ( int i = 0; i < file_list.size(); ++i ) {
175             install_box->add( sort_list[i].c_str() );
176         }
177
178         delete [] sort_list;
179     }
180 }
181
182
183 // scan the source directory and update the install_box contents
184 void FGAdminUI::update_remove_box() {
185     int i;
186     vector<string> dir_list;
187     dir_list.clear();
188
189     remove_box->clear();
190
191     if ( dest.length() ) {
192         ulDir *dir = ulOpenDir( dest.c_str() ) ;
193         ulDirEnt *ent;
194         while ( ent = ulReadDir( dir ) ) {
195             if ( strcmp(ent->d_name, ".") && strcmp(ent->d_name, "..") ) {
196                 dir_list.push_back( ent->d_name );
197             }
198         }
199         ulCloseDir( dir );
200
201         // convert to a qsort()'able array
202         string *sort_list = new string[dir_list.size()];
203         for ( i = 0; i < dir_list.size(); ++i ) {
204             sort_list[i] = fl_filename_name( dir_list[i].c_str() );
205         }
206
207         // Sort the file list into display order
208         qsort(sort_list, dir_list.size(), sizeof(string), stringCompare);
209
210         for ( int i = 0; i < dir_list.size(); ++i ) {
211             remove_box->add( sort_list[i].c_str() );
212         }
213
214         delete [] sort_list;
215     }
216 }
217
218
219 // install selected files
220 void FGAdminUI::install_selected() {
221     char *f;
222
223     // traverse install box and install each item
224     for ( int i = 0; i < install_box->nitems(); ++i ) {
225         if ( install_box->checked( i ) ) {
226             f = install_box->text( i );
227             SGPath file( source );
228             file.append( f );
229             cout << "installing " << file.str() << endl;
230             tarextract( (char *)file.c_str(), (char *)dest.c_str(), true );
231         }
232     }
233
234     refresh_lists();
235 }
236
237
238 static void remove_dir( const char *dir_name ) {
239     ulDir *dir = ulOpenDir( dir_name ) ;
240     ulDirEnt *ent;
241     while ( ent = ulReadDir( dir ) ) {
242         if ( strcmp( ent->d_name, "." ) == 0 ) {
243             // ignore "."
244         } else if ( strcmp( ent->d_name, ".." ) == 0 ) {
245             // ignore ".."
246         } else if ( ent->d_isdir ) {
247             SGPath child( dir_name );
248             child.append( ent->d_name );
249             remove_dir( child.c_str() );
250         } else {
251             SGPath child( dir_name );
252             child.append( ent->d_name );
253             unlink( child.c_str() );
254         }
255     }
256     ulCloseDir( dir );
257     rmdir( dir_name );
258 }
259
260
261 // remove selected files
262 void FGAdminUI::remove_selected() {
263     char *f;
264
265     // traverse remove box and recursively remove each item
266     for ( int i = 0; i < remove_box->nitems(); ++i ) {
267         if ( remove_box->checked( i ) ) {
268             f = remove_box->text( i );
269             SGPath dir( dest );
270             dir.append( f );
271             cout << "removing " << dir.str() << endl;
272             remove_dir( dir.c_str() );
273         }
274     }
275
276     refresh_lists();
277    
278 }