Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

filebrowser.cpp

Go to the documentation of this file.
00001 /**********************************************************************
00002 ** Copyright (C) 2000 Trolltech AS.  All rights reserved.
00003 **
00004 ** This file is part of Qtopia Environment.
00005 **
00006 ** This file may be distributed and/or modified under the terms of the
00007 ** GNU General Public License version 2 as published by the Free Software
00008 ** Foundation and appearing in the file LICENSE.GPL included in the
00009 ** packaging of this file.
00010 **
00011 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00012 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00013 **
00014 ** See http://www.trolltech.com/gpl/ for GPL licensing information.
00015 **
00016 ** Contact info@trolltech.com if any conditions of this licensing are
00017 ** not clear to you.
00018 **
00019 **********************************************************************/
00020 
00021 
00022 #include "inlineedit.h"
00023 #include "filebrowser.h"
00024 #include "filePermissions.h"
00025 #include <qpe/resource.h>
00026 #include <qpe/global.h>
00027 #include <qpe/mimetype.h>
00028 #include <qpe/applnk.h>
00029 #include <qpe/config.h>
00030 
00031 #include <qcopchannel_qws.h>
00032 #include <qpe/qcopenvelope_qws.h>
00033 
00034 #include <qmessagebox.h>
00035 #include <qdir.h>
00036 #include <qregexp.h>
00037 #include <qheader.h>
00038 #include <qtoolbar.h>
00039 #include <qpopupmenu.h>
00040 #include <qmenubar.h>
00041 #include <qaction.h>
00042 #include <qstringlist.h>
00043 #include <qcursor.h>
00044 #include <qmultilineedit.h>
00045 #include <qfont.h>
00046 #include <qpainter.h>
00047 #include <qprogressbar.h>
00048 
00049 #include <unistd.h>
00050 #include <stdlib.h>
00051 #include <sys/stat.h>
00052 #include <qpe/qpeapplication.h>
00053 
00054 //
00055 //  FileItem
00056 //
00057 FileItem::FileItem( QListView * parent, const QFileInfo & fi )
00058     : QListViewItem( parent ),
00059       fileInfo( fi )
00060 {
00061     QDate d = fi.lastModified().date();
00062 
00063     setText( 0, fi.fileName() );
00064     setText( 1, sizeString( fi.size() ) + " " );
00065     setText( 2, QString().sprintf("%4d-%02d-%02d",d.year(), d.month(), d.day() ) );
00066 
00067     MimeType mt(fi.filePath());
00068 
00069   if ( fi.isSymLink() )
00070     setText( 3, "symlink" );
00071     else if( fi.isDir() )
00072     setText( 3, "directory" );
00073     else if( isLib() )
00074   setText( 3, "library" );
00075     else
00076   setText( 3, mt.description() );
00077 
00078     QPixmap pm;
00079     if( fi.isDir() ){
00080   if( !QDir( fi.filePath() ).isReadable() )
00081       pm = Resource::loadPixmap( "lockedfolder" );
00082   else
00083       pm = Resource::loadPixmap( "folder" );
00084     }
00085     else if( !fi.isReadable() )
00086   pm = Resource::loadPixmap( "locked" );
00087     else if( isLib() )
00088   pm = Resource::loadPixmap( "library" );
00089     else if( ((FileView* )parent)->getShowThumbnails() && mt.id().contains(QRegExp("^image/", FALSE, FALSE)) )
00090       pm = drawThumbnail(fi);
00091   else
00092   pm = mt.pixmap();
00093     if ( pm.isNull() )
00094   pm = Resource::loadPixmap("UnknownDocument-14");
00095 
00096    if( fi.isSymLink() ){
00097     // overlay link image
00098     QPixmap lnk = Resource::loadPixmap( "filebrowser/symlink" );
00099     QPainter painter( &pm );
00100     painter.drawPixmap( pm.width()-lnk.width(), pm.height()-lnk.height(), lnk );
00101         pm.setMask( pm.createHeuristicMask( FALSE ) );
00102     }
00103     setPixmap(0,pm);
00104 }
00105 
00106 QString FileItem::sizeString( unsigned int s )
00107 {
00108     double size = s;
00109 
00110     if ( size > 1024 * 1024 * 1024 )
00111     return QString().sprintf( "%.1f", size / ( 1024 * 1024 * 1024 ) ) + "G";
00112     else if ( size > 1024 * 1024 )
00113     return QString().sprintf( "%.1f", size / ( 1024 * 1024 ) ) + "M";
00114     else if ( size > 1024 )
00115     return QString().sprintf( "%.1f", size / ( 1024 ) ) + "K";
00116     else
00117     return QString::number( size ) + "B";
00118 }
00119 
00120 QString FileItem::key( int column, bool ascending ) const
00121 {
00122     QString tmp;
00123 
00124     ascending = ascending;
00125 
00126     if( (column == 0) && fileInfo.isDir() ){ // Sort by name
00127     // We want the directories to appear at the top of the list
00128     tmp = (char) 0;
00129     return (tmp + text( column ).lower());
00130     }
00131     else if( column == 2 ) { // Sort by date
00132     QDateTime epoch( QDate( 1980, 1, 1 ) );
00133         tmp.sprintf( "%08d", epoch.secsTo( fileInfo.lastModified() ) );
00134     return tmp;
00135     }
00136     else if( column == 1 ) { // Sort by size
00137     return tmp.sprintf( "%08d", fileInfo.size() );
00138     }
00139 
00140     return text( column ).lower();
00141 }
00142 
00143 bool FileItem::isLib()
00144 {
00145     // This is of course not foolproof
00146     if( !qstrncmp("lib", fileInfo.baseName(), 3) &&
00147     ( fileInfo.extension().contains( "so" ) ||
00148       fileInfo.extension().contains( "a" ) ) )
00149     return TRUE;
00150     else
00151     return FALSE;
00152 }
00153 
00154 int FileItem::launch()
00155 {
00156     DocLnk doc( fileInfo.filePath(), FALSE );
00157     doc.execute();
00158     listView()->clearSelection();
00159     return 1;
00160 }
00161 
00162 bool FileItem::rename( const QString & name )
00163 {
00164     QString oldpath, newpath;
00165 
00166     if ( name.isEmpty() )
00167     return FALSE;
00168 
00169     if ( name.contains( QRegExp("[/\\$\"\'\\*\\?]") ) )
00170     return FALSE;
00171 
00172     oldpath = fileInfo.filePath();
00173     newpath = fileInfo.dirPath() + "/" + name;
00174 
00175     if ( ::rename( (const char *) oldpath, (const char *) newpath ) != 0 )
00176     return FALSE;
00177     else
00178     return TRUE;
00179 }
00180 
00181 QPixmap FileItem::drawThumbnail(const QFileInfo &file) {
00182 
00183   /*
00184    * this thing is sloooooow, and it also doesn't load 
00185    * dynamicly (like a web browser). if anyone knows how to 
00186    * do that, please do!
00187    */
00188   QString cacheDir = "/tmp/filebrowserThumbnailCache";
00189   QFileInfo cachedFile (cacheDir + file.filePath());
00190 
00191   if (cachedFile.exists() && cachedFile.lastModified() == file.lastModified()) {
00192 
00193     QPixmap cachedImage (cachedFile.filePath());
00194     return cachedImage;
00195   }
00196   else {
00197 
00198     QImage image (file.filePath());
00199 
00200     // if inside of cache dir, don't render thumbnails! recursive error!
00201     if (image.isNull() || file.filePath().contains(QRegExp("^" + cacheDir))) { 
00202       DocLnk doc (file.filePath());
00203       return doc.pixmap(); 
00204     }
00205     Config cfg("Filebrowser");
00206     cfg.setGroup("View");
00207     int size;
00208     size =cfg.readNumEntry("ThumbSize", 72);
00209     QPixmap thumb (size, size);
00210 
00211     double scale = (double)image.height() / (double)image.width();
00212     int newHeight = int(size * scale);
00213     thumb.convertFromImage (image.smoothScale(size, newHeight));
00214 
00215     if (!cachedFile.dir().exists()) {
00216       QString cmd = "/bin/mkdir -p \"" + cachedFile.dirPath() +"\"";
00217           system( (const char *) cmd );
00218     }
00219 
00220     if (thumb.save(cachedFile.filePath(), QPixmap::imageFormat(file.filePath()), 70)) {
00221       // make thumbnail modify time the same as the image
00222       QString cmd = "/bin/touch -r \"" + file.filePath() +"\" " +
00223           "\"" + cachedFile.filePath() + "\"";
00224           system( (const char *) cmd );
00225 
00226     }
00227 
00228     return thumb;
00229   }
00230 }
00231 
00232 //
00233 //  FileView
00234 //
00235 FileView::FileView( const QString & dir, QWidget * parent,
00236           const char * name, 
00237           bool hidden, bool symlinks, bool thumbnails )
00238     : QListView( parent, name ),
00239       menuTimer( this ),
00240       le( NULL ),
00241       itemToRename( NULL ),
00242       showHidden( hidden ),
00243       showSymlinks( symlinks ),
00244       showThumbnails( thumbnails ),
00245     menuKeepsOpen( FALSE )
00246 {
00247     addColumn( "Name" );
00248     addColumn( "Size" );
00249     addColumn( "Date" );
00250     addColumn( "Type" );
00251 
00252     setMultiSelection( TRUE );
00253     //header()->hide();
00254 
00255     setColumnWidthMode( 0, Manual );
00256     setColumnWidthMode( 3, Manual );
00257 
00258     // right align yize column
00259     setColumnAlignment( 1, AlignRight );
00260 
00261     generateDir( dir );
00262 
00263     connect( this, SIGNAL( clicked(QListViewItem*)),
00264        SLOT( itemClicked(QListViewItem*)) );
00265     connect( this, SIGNAL( doubleClicked(QListViewItem*)),
00266        SLOT( itemDblClicked(QListViewItem*)) );
00267     connect( this, SIGNAL( selectionChanged() ), SLOT( cancelMenuTimer() ) );
00268     connect( &menuTimer, SIGNAL( timeout() ), SLOT( showFileMenu() ) );
00269 }
00270 
00271 void FileView::resizeEvent( QResizeEvent *e )
00272 {
00273     setColumnWidth( 0, width() - 2 * lineWidth() - 20 - columnWidth( 1 ) - columnWidth( 2 ) );
00274 
00275     // hide type column, we use it for "sort by type" only
00276     //setColumnWidth( 3, 0 );
00277     QListView::resizeEvent( e );
00278 }
00279 
00280 void FileView::updateDir()
00281 {
00282     generateDir( currentDir );
00283 }
00284 
00285 void FileView::setDir( const QString & dir )
00286 {
00287     if ( dir.startsWith( "/dev" ) ) {
00288   QMessageBox::warning( this, tr( "File Manager" ),
00289             tr( "Can't show /dev/ directory." ), tr( "&Ok" ) );
00290   return;
00291     }
00292     dirHistory += currentDir;
00293     generateDir( dir );
00294 }
00295 
00296 void FileView::generateDir( const QString & dir )
00297 {
00298   if(menuKeepsOpen){    
00299     cancelMenuTimer();
00300     }
00301   QDir d( dir );
00302 
00303     if( d.exists() && !d.isReadable() ) return;
00304 
00305     currentDir = d.canonicalPath();
00306 
00307       if( !showHidden)
00308     d.setFilter( QDir::Dirs | QDir::Files );
00309       else
00310     d.setFilter( QDir::Dirs | QDir::Files |QDir::Hidden | QDir::All);
00311 
00312      d.setSorting( QDir::Name | QDir::DirsFirst | QDir::IgnoreCase |  QDir::Reversed );
00313         
00314     const QFileInfoList * list = d.entryInfoList();
00315     QFileInfoListIterator it( *list );
00316     QFileInfo *fi;
00317 
00318   QProgressBar *thumbProgress = 0;
00319   if (showThumbnails) {
00320 
00321     thumbProgress = new QProgressBar(it.count(), this);
00322     thumbProgress->show();
00323   }
00324 
00325     clear();
00326 
00327   int fileCount = 1; // used in the thumbnail progress meter
00328   while( (fi = it.current()) ){
00329     if( (fi->fileName() == ".") || (fi->fileName() == "..") ){
00330       ++it;
00331       continue;
00332     }
00333     if(!showSymlinks && fi->isSymLink()){
00334       ++it;
00335       continue;
00336     }
00337     // thumbnail progress
00338     if (showThumbnails) {
00339 
00340       thumbProgress->setProgress(fileCount);
00341     }
00342     (void) new FileItem( (QListView *) this, *fi );
00343 
00344     ++it;
00345     ++fileCount;
00346   }
00347 
00348   if (showThumbnails) { 
00349     thumbProgress->close();
00350   }
00351     emit dirChanged();
00352 
00353 }
00354 
00355 void FileView::rename()
00356 {
00357     itemToRename = (FileItem *) currentItem();
00358     const QPixmap * pm;
00359     int pmw;
00360 
00361     if( itemToRename == NULL ) return;
00362 
00363     if( ( pm = itemToRename->pixmap( 0 ) ) == NULL )
00364     pmw = 0;
00365     else
00366     pmw = pm->width();
00367 
00368     ensureItemVisible( itemToRename );
00369     horizontalScrollBar()->setValue( 0 );
00370     horizontalScrollBar()->setEnabled( FALSE );
00371     verticalScrollBar()->setEnabled( FALSE );
00372 
00373     selected = isSelected( itemToRename );
00374     setSelected( itemToRename, FALSE );
00375 
00376     if( le == NULL ){
00377     le = new InlineEdit( this );
00378     le->setFrame( FALSE );
00379     connect( le, SIGNAL( lostFocus() ), SLOT( endRenaming() ) );
00380     }
00381 
00382     QRect r = itemRect( itemToRename );
00383     r.setTop( r.top() + frameWidth() + 1 );
00384     r.setLeft( r.left() + frameWidth() + pmw );
00385     r.setBottom( r.bottom() + frameWidth() );
00386     r.setWidth( columnWidth( 0 ) - pmw );
00387 
00388     le->setGeometry( r );
00389     le->setText( itemToRename->text( 0 ) );
00390     le->selectAll();
00391     le->show();
00392     le->setFocus();
00393 }
00394 
00395 void FileView::endRenaming()
00396 {
00397     if( le && itemToRename ){
00398     le->hide();
00399     setSelected( itemToRename, selected );
00400 
00401     if( !itemToRename->rename( le->text() ) ){
00402       QMessageBox::warning( this, tr( "Rename file" ),
00403                   tr( "Rename failed!" ), tr( "&Ok" ) );
00404     } else {
00405       updateDir();
00406     }
00407     itemToRename = NULL;
00408     horizontalScrollBar()->setEnabled( TRUE );
00409     verticalScrollBar()->setEnabled( TRUE );
00410     }
00411 }
00412 
00413 void FileView::copy()
00414 {
00415     // dont keep cut files any longer than necessary
00416     // ##### a better inmplementation might be to rename the CUT file
00417     // ##### to ".QPE-FILEBROWSER-MOVING" rather than copying it.
00418     system ( "rm -rf /tmp/qpemoving" );
00419 
00420     FileItem * i;
00421 
00422     if((i = (FileItem *) firstChild()) == 0) return;
00423 
00424     flist.clear();
00425     while( i ){
00426     if( i->isSelected() /*&& !i->isDir()*/ ){
00427       flist += i->getFilePath();
00428     }
00429     i = (FileItem *) i->nextSibling();
00430     }
00431 }
00432 
00433 void FileView::paste()
00434 {
00435     int i, err;
00436     QString cmd, dest, basename, cd = currentDir;
00437 
00438     if(cd == "/") cd = "";
00439 
00440     for ( QStringList::Iterator it = flist.begin(); it != flist.end(); ++it ) {
00441     basename = (*it).mid((*it).findRev("/") + 1, (*it).length());
00442 
00443     dest = cd + "/" + basename;
00444     if( QFile( dest ).exists() ){
00445       i = 1;
00446       dest = cd + "/Copy of " + basename;
00447       while( QFile( dest ).exists() ){
00448         dest.sprintf( "%s/Copy (%d) of %s", (const char *) cd, i++,
00449                 (const char *) basename );
00450       }
00451     }
00452 
00453     //
00454     // Copy a directory recursively using the "cp" command -
00455     // may have to be changed
00456     //
00457     if( QFileInfo( (*it) ).isDir() ){
00458       cmd = "/bin/cp -fpR \"" + (*it) +"\" " + "\"" + dest + "\"";
00459       err = system( (const char *) cmd );
00460     } else if( !copyFile( dest, (*it) ) ){
00461       err = -1;
00462     } else {
00463       err = 0;
00464     }
00465 
00466     if ( err != 0 ) {
00467       QMessageBox::warning( this, tr("Paste file"), tr("Paste failed!"),
00468                   tr("Ok") );
00469       break;
00470     } else {
00471       updateDir();
00472       QListViewItem * i = firstChild();
00473       basename = dest.mid( dest.findRev("/") + 1, dest.length() );
00474 
00475       while( i ){
00476         if( i->text(0) == basename ){
00477           setCurrentItem( i );
00478           ensureItemVisible( i );
00479           break;
00480         }
00481         i = i->nextSibling();
00482       }
00483     }
00484     }
00485 }
00486 
00487 bool FileView::copyFile( const QString & dest, const QString & src )
00488 {
00489     char bf[ 50000 ];
00490     int  bytesRead;
00491     bool success = TRUE;
00492     struct stat status;
00493 
00494     QFile s( src );
00495     QFile d( dest );
00496 
00497     if( s.open( IO_ReadOnly | IO_Raw ) &&
00498     d.open( IO_WriteOnly | IO_Raw ) )
00499     {
00500     while( (bytesRead = s.readBlock( bf, sizeof( bf ) )) ==
00501          sizeof( bf ) )
00502     {
00503       if( d.writeBlock( bf, sizeof( bf ) ) != sizeof( bf ) ){
00504         success = FALSE;
00505         break;
00506       }
00507     }
00508     if( success && (bytesRead > 0) ){
00509       d.writeBlock( bf, bytesRead );
00510     }
00511     } else {
00512     success = FALSE;
00513     }
00514 
00515     // Set file permissions
00516     if( stat( (const char *) src, &status ) == 0 ){
00517     chmod( (const char *) dest, status.st_mode );
00518     }
00519 
00520     return success;
00521 }
00522 
00523 void FileView::cut()
00524 {
00525     int err;
00526     // ##### a better inmplementation might be to rename the CUT file
00527     // ##### to ".QPE-FILEBROWSER-MOVING" rather than copying it.
00528     QString cmd, dest, basename, cd = "/tmp/qpemoving";
00529   QStringList newflist;
00530   newflist.clear();
00531   
00532   cmd = "rm -rf " + cd;
00533   system ( (const char *) cmd );
00534   cmd = "mkdir " + cd;
00535   system( (const char *) cmd );
00536 
00537 // get the names of the files to cut
00538     FileItem * item;
00539  
00540     if((item = (FileItem *) firstChild()) == 0) return;
00541  
00542     flist.clear();
00543     while( item ){
00544         if( item->isSelected() /*&& !item->isDir()*/ ){
00545             flist += item->getFilePath();
00546         }
00547         item = (FileItem *) item->nextSibling();
00548     }
00549 
00550 // move these files into a tmp dir
00551     for ( QStringList::Iterator it = flist.begin(); it != flist.end(); ++it ) {
00552         basename = (*it).mid((*it).findRev("/") + 1, (*it).length());
00553  
00554         dest = cd + "/" + basename;
00555 
00556     newflist += dest;
00557  
00558         cmd = "/bin/mv -f \"" + (*it) +"\" " + "\"" + dest + "\"";
00559         err = system( (const char *) cmd );
00560  
00561         if ( err != 0 ) {
00562             QMessageBox::warning( this, tr("Cut file"), tr("Cut failed!"),
00563                                   tr("Ok") );
00564             break;
00565         } else {
00566             updateDir();
00567             QListViewItem * im = firstChild();
00568             basename = dest.mid( dest.findRev("/") + 1, dest.length() );
00569  
00570             while( im ){
00571                 if( im->text(0) == basename ){
00572                     setCurrentItem( im );
00573                     ensureItemVisible( im );
00574                     break;
00575                 }
00576                 im = im->nextSibling();
00577             }
00578         }
00579     }
00580 
00581   // update the filelist to point to tmp dir so paste works nicely
00582   flist = newflist;
00583 }
00584 
00585 void FileView::del()
00586 {
00587     FileItem * i;
00588     QStringList fl;
00589     QString cmd;
00590     int err;
00591 
00592     if((i = (FileItem *) firstChild()) == 0) return;
00593 
00594     while( i ){
00595     if( i->isSelected() ){
00596       fl += i->getFilePath();
00597     }
00598     i = (FileItem *) i->nextSibling();
00599     }
00600     if( fl.count() < 1 ) return;
00601 
00602     if( QMessageBox::warning( this, tr("Delete"), tr("Are you sure?"),
00603                 tr("Yes"), tr("No") ) == 0)
00604     {
00605     //
00606     // Dependant upon the "rm" command - will probably have to be replaced
00607     //
00608     for ( QStringList::Iterator it = fl.begin(); it != fl.end(); ++it ) {
00609       cmd = "/bin/rm -rf \"" + (*it) + "\"";
00610       err = system( (const char *) cmd );
00611       if ( err != 0 ) {
00612         QMessageBox::warning( this, tr("Delete"), tr("Delete failed!"),
00613                     tr("Ok") );
00614         break;
00615       }
00616     }
00617     updateDir();
00618     }
00619 }
00620 
00621 void FileView::newFolder()
00622 {
00623     int t = 1;
00624     FileItem * i;
00625     QString nd = currentDir + "/NewFolder";
00626 
00627     while( QFile( nd ).exists() ){
00628     nd.sprintf( "%s/NewFolder (%d)", (const char *) currentDir, t++ );
00629     }
00630 
00631     if( mkdir( (const char *) nd, 0777 ) != 0){
00632     QMessageBox::warning( this, tr( "New folder" ),
00633                 tr( "Folder creation failed!" ),
00634                 tr( "Ok" ) );
00635     return;
00636     }
00637     updateDir();
00638 
00639     if((i = (FileItem *) firstChild()) == 0) return;
00640 
00641     while( i ){
00642     if( i->isDir() && ( i->getFilePath() == nd ) ){
00643       setCurrentItem( i );
00644       rename();
00645       break;
00646     }
00647     i = (FileItem *) i->nextSibling();
00648     }
00649 }
00650 
00651 void FileView::viewAsText()
00652 {
00653     FileItem * i = (FileItem *) currentItem();
00654     QCopEnvelope e("QPE/Application/textedit","setDocument(QString)");
00655     e << i->getFilePath();
00656 //    Global::execute( "textedit -f ", i->getFilePath() );
00657 }
00658 
00659 void FileView::itemClicked( QListViewItem * i)
00660 {
00661     FileItem * t = (FileItem *) i;
00662 
00663     if( t == NULL ) return;
00664     if( t->isDir() ){
00665   setDir( t->getFilePath() );
00666     }
00667 }
00668 
00669 void FileView::itemDblClicked( QListViewItem * i)
00670 {
00671   if(menuKeepsOpen){    
00672     cancelMenuTimer();
00673   }
00674 
00675   FileItem * t = (FileItem *) i;
00676 
00677     if(t == NULL) return;
00678     if(t->launch() == -1){
00679     QMessageBox::warning( this, tr( "Launch Application" ),
00680                 tr( "Launch failed!" ), tr( "Ok" ) );
00681     }
00682 }
00683 
00684 void FileView::parentDir()
00685 {
00686     setDir( currentDir + "./.." );
00687 }
00688 
00689 void FileView::lastDir()
00690 {
00691     if( dirHistory.count() == 0 ) return;
00692 
00693     QString newDir = dirHistory.last();
00694     dirHistory.remove( dirHistory.last() );
00695     generateDir( newDir );
00696 }
00697 
00698 void FileView::contentsMousePressEvent( QMouseEvent * e )
00699 {
00700     QListView::contentsMousePressEvent( e );
00701     menuTimer.start( 750, TRUE );
00702 }
00703 
00704 void FileView::contentsMouseReleaseEvent( QMouseEvent * e )
00705 {
00706     QListView::contentsMouseReleaseEvent( e );
00707   if(!menuKeepsOpen){   
00708     menuTimer.stop();
00709   }
00710   
00711 }
00712 
00713 void FileView::cancelMenuTimer()
00714 {
00715     if( menuTimer.isActive() )
00716     menuTimer.stop();
00717 }
00718 
00719 void FileView::addToDocuments()
00720 {
00721     FileItem * i = (FileItem *) currentItem();
00722     DocLnk f;
00723     QString n = i->text(0);
00724     n.replace(QRegExp("\\..*"),"");
00725     f.setName( n );
00726     f.setFile( i->getFilePath() );
00727     f.writeLink();
00728 }
00729 
00730 void FileView::run()
00731 {
00732     FileItem * i = (FileItem *) currentItem();
00733     i->launch();
00734 }
00735 
00736 void FileView::showFileMenu()
00737 {
00738     FileItem * i = (FileItem *) currentItem();
00739     if ( !i )
00740     return;
00741 
00742     QPopupMenu * m = new QPopupMenu( this );
00743 
00744     if ( !i->isDir() ) {
00745     m->insertItem( tr( "Add to Documents" ), this, SLOT( addToDocuments() ) );
00746     m->insertSeparator();
00747     }
00748 
00749     MimeType mt(i->getFilePath());
00750     const AppLnk* app = mt.application();
00751 
00752     if ( !i->isDir() ) {
00753     if ( app )
00754       m->insertItem( app->pixmap(), tr( "Open in " + app->name() ), this, SLOT( run() ) );
00755     else if( i->isExecutable() )
00756       m->insertItem( Resource::loadPixmap( i->text( 0 ) ), tr( "Run" ), this, SLOT( run() ) );
00757 
00758     m->insertItem( Resource::loadPixmap( "txt" ), tr( "View as text" ),
00759              this, SLOT( viewAsText() ) );
00760 
00761     m->insertSeparator();
00762     }
00763 
00764     m->insertItem( tr( "Rename" ), this, SLOT( rename() ) );
00765     m->insertItem( Resource::loadPixmap("cut"),
00766             tr( "Cut" ), this, SLOT( cut() ) );
00767     m->insertItem( Resource::loadPixmap("copy"),
00768 
00769            tr( "Copy" ), this, SLOT( copy() ) );
00770     m->insertItem( Resource::loadPixmap("paste"),
00771            tr( "Paste" ), this, SLOT( paste() ) );
00772     m->insertItem( tr( "Change Permissions" ), this, SLOT( chPerm() ) );
00773     m->insertItem(Resource::loadPixmap( "close" ), tr( "Delete" ), this, SLOT( del() ) );
00774     m->insertSeparator();
00775     m->insertItem( tr( "Select all" ), this, SLOT( selectAll() ) );
00776     m->insertItem( tr( "Deselect all" ), this, SLOT( deselectAll() ) );
00777     m->popup( QCursor::pos() );
00778 }
00779 
00780 //
00781 //  FileBrowser
00782 //
00783 
00784 void FileView::setShowHidden(bool hidden)
00785 {
00786   showHidden=hidden;
00787 }
00788 
00789 void FileView::setShowSymlinks(bool symlinks)
00790 {
00791   showSymlinks=symlinks;
00792 }
00793 
00794 void FileView::setShowThumbnails(bool thumbnails)
00795 {
00796   showThumbnails=thumbnails;
00797 }
00798 
00799 void FileView::setMenuKeepsOpen(bool keepOpen)
00800 {
00801   menuKeepsOpen=keepOpen; 
00802 }
00803 
00804 FileBrowser::FileBrowser( QWidget * parent,
00805               const char * name, WFlags f ) :
00806     QMainWindow( parent, name, f )
00807 {
00808     init( QDir::current().canonicalPath() );
00809 }
00810 
00811 FileBrowser::FileBrowser( const QString & dir, QWidget * parent,
00812               const char * name, WFlags f ) :
00813     QMainWindow( parent, name, f )
00814 {
00815     init( dir );
00816 }
00817 
00818 void FileBrowser::init(const QString & dir)
00819 {
00820     setCaption( tr("File Manager") );
00821     setIcon( Resource::loadPixmap( "filebrowser_icon" ) );
00822     connect( qApp,SIGNAL( aboutToQuit()),SLOT( cleanUp()) );
00823 
00824 
00825   Config cfg("Filebrowser");
00826   cfg.setGroup("View");
00827   bool showHidden=(cfg.readEntry("Hidden","FALSE") == "TRUE");
00828   bool showSymlinks=(cfg.readEntry("Symlinks","FALSE") == "TRUE");
00829   bool showThumbnails=(cfg.readEntry("Thumbnails","FALSE") == "TRUE");
00830 
00831   cfg.setGroup("Menu"); 
00832   bool menuKeepsOpen=(cfg.readEntry("KeepOpen", "FALSE") == "TRUE");
00833   
00834 
00835     fileView = new FileView( dir, this, 0, showHidden, showSymlinks, showThumbnails );
00836     fileView->setAllColumnsShowFocus( TRUE );
00837   fileView->setMenuKeepsOpen(menuKeepsOpen);
00838   
00839     setCentralWidget( fileView );
00840     setToolBarsMovable( FALSE );
00841 
00842     QToolBar* toolBar = new QToolBar( this );
00843     toolBar->setHorizontalStretchable( TRUE );
00844 
00845     QMenuBar* menuBar = new QMenuBar( toolBar );
00846 
00847     dirMenu = new QPopupMenu( this );
00848     menuBar->insertItem( tr( "Dir" ), dirMenu );
00849 
00850     sortMenu = new QPopupMenu( this );
00851     menuBar->insertItem( tr( "Sort" ), sortMenu );
00852     sortMenu->insertItem( tr( "by Name "), this, SLOT( sortName() ) );
00853     sortMenu->insertItem( tr( "by Size "), this, SLOT( sortSize() ) );
00854     sortMenu->insertItem( tr( "by Date "), this, SLOT( sortDate() ) );
00855     sortMenu->insertItem( tr( "by Type "), this, SLOT( sortType() ) );
00856     sortMenu->insertSeparator();
00857     sortMenu->insertItem( tr( "Ascending" ), this, SLOT( updateSorting() ) );
00858 
00859     sortMenu->setItemChecked( sortMenu->idAt( 5 ), TRUE );
00860     sortMenu->setItemChecked( sortMenu->idAt( 0 ), TRUE );
00861 
00862     viewMenu = new QPopupMenu( this);  
00863   viewMenu->insertItem( tr( "Hidden"), this, SLOT( updateShowHidden() ) );
00864   viewMenu->insertItem( tr( "Symlinks"), this, SLOT( updateShowSymlinks() ) );
00865   viewMenu->insertItem( tr( "Thumbnails"), this, SLOT( updateShowThumbnails() ) );
00866     viewMenu->setItemChecked( viewMenu->idAt( 0 ), showHidden );
00867     viewMenu->setItemChecked( viewMenu->idAt( 1 ), showSymlinks );
00868     viewMenu->setItemChecked( viewMenu->idAt( 2 ), showThumbnails );
00869 
00870   menuBar->insertItem( tr("View"), viewMenu );
00871     
00872     toolBar = new QToolBar( this );
00873 
00874     lastAction = new QAction( tr("Previous dir"), Resource::loadIconSet( "back" ),
00875                 QString::null, 0, this, 0 );
00876     connect( lastAction, SIGNAL( activated() ), fileView, SLOT( lastDir() ) );
00877     lastAction->addTo( toolBar );
00878     lastAction->setEnabled( FALSE );
00879 
00880     upAction = new QAction( tr("Parent dir"), Resource::loadIconSet( "up" ),
00881            QString::null, 0, this, 0 );
00882     connect( upAction, SIGNAL( activated() ), fileView, SLOT( parentDir() ) );
00883     upAction->addTo( toolBar );
00884 
00885     QAction *a = new QAction( tr("New folder"), Resource::loadPixmap( "newfolder" ),
00886            QString::null, 0, this, 0 );
00887     connect( a, SIGNAL( activated() ), fileView, SLOT( newFolder() ) );
00888     a->addTo( toolBar );
00889 
00890     a = new QAction( tr("Cut"), Resource::loadPixmap( "cut" ),
00891            QString::null, 0, this, 0 );
00892     connect( a, SIGNAL( activated() ), fileView, SLOT( cut() ) );
00893     a->addTo( toolBar );
00894 
00895     a = new QAction( tr("Copy"), Resource::loadPixmap( "copy" ),
00896            QString::null, 0, this, 0 );
00897     connect( a, SIGNAL( activated() ), fileView, SLOT( copy() ) );
00898     a->addTo( toolBar );
00899 
00900     pasteAction = new QAction( tr("Paste"), Resource::loadPixmap( "paste" ),
00901                  QString::null, 0, this, 0 );
00902     connect( pasteAction, SIGNAL( activated() ), fileView, SLOT( paste() ) );
00903     pasteAction->addTo( toolBar );
00904 
00905 //    dirLabel = new QLabel(this, "DirLabel");
00906 
00907     connect( fileView, SIGNAL( dirChanged() ), SLOT( updateDirMenu() ) );
00908     updateDirMenu();
00909 
00910     QCopChannel* pcmciaChannel = new QCopChannel( "QPE/Card", this );
00911     connect( pcmciaChannel, SIGNAL(received(const QCString&,const QByteArray&)),
00912    this, SLOT(pcmciaMessage(const QCString&,const QByteArray&)) );
00913 }
00914 
00915 void FileBrowser::pcmciaMessage( const QCString &msg, const QByteArray &)
00916 {
00917     if ( msg == "mtabChanged()" ) {
00918   // ## Only really needed if current dir is on a card
00919         fileView->updateDir();
00920     }
00921 }
00922 
00923 void FileBrowser::changeCaption(const QString & dir) {
00924     setCaption( dir);
00925 }
00926 
00927 void FileBrowser::dirSelected( int id )
00928 {
00929     int i = 0, j;
00930     QString dir;
00931 
00932     // Bulid target dir from menu
00933     while( (j = dirMenu->idAt( i )) != id ){
00934     dir += dirMenu->text( j ).stripWhiteSpace();
00935     if( dirMenu->text( j ) != "/" ) dir += "/";
00936     i++;
00937     }
00938     dir += dirMenu->text( dirMenu->idAt( i ) ).stripWhiteSpace();
00939 
00940     fileView->setDir( dir );
00941 }
00942 
00943 void FileBrowser::updateDirMenu()
00944 {
00945     QString spc, cd = fileView->cd();
00946     QStringList l = QStringList::split( "/", cd );
00947     int i = 0;
00948 
00949     dirMenu->clear();
00950     dirMenu->insertItem( tr( "/" ), this, SLOT( dirSelected(int) ) );
00951 
00952     for ( QStringList::Iterator it = l.begin(); it != l.end(); ++it ) {
00953     spc.fill( ' ', i++);
00954     dirMenu->insertItem( spc + (*it), this,
00955                SLOT( dirSelected(int) ) );
00956     }
00957     dirMenu->setItemChecked( dirMenu->idAt( l.count() ), TRUE );
00958 
00959     lastAction->setEnabled( fileView->history().count() != 0 );
00960     upAction->setEnabled( cd != "/" );
00961 }
00962 
00963 void FileBrowser::sortName()
00964 {
00965     fileView->setSorting( 0, sortMenu->isItemChecked( sortMenu->idAt( 5 ) ) );
00966     fileView->sort();
00967     sortMenu->setItemChecked( sortMenu->idAt( 0 ), TRUE );
00968     sortMenu->setItemChecked( sortMenu->idAt( 1 ), FALSE );
00969     sortMenu->setItemChecked( sortMenu->idAt( 2 ), FALSE );
00970     sortMenu->setItemChecked( sortMenu->idAt( 3 ), FALSE );
00971 }
00972 
00973 void FileBrowser::sortSize()
00974 {
00975     fileView->setSorting( 1, sortMenu->isItemChecked( sortMenu->idAt( 5 ) ) );
00976     fileView->sort();
00977     sortMenu->setItemChecked( sortMenu->idAt( 0 ), FALSE );
00978     sortMenu->setItemChecked( sortMenu->idAt( 1 ), TRUE );
00979     sortMenu->setItemChecked( sortMenu->idAt( 2 ), FALSE );
00980     sortMenu->setItemChecked( sortMenu->idAt( 3 ), FALSE );
00981 }
00982 
00983 void FileBrowser::sortDate()
00984 {
00985     fileView->setSorting( 2, sortMenu->isItemChecked( sortMenu->idAt( 5 ) ) );
00986     fileView->sort();
00987     sortMenu->setItemChecked( sortMenu->idAt( 0 ), FALSE );
00988     sortMenu->setItemChecked( sortMenu->idAt( 1 ), FALSE );
00989     sortMenu->setItemChecked( sortMenu->idAt( 2 ), TRUE );
00990     sortMenu->setItemChecked( sortMenu->idAt( 3 ), FALSE );
00991 }
00992 
00993 void FileBrowser::sortType()
00994 {
00995     fileView->setSorting( 3, sortMenu->isItemChecked( sortMenu->idAt( 5 ) ) );
00996     fileView->sort();
00997     sortMenu->setItemChecked( sortMenu->idAt( 0 ), FALSE );
00998     sortMenu->setItemChecked( sortMenu->idAt( 1 ), FALSE );
00999     sortMenu->setItemChecked( sortMenu->idAt( 2 ), FALSE );
01000     sortMenu->setItemChecked( sortMenu->idAt( 3 ), TRUE );
01001 }
01002 
01003 void FileBrowser::updateSorting()
01004 {
01005     sortMenu->setItemChecked( sortMenu->idAt( 5 ), !sortMenu->isItemChecked( sortMenu->idAt( 5 ) ) );
01006 
01007     if ( sortMenu->isItemChecked( sortMenu->idAt( 0 ) ) )
01008     sortName();
01009     else if ( sortMenu->isItemChecked( sortMenu->idAt( 1 ) ) )
01010     sortSize();
01011     else if ( sortMenu->isItemChecked( sortMenu->idAt( 2 ) ) )
01012     sortDate();
01013     else
01014     sortType();
01015 }
01016 
01017 void FileView::chPerm() {
01018     FileItem * i;
01019     QStringList fl;
01020     QString cmd;
01021 
01022     if((i = (FileItem *) firstChild()) == 0) return;
01023 
01024     while( i ){
01025     if( i->isSelected() ){
01026       fl += i->getFilePath();
01027     }
01028     i = (FileItem *) i->nextSibling();
01029     }
01030     if( fl.count() < 1 ) return;
01031     if( QMessageBox::warning( this, tr("Change permissions"), tr("Are you sure?"),
01032                 tr("Yes"), tr("No") ) == 0) {
01033     for ( QStringList::Iterator it = fl.begin(); it != fl.end(); ++it ) {
01034         filePermissions *filePerm;
01035         filePerm = new filePermissions(this, "Permissions",true,0,(const QString &)(*it));
01036         filePerm->exec();
01037         if( filePerm)
01038             delete  filePerm;
01039         break;
01040       }
01041     updateDir();
01042     }
01043 }
01044 
01045 void FileBrowser::updateShowHidden()
01046 {
01047   bool valShowHidden=viewMenu->isItemChecked( viewMenu->idAt( 0 ) );
01048   valShowHidden=!valShowHidden;
01049     viewMenu->setItemChecked( viewMenu->idAt( 0 ), valShowHidden );
01050   fileView->setShowHidden(valShowHidden);
01051     
01052     Config cfg("Filebrowser");
01053     cfg.setGroup("View");
01054     cfg.writeEntry("Hidden",valShowHidden?"TRUE":"FALSE");
01055 
01056   fileView->updateDir();
01057 }
01058 
01059 void FileBrowser::updateShowSymlinks()
01060 {
01061   bool valShowSymlinks=viewMenu->isItemChecked( viewMenu->idAt( 1 ) );
01062   valShowSymlinks=!valShowSymlinks;
01063     viewMenu->setItemChecked( viewMenu->idAt( 1 ), valShowSymlinks );
01064   fileView->setShowSymlinks(valShowSymlinks);
01065 
01066     Config cfg("Filebrowser");
01067     cfg.setGroup("View");
01068     cfg.writeEntry("Symlinks",valShowSymlinks?"TRUE":"FALSE");
01069 
01070   fileView->updateDir();
01071 }
01072 
01073 void FileBrowser::updateShowThumbnails()
01074 {
01075   bool valShowThumbnails=viewMenu->isItemChecked( viewMenu->idAt( 2 ) );
01076   valShowThumbnails=!valShowThumbnails;
01077     viewMenu->setItemChecked( viewMenu->idAt( 2 ), valShowThumbnails );
01078   fileView->setShowThumbnails(valShowThumbnails);
01079 
01080     Config cfg("Filebrowser");
01081     cfg.setGroup("View");
01082     cfg.writeEntry("Thumbnails",valShowThumbnails?"TRUE":"FALSE");
01083 
01084   fileView->updateDir();
01085 }
01086 
01087 void FileBrowser::cleanUp() {
01088   QString cmdr = "rm -rf /tmp/filebrowserThumbnailCache";
01089 //  qDebug("exit");  
01090   system(cmdr.latin1());
01091 }

Generated on Sat Nov 5 16:18:03 2005 for OPIE by  doxygen 1.4.2