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
00025 class FileInfo
00026 {
00027 public:
00028 ASCString name;
00029 ASCString location;
00030 time_t modificationTime;
00031 int level;
00032 FileInfo( const ASCString& filename, const ASCString& filelocation, time_t time, int directorylevel ) : name( filename), location( filelocation ), modificationTime( time ), level( directorylevel )
00033 {}
00034 FileInfo( const FileInfo& fi ) : name( fi.name ), location( fi.location ), modificationTime( fi.modificationTime ), level ( fi.level )
00035 {}
00036 }
00037 ;
00038
00039
00040
00041 class FileWidget: public SelectionWidget
00042 {
00043 FileInfo fileInfo;
00044 ASCString time;
00045 public:
00046 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 )
00047 {
00048 #ifndef ctime_r
00049 char* c = ctime( &fileInfo.modificationTime );
00050 if ( c )
00051 time = c;
00052 else
00053 time = "-";
00054 #else
00055
00056 char c[100];
00057 ctime_r( &fileInfo.modificationTime, c );
00058 time = c;
00059 #endif
00060
00061 int col1 = width * 3 / 9;
00062 int col2 = col1 + width * 3 / 9;
00063
00064 PG_Label* lbl1 = new PG_Label( this, PG_Rect( 0, 0, col1 - 10, Height() ), fileInfo.name );
00065 lbl1->SetFontSize( lbl1->GetFontSize() -2 );
00066
00067 PG_Label* lbl2 = new PG_Label( this, PG_Rect( col1, 0, col2-col1-10, Height() ), time );
00068 lbl2->SetFontSize( lbl2->GetFontSize() -2 );
00069
00070 PG_Label* lbl3 = new PG_Label( this, PG_Rect( col2, 0, Width() - col2, Height() ), fileInfo.location );
00071 lbl3->SetFontSize( lbl3->GetFontSize() -2 );
00072
00073 SetTransparency( 255 );
00074 };
00075
00076 ASCString getName() const
00077 {
00078 return fileInfo.name;
00079 };
00080
00081 protected:
00082
00083 void display( SDL_Surface * surface, const PG_Rect & src, const PG_Rect & dst )
00084 {
00085 }
00086 ;
00087 };
00088
00089
00090
00091 FileSelectionItemFactory::FileSelectionItemFactory( const ASCString& wildcard )
00092 {
00093 ASCString::size_type begin = 0;
00094 ASCString::size_type pos = wildcard.find( ";" );
00095 do {
00096 ASCString w = wildcard.substr( begin, pos );
00097 if ( pos != ASCString::npos && pos+1 < wildcard.length() ) {
00098 begin = pos + 1;
00099 pos = wildcard.find( ";", begin );
00100 } else
00101 begin = pos = ASCString::npos;
00102
00103 tfindfile ff ( w );
00104
00105 tfindfile::FileInfo fi;
00106 while ( ff.getnextname( fi) ) {
00107 FileInfo* fi2 = new FileInfo( fi.name, fi.location, fi.date, fi.directoryLevel );
00108 items.push_back ( fi2 );
00109 }
00110 } while ( begin != ASCString::npos );
00111
00112 sort( items.begin(), items.end(), comp );
00113 restart();
00114 };
00115
00116 bool FileSelectionItemFactory::comp ( const FileInfo* i1, const FileInfo* i2 )
00117 {
00118 return i1->modificationTime > i2->modificationTime || ( (i1->modificationTime == i2->modificationTime) && (i1->name < i2->name) );
00119
00120 };
00121
00122 void FileSelectionItemFactory::restart()
00123 {
00124 it = items.begin();
00125 };
00126
00127 int FileSelectionItemFactory::getLevel( const ASCString& name )
00128 {
00129 for ( Items::iterator it = items.begin(); it != items.end(); ++it )
00130 if ( (*it)->name == name )
00131 return (*it)->level;
00132 return -1;
00133 };
00134
00135
00136 SelectionWidget* FileSelectionItemFactory::spawnNextItem( PG_Widget* parent, const PG_Point& pos )
00137 {
00138 if ( it != items.end() )
00139 return new FileWidget( parent, pos, parent->Width() - 15, *(it++) );
00140 else
00141 return NULL;
00142 };
00143
00144
00145 void FileSelectionItemFactory::itemMarked( const SelectionWidget* widget )
00146 {
00147 if ( !widget )
00148 return;
00149
00150 const FileWidget* fw = dynamic_cast<const FileWidget*>(widget);
00151 assert( fw );
00152 filenameMarked( fw->getName() );
00153 }
00154
00155 void FileSelectionItemFactory::itemSelected( const SelectionWidget* widget, bool mouse )
00156 {
00157 if ( !widget )
00158 return;
00159
00160 const FileWidget* fw = dynamic_cast<const FileWidget*>(widget);
00161 assert( fw );
00162 if ( mouse )
00163 filenameSelectedMouse( fw->getName() );
00164 else
00165 filenameSelectedKeyb( fw->getName() );
00166 }
00167
00168
00169
00170 void FileSelectionWindow::fileNameSelected( const ASCString& filename )
00171 {
00172
00173 this->filename = filename;
00174 if ( this->filename.find('.') == ASCString::npos )
00175 this->filename += wildcard.substr( wildcard.find_first_not_of("*") );
00176
00177 if ( saveFile && factory ) {
00178 if ( factory->getLevel( this->filename ) == 0 )
00179 if ( !overwriteMessage || choice_dlg( "overwrite " + this->filename +" ?", "~y~es","~n~o") == 2) {
00180
00181 this->filename = "";
00182 return;
00183 }
00184 }
00185
00186 quitModalLoop(0);
00187 };
00188
00189 void FileSelectionWindow::fileNameEntered( ASCString filename )
00190 {
00191 if ( !patimat( wildcard, filename ))
00192 filename += wildcard.substr(1);
00193 fileNameSelected(filename);
00194 };
00195
00196 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)
00197 {
00198 if ( save )
00199 SetTitle( "Enter Filename" );
00200 else
00201 SetTitle( "Choose File" );
00202
00203 this->overwriteMessage = overwriteMessage;
00204
00205 factory = new FileSelectionItemFactory( fileWildcard );
00206 factory->filenameSelectedMouse.connect ( SigC::slot( *this, &FileSelectionWindow::fileNameSelected ));
00207 factory->filenameSelectedKeyb.connect ( SigC::slot( *this, &FileSelectionWindow::fileNameSelected ));
00208
00209 ItemSelectorWidget* isw = new ItemSelectorWidget( this, PG_Rect(10, GetTitlebarHeight(), r.Width() - 20, r.Height() - GetTitlebarHeight()), factory );
00210 if ( save ) {
00211 isw->constrainNames( false );
00212 isw->nameEntered.connect( SigC::slot( *this, &FileSelectionWindow::fileNameEntered ));
00213 }
00214 isw->sigQuitModal.connect( SigC::slot( *this, &ItemSelectorWindow::QuitModal));
00215
00216 };
00217
00218
00219
00220 ASCString selectFile( const ASCString& ext, bool load, bool overwriteMessage )
00221 {
00222 FileSelectionWindow fsw( NULL, PG_Rect( 10, 10, 700, 500 ), ext, !load, overwriteMessage );
00223 fsw.Show();
00224 fsw.RunModal();
00225 return fsw.getFilename();
00226 }
00227