00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "fileselector.h"
00023 #include "../dialog.h"
00024 #include "../iconrepository.h"
00025
00026 #include "../widgets/textrenderer.h"
00027 #include "../graphics/blitter.h"
00028 #include "../graphics/drawing.h"
00029 #include "../loaders.h"
00030
00031
00032
00033 class FileWidget: public SelectionWidget
00034 {
00035 FileInfo fileInfo;
00036 ASCString time;
00037 public:
00038 FileWidget( PG_Widget* parent, const PG_Point& pos, int width, const FileInfo* fi ) : SelectionWidget( parent, PG_Rect( pos.x, pos.y, width, 18 )), fileInfo( *fi ) {
00039 #ifndef ctime_r
00040 char* c = ctime( &fileInfo.modificationTime );
00041 if ( c )
00042 time = c;
00043 else
00044 time = "-";
00045 #else
00046
00047 char c[100];
00048 ctime_r( &fileInfo.modificationTime, c );
00049 time = c;
00050 #endif
00051 int col1 = width * 3 / 9;
00052 int col2 = col1 + width * 3 / 9;
00053
00054 PG_Label* lbl1 = new PG_Label( this, PG_Rect( 0, 0, col1 - 10, Height() ), fileInfo.name );
00055 lbl1->SetFontSize( lbl1->GetFontSize() -2 );
00056
00057 PG_Label* lbl2 = new PG_Label( this, PG_Rect( col1, 0, col2-col1-10, Height() ), time );
00058 lbl2->SetFontSize( lbl2->GetFontSize() -2 );
00059
00060 PG_Label* lbl3 = new PG_Label( this, PG_Rect( col2, 0, Width() - col2, Height() ), fileInfo.location );
00061 lbl3->SetFontSize( lbl3->GetFontSize() -2 );
00062
00063 SetTransparency( 255 );
00064 };
00065
00066 ASCString getName() const {
00067 return fileInfo.name;
00068 };
00069
00070 protected:
00071
00072 void display( SDL_Surface * surface, const PG_Rect & src, const PG_Rect & dst ) {
00073 }
00074 ;
00075 };
00076
00077 SavegameWidget::SavegameWidget( PG_Widget* parent, const PG_Point& pos, int width, const FileInfo* fi )
00078 : SelectionWidget( parent, PG_Rect( pos.x, pos.y, width, 110 )), fileInfo( *fi ), fileInformationLoaded(false)
00079 {
00080 #ifndef ctime_r
00081 char* c = ctime( &fileInfo.modificationTime );
00082 if ( c )
00083 time = c;
00084 else
00085 time = "-";
00086 #else
00087
00088 char c[100];
00089 ctime_r( &fileInfo.modificationTime, c );
00090 time = c;
00091 #endif
00092
00093
00094 int col2 = 120;
00095 int HeightRow = 20;
00096
00097 new Emboss( this, PG_Rect( 1, 1, Width()-5, Height()-2), true );
00098
00099 PG_Label* lbl1 = new PG_Label( this, PG_Rect( col2, 10, Width()-col2-10, HeightRow ), fileInfo.name );
00100 lbl1->SetFontSize( lbl1->GetFontSize()+2 );
00101
00102 mapTitleLabel = new PG_Label( this, PG_Rect( col2, 10+HeightRow, Width()-col2-10, HeightRow ), "" );
00103 mapTitleLabel->SetFontSize( mapTitleLabel->GetFontSize() -2 );
00104
00105
00106 PG_Label* lbl2 = new PG_Label( this, PG_Rect( col2, 10+HeightRow*2, Width()-col2-10, HeightRow ), time );
00107 lbl2->SetFontSize( lbl2->GetFontSize() -2 );
00108
00109 PG_Label* lbl3 = new PG_Label( this, PG_Rect( col2, 10+HeightRow*3, Width()-col2-10, HeightRow ), fileInfo.location );
00110 lbl3->SetFontSize( lbl3->GetFontSize() -2 );
00111
00112 if ( !alternateImage.valid() )
00113 alternateImage = IconRepository::getIcon("nomappicture.png");
00114
00115 SetTransparency( 255 );
00116 };
00117
00118 ASCString SavegameWidget::getName() const
00119 {
00120 return fileInfo.name;
00121 };
00122
00123
00124 Surface SavegameWidget::alternateImage;
00125
00126
00127 void SavegameWidget::display( SDL_Surface * surface, const PG_Rect & src, const PG_Rect & dst )
00128 {
00129 if ( !fileInformationLoaded ) {
00130 tsavegameloaders loader;
00131 gfi = loader.loadMapimageFromFile( fileInfo.name );
00132 fileInformationLoaded = true;
00133 ASCString s = gfi.maptitle + " - " + gfi.playername + " turn " + ASCString::toString( gfi.turn );
00134 mapTitleLabel->SetText( s );
00135 }
00136 if ( !gfi.image.valid()) {
00137 PG_Draw::BlitSurface( alternateImage.getBaseSurface(), src, surface, PG_Rect( dst.x+10, dst.y+5, dst.Width(), dst.Height() ));
00138 } else {
00139 PG_Draw::BlitSurface( gfi.image.getBaseSurface(), src, surface, PG_Rect( dst.x+10, dst.y+5, dst.Width(), dst.Height() ));
00140 }
00141 };
00142
00143
00144
00145 FileSelectionItemFactory::FileSelectionItemFactory( const ASCString& wildcard )
00146 {
00147 ASCString::size_type begin = 0;
00148 ASCString::size_type pos = wildcard.find( ";" );
00149 do {
00150 ASCString w = wildcard.substr( begin, pos );
00151 if ( pos != ASCString::npos && pos+1 < wildcard.length() ) {
00152 begin = pos + 1;
00153 pos = wildcard.find( ";", begin );
00154 } else
00155 begin = pos = ASCString::npos;
00156
00157 tfindfile ff ( w );
00158
00159 tfindfile::FileInfo fi;
00160 while ( ff.getnextname( fi) ) {
00161 FileInfo* fi2 = new FileInfo( fi.name, fi.location, fi.date, fi.directoryLevel );
00162 items.push_back ( fi2 );
00163 }
00164 } while ( begin != ASCString::npos );
00165
00166 sort( items.begin(), items.end(), comp );
00167 restart();
00168 };
00169
00170 bool FileSelectionItemFactory::comp ( const FileInfo* i1, const FileInfo* i2 )
00171 {
00172 return i1->modificationTime > i2->modificationTime || ( (i1->modificationTime == i2->modificationTime) && (i1->name < i2->name) );
00173
00174 };
00175
00176 void FileSelectionItemFactory::restart()
00177 {
00178 it = items.begin();
00179 };
00180
00181 int FileSelectionItemFactory::getLevel( const ASCString& name )
00182 {
00183 for ( Items::iterator it = items.begin(); it != items.end(); ++it )
00184 if ( (*it)->name == name )
00185 return (*it)->level;
00186 return -1;
00187 };
00188
00189
00190 SelectionWidget* FileSelectionItemFactory::spawnNextItem( PG_Widget* parent, const PG_Point& pos )
00191 {
00192 if ( it != items.end() )
00193 return new FileWidget( parent, pos, parent->Width() - 15, *(it++) );
00194 else
00195 return NULL;
00196 };
00197
00198
00199 void FileSelectionItemFactory::itemMarked( const SelectionWidget* widget )
00200 {
00201 if ( !widget )
00202 return;
00203
00204 const FileWidget* fw = dynamic_cast<const FileWidget*>(widget);
00205 assert( fw );
00206 filenameMarked( fw->getName() );
00207 }
00208
00209 void FileSelectionItemFactory::itemSelected( const SelectionWidget* widget, bool mouse )
00210 {
00211 if ( !widget )
00212 return;
00213
00214 const FileWidget* fw = dynamic_cast<const FileWidget*>(widget);
00215 assert( fw );
00216 if ( mouse )
00217 filenameSelectedMouse( fw->getName() );
00218 else
00219 filenameSelectedKeyb( fw->getName() );
00220 }
00221
00222
00223
00224 void FileSelectionWindow::fileNameSelected( const ASCString& filename )
00225 {
00226
00227 this->filename = filename;
00228 if ( this->filename.find('.') == ASCString::npos )
00229 this->filename += wildcard.substr( wildcard.find_first_not_of("*") );
00230
00231 if ( saveFile && factory ) {
00232 if ( factory->getLevel( this->filename ) == 0 )
00233 if ( !overwriteMessage || choice_dlg( "overwrite " + this->filename +" ?", "~y~es","~n~o") == 2) {
00234
00235 this->filename = "";
00236 return;
00237 }
00238 }
00239
00240 quitModalLoop(0);
00241 };
00242
00243 void FileSelectionWindow::fileNameEntered( ASCString filename )
00244 {
00245 if ( !patimat( wildcard, filename ))
00246 filename += wildcard.substr(1);
00247 fileNameSelected(filename);
00248 };
00249
00250 FileSelectionWindow::FileSelectionWindow( PG_Widget *parent, const PG_Rect &r, const ASCString& fileWildcard, bool save, bool overwriteMessage ) : ASC_PG_Dialog( parent, r, "" ), wildcard( fileWildcard), saveFile(save)
00251 {
00252 if ( save )
00253 SetTitle( "Enter Filename" );
00254 else
00255 SetTitle( "Choose File" );
00256
00257 this->overwriteMessage = overwriteMessage;
00258
00259 factory = new FileSelectionItemFactory( fileWildcard );
00260 factory->filenameSelectedMouse.connect ( SigC::slot( *this, &FileSelectionWindow::fileNameSelected ));
00261 factory->filenameSelectedKeyb.connect ( SigC::slot( *this, &FileSelectionWindow::fileNameSelected ));
00262
00263 ItemSelectorWidget* isw = new ItemSelectorWidget( this, PG_Rect(10, GetTitlebarHeight(), r.Width() - 20, r.Height() - GetTitlebarHeight()), factory );
00264 if ( save ) {
00265 isw->constrainNames( false );
00266 isw->nameEntered.connect( SigC::slot( *this, &FileSelectionWindow::fileNameEntered ));
00267 }
00268 isw->sigQuitModal.connect( SigC::slot( *this, &ItemSelectorWindow::QuitModal));
00269
00270 };
00271
00272
00273
00274 ASCString selectFile( const ASCString& ext, bool load, bool overwriteMessage )
00275 {
00276 FileSelectionWindow fsw( NULL, PG_Rect( 10, 10, 700, 500 ), ext, !load, overwriteMessage );
00277 fsw.Show();
00278 fsw.RunModal();
00279 return fsw.getFilename();
00280 }
00281
00282
00283 SavegameSelectionItemFactory::SavegameSelectionItemFactory( const ASCString& wildcard )
00284 {
00285 ASCString::size_type begin = 0;
00286 ASCString::size_type pos = wildcard.find( ";" );
00287 do {
00288 ASCString w = wildcard.substr( begin, pos );
00289 if ( pos != ASCString::npos && pos+1 < wildcard.length() ) {
00290 begin = pos + 1;
00291 pos = wildcard.find( ";", begin );
00292 } else
00293 begin = pos = ASCString::npos;
00294
00295 tfindfile ff ( w );
00296
00297 tfindfile::FileInfo fi;
00298 while ( ff.getnextname( fi) ) {
00299 FileInfo* fi2 = new FileInfo( fi.name, fi.location, fi.date, fi.directoryLevel );
00300 items.push_back ( fi2 );
00301 }
00302 } while ( begin != ASCString::npos );
00303
00304 sort( items.begin(), items.end(), comp );
00305 restart();
00306 };
00307
00308 bool SavegameSelectionItemFactory::comp ( const FileInfo* i1, const FileInfo* i2 )
00309 {
00310 return i1->modificationTime > i2->modificationTime || ( (i1->modificationTime == i2->modificationTime) && (i1->name < i2->name) );
00311
00312 };
00313
00314 void SavegameSelectionItemFactory::restart()
00315 {
00316 it = items.begin();
00317 };
00318
00319 int SavegameSelectionItemFactory::getLevel( const ASCString& name )
00320 {
00321 for ( Items::iterator it = items.begin(); it != items.end(); ++it )
00322 if ( (*it)->name == name )
00323 return (*it)->level;
00324 return -1;
00325 };
00326
00327
00328 SelectionWidget* SavegameSelectionItemFactory::spawnNextItem( PG_Widget* parent, const PG_Point& pos )
00329 {
00330 if ( it != items.end() )
00331 return new SavegameWidget( parent, pos, parent->Width() - 15, *(it++) );
00332 else
00333 return NULL;
00334 };
00335
00336
00337 void SavegameSelectionItemFactory::itemMarked( const SelectionWidget* widget )
00338 {
00339 if ( !widget )
00340 return;
00341
00342 const SavegameWidget* fw = dynamic_cast<const SavegameWidget*>(widget);
00343 assert( fw );
00344 filenameMarked( fw->getName() );
00345 }
00346
00347 void SavegameSelectionItemFactory::itemSelected( const SelectionWidget* widget, bool mouse )
00348 {
00349 if ( !widget )
00350 return;
00351
00352 const SavegameWidget* fw = dynamic_cast<const SavegameWidget*>(widget);
00353 assert( fw );
00354 if ( mouse )
00355 filenameSelectedMouse( fw->getName() );
00356 else
00357 filenameSelectedKeyb( fw->getName() );
00358 }
00359
00360
00361
00362
00363 void SavegameSelectionWindow::fileNameSelected( const ASCString& filename )
00364 {
00365
00366 this->filename = filename;
00367 if ( this->filename.find('.') == ASCString::npos )
00368 this->filename += wildcard.substr( wildcard.find_first_not_of("*") );
00369
00370 if ( saveFile && factory ) {
00371 if ( factory->getLevel( this->filename ) == 0 )
00372 if ( !overwriteMessage || choice_dlg( "overwrite " + this->filename +" ?", "~y~es","~n~o") == 2) {
00373
00374 this->filename = "";
00375 return;
00376 }
00377 }
00378
00379 quitModalLoop(0);
00380 };
00381
00382 void SavegameSelectionWindow::fileNameEntered( ASCString filename )
00383 {
00384 if ( !patimat( wildcard, filename ))
00385 filename += wildcard.substr(1);
00386 fileNameSelected(filename);
00387 };
00388
00389 SavegameSelectionWindow::SavegameSelectionWindow( PG_Widget *parent, const PG_Rect &r, const ASCString& fileWildcard, bool save, bool overwriteMessage ) : ASC_PG_Dialog( parent, r, "" ), wildcard( fileWildcard), saveFile(save)
00390 {
00391 if ( save )
00392 SetTitle( "Enter Filename" );
00393 else
00394 SetTitle( "Choose File" );
00395
00396 this->overwriteMessage = overwriteMessage;
00397
00398 factory = new SavegameSelectionItemFactory( fileWildcard );
00399 factory->filenameSelectedMouse.connect ( SigC::slot( *this, &SavegameSelectionWindow::fileNameSelected ));
00400 factory->filenameSelectedKeyb.connect ( SigC::slot( *this, &SavegameSelectionWindow::fileNameSelected ));
00401
00402 ItemSelectorWidget* isw = new ItemSelectorWidget( this, PG_Rect(10, GetTitlebarHeight(), r.Width() - 20, r.Height() - GetTitlebarHeight()), factory );
00403 if ( save ) {
00404 isw->constrainNames( false );
00405 isw->nameEntered.connect( SigC::slot( *this, &SavegameSelectionWindow::fileNameEntered ));
00406 }
00407 isw->sigQuitModal.connect( SigC::slot( *this, &ItemSelectorWindow::QuitModal));
00408
00409 };
00410
00411
00412 ASCString selectSavegame( const ASCString& ext, bool load, bool overwriteMessage )
00413 {
00414 SavegameSelectionWindow ssw( NULL, PG_Rect( -1, 10, 700, PG_Application::GetScreenHeight()-20), ext, !load, overwriteMessage );
00415 ssw.Show();
00416 ssw.RunModal();
00417 return ssw.getFilename();
00418 }