fileselector.cpp

Go to the documentation of this file.
00001 /*
00002      This file is part of Advanced Strategic Command; http://www.asc-hq.de
00003      Copyright (C) 1994-2010  Martin Bickel  and  Marc Schellenberger
00004 
00005      This program is free software; you can redistribute it and/or modify
00006      it under the terms of the GNU General Public License as published by
00007      the Free Software Foundation; either version 2 of the License, or
00008      (at your option) any later version.
00009 
00010      This program is distributed in the hope that it will be useful,
00011      but WITHOUT ANY WARRANTY; without even the implied warranty of
00012      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013      GNU General Public License for more details.
00014 
00015      You should have received a copy of the GNU General Public License
00016      along with this program; see the file COPYING. If not, write to the
00017      Free Software Foundation, Inc., 59 Temple Place, Suite 330,
00018      Boston, MA  02111-1307  USA
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    // return  i1->name < i2->name;
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    // if ( !patimat ( wildcard.c_str(), filename.c_str() ))
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             // isw->resetNamesearch();
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    // factory->filenameMarked.connect   ( SigC::slot( *this, &FileSelectionWindow::fileNameSelected ));
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    // return  i1->name < i2->name;
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    // if ( !patimat ( wildcard.c_str(), filename.c_str() ))
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             // isw->resetNamesearch();
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    // factory->filenameMarked.connect   ( SigC::slot( *this, &SavegameSelectionWindow::fileNameSelected ));
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 }

Generated on Mon May 21 01:26:33 2012 for Advanced Strategic Command by  doxygen 1.5.1