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

fileselector.cpp

Go to the documentation of this file.
00001 /**********************************************************************
00002 ** Copyright (C) 2000-2002 Trolltech AS.  All rights reserved.
00003 **
00004 ** This file is part of the 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 // WARNING: Do *NOT* define this yourself. The SL5xxx from SHARP does NOT
00022 //      have this class.
00023 #define QTOPIA_INTERNAL_FSLP
00024 
00025 #include "fileselector.h"
00026 #include "fileselector_p.h"
00027 #include "global.h"
00028 #include "resource.h"
00029 #include "config.h"
00030 #include "storage.h"
00031 #include "qpemenubar.h"
00032 #include <qcopchannel_qws.h>
00033 #include "lnkproperties.h"
00034 #include <qpe/qpeapplication.h>
00035 #include "categorymenu.h"
00036 #include "categoryselect.h"
00037 #include "mimetype.h"
00038 #include <qpe/categories.h>
00039 
00040 #include <stdlib.h>
00041 
00042 #include <qdir.h>
00043 #include <qwidget.h>
00044 #include <qpopupmenu.h>
00045 #include <qtoolbutton.h>
00046 #include <qpushbutton.h>
00047 #include <qheader.h>
00048 #include <qtooltip.h>
00049 #include <qwhatsthis.h>
00050 
00051 class TypeCombo : public QComboBox
00052 {
00053     Q_OBJECT
00054 public:
00055     TypeCombo( QWidget *parent, const char *name=0 )
00056         : QComboBox( parent, name )
00057     {
00058         connect( this, SIGNAL(activated(int)), this, SLOT(selectType(int)) );
00059     }
00060 
00061     void reread( DocLnkSet &files, const QString &filter );
00062 
00063 signals:
00064     void selected( const QString & );
00065 
00066 protected slots:
00067     void selectType( int idx ) {
00068         emit selected( typelist[idx] );
00069     }
00070 
00071 protected:
00072     QStringList typelist;
00073     QString prev;
00074 };
00075 
00076 void TypeCombo::reread( DocLnkSet &files, const QString &filter )
00077 {
00078     typelist.clear();
00079     QStringList filters = QStringList::split( ';', filter );
00080     int pos = filter.find( '/' );
00081     //### do for each filter
00082     if ( filters.count() == 1 && pos >= 0 && filter[pos+1] != '*' ) {
00083         typelist.append( filter );
00084         clear();
00085         QString minor = filter.mid( pos+1 );
00086         minor[0] = minor[0].upper();
00087         insertItem( tr("%1 files").arg(minor) );
00088         setCurrentItem(0);
00089         setEnabled( FALSE );
00090         return;
00091     }
00092 
00093     QListIterator<DocLnk> dit( files.children() );
00094     for ( ; dit.current(); ++dit ) {
00095         if ( !typelist.contains( (*dit)->type() ) )
00096             typelist.append(  (*dit)->type() );
00097     }
00098 
00099     QStringList types;
00100     QStringList::ConstIterator it;
00101     for (it = typelist.begin(); it!=typelist.end(); ++it) {
00102         QString t = *it;
00103         if ( t.left(12) == "application/" ) {
00104             MimeType mt(t);
00105             const AppLnk* app = mt.application();
00106             if ( app )
00107                 t = app->name();
00108             else
00109                 t = t.mid(12);
00110         } else {
00111             QString major, minor;
00112             int pos = t.find( '/' );
00113             if ( pos >= 0 ) {
00114                 major = t.left( pos );
00115                 minor = t.mid( pos+1 );
00116             }
00117             if ( minor.find( "x-" ) == 0 )
00118                 minor = minor.mid( 2 );
00119             minor[0] = minor[0].upper();
00120             major[0] = major[0].upper();
00121             if ( filters.count() > 1 )
00122                 t = tr("%1 %2", "minor mimetype / major mimetype").arg(minor).arg(major);
00123             else
00124                 t = minor;
00125         }
00126         types += tr("%1 files").arg(t);
00127     }
00128     for (it = filters.begin(); it!=filters.end(); ++it) {
00129         typelist.append( *it );
00130         int pos = (*it).find( '/' );
00131         if ( pos >= 0 ) {
00132             QString maj = (*it).left( pos );
00133             maj[0] = maj[0].upper();
00134             types << tr("All %1 files").arg(maj);
00135         }
00136     }
00137     if ( filters.count() > 1 ) {
00138         typelist.append( filter );
00139         types << tr("All files");
00140     }
00141     prev = currentText();
00142     clear();
00143     insertStringList(types);
00144     for (int i=0; i<count(); i++) {
00145         if ( text(i) == prev ) {
00146             setCurrentItem(i);
00147             break;
00148         }
00149     }
00150     if ( prev.isNull() )
00151         setCurrentItem(count()-1);
00152     setEnabled( TRUE );
00153 }
00154 
00155 
00156 //===========================================================================
00157 
00158 FileSelectorItem::FileSelectorItem( QListView *parent, const DocLnk &f )
00159     : QListViewItem( parent ), fl( f )
00160 {
00161     setText( 0, f.name() );
00162     setPixmap( 0, f.pixmap() );
00163 }
00164 
00165 FileSelectorItem::~FileSelectorItem()
00166 {
00167 }
00168 
00169 FileSelectorView::FileSelectorView( QWidget *parent, const char *name )
00170     : QListView( parent, name )
00171 {
00172     setAllColumnsShowFocus( TRUE );
00173     addColumn( tr( "Name" ) );
00174     header()->hide();
00175 }
00176 
00177 FileSelectorView::~FileSelectorView()
00178 {
00179 }
00180 
00181 void FileSelectorView::keyPressEvent( QKeyEvent *e )
00182 {
00183     QString txt = e->text();
00184     if (e->key() == Key_Space)
00185         emit returnPressed( currentItem() );
00186     else if ( !txt.isNull() && txt[0] > ' ' && e->key() < 0x1000 )
00187         e->ignore();
00188     else
00189         QListView::keyPressEvent(e);
00190 }
00191 
00192 class NewDocItem : public FileSelectorItem
00193 {
00194 public:
00195     NewDocItem( QListView *parent, const DocLnk &f )
00196         : FileSelectorItem( parent, f ) {
00197         setText( 0, QObject::tr("New Document") );
00198         QImage img( Resource::loadImage( "new" ) );
00199         QPixmap pm;
00200         pm = img.smoothScale( AppLnk::smallIconSize(), AppLnk::smallIconSize() );
00201         setPixmap( 0, pm );
00202     }
00203     QString key ( int, bool ) const {
00204         return QString("\n");
00205     }
00206 
00207     void paintCell( QPainter *p, const QColorGroup &cg, int column, int width, int alignment ) {
00208         QFont oldFont = p->font();
00209         QFont newFont = p->font();
00210         newFont.setWeight( QFont::Bold );
00211         p->setFont( newFont );
00212         FileSelectorItem::paintCell( p, cg, column, width, alignment );
00213         p->setFont( oldFont );
00214     }
00215 
00216     int width( const QFontMetrics &fm, const QListView *v, int c ) const {
00217         return FileSelectorItem::width( fm, v, c )*4/3; // allow for bold font
00218     }
00219 };
00220 
00221 //===========================================================================
00222 
00223 class FileSelectorPrivate
00224 {
00225 public:
00226     TypeCombo *typeCombo;
00227     CategorySelect *catSelect;
00228     QValueList<QRegExp> mimeFilters;
00229     int catId;
00230     bool showNew;
00231     NewDocItem *newDocItem;
00232     DocLnkSet files;
00233     QHBox *toolbar;
00234 };
00235 
00281 FileSelector::FileSelector( const QString &f, QWidget *parent, const char *name, bool newVisible, bool closeVisible )
00282     : QVBox( parent, name ), filter( f )
00283 {
00284     setMargin( 0 );
00285     setSpacing( 0 );
00286 
00287     d = new FileSelectorPrivate();
00288     d->newDocItem = 0;
00289     d->showNew = newVisible;
00290     d->catId = -2; // All files
00291 
00292     d->toolbar = new QHBox( this );
00293     d->toolbar->setBackgroundMode( PaletteButton );   // same colour as toolbars
00294     d->toolbar->setSpacing( 0 );
00295     d->toolbar->hide();
00296 
00297     QWidget *spacer = new QWidget( d->toolbar );
00298     spacer->setBackgroundMode( PaletteButton );
00299 
00300     QToolButton *tb = new QToolButton( d->toolbar );
00301     tb->setPixmap( Resource::loadPixmap( "close" ) );
00302     connect( tb, SIGNAL( clicked() ), this, SIGNAL( closeMe() ) );
00303     buttonClose = tb;
00304     tb->setFixedSize( 18, 20 ); // tb->sizeHint() );
00305     tb->setAutoRaise( TRUE );
00306     QToolTip::add( tb, tr( "Close the File Selector" ) );
00307     QPEMenuToolFocusManager::manager()->addWidget( tb );
00308 
00309     view = new FileSelectorView( this, "fileview" );
00310     QPEApplication::setStylusOperation( view->viewport(), QPEApplication::RightOnHold );
00311     connect( view, SIGNAL( mouseButtonClicked(int,QListViewItem*,const QPoint&,int) ),
00312              this, SLOT( fileClicked(int,QListViewItem*,const QPoint&,int) ) );
00313     connect( view, SIGNAL( mouseButtonPressed(int,QListViewItem*,const QPoint&,int) ),
00314              this, SLOT( filePressed(int,QListViewItem*,const QPoint&,int) ) );
00315     connect( view, SIGNAL( returnPressed(QListViewItem*) ),
00316              this, SLOT( fileClicked(QListViewItem*) ) );
00317 
00318     QHBox *hb = new QHBox( this );
00319 
00320     d->typeCombo = new TypeCombo( hb );
00321     connect( d->typeCombo, SIGNAL(selected(const QString&)),
00322             this, SLOT(typeSelected(const QString&)) );
00323     QWhatsThis::add( d->typeCombo, tr("Show documents of this type") );
00324 
00325     Categories c;
00326     c.load(categoryFileName());
00327     QArray<int> vl( 0 );
00328     d->catSelect = new CategorySelect( hb );
00329     d->catSelect->setRemoveCategoryEdit( TRUE );
00330     d->catSelect->setCategories( vl, "Document View", tr("Document View") );
00331     d->catSelect->setAllCategories( TRUE );
00332     connect( d->catSelect, SIGNAL(signalSelected(int)), this, SLOT(catSelected(int)) );
00333     QWhatsThis::add( d->catSelect, tr("Show documents in this category") );
00334 
00335     setCloseVisible( closeVisible );
00336 
00337     QCopChannel *channel = new QCopChannel( "QPE/Card", this );
00338     connect( channel, SIGNAL(received(const QCString&,const QByteArray&)),
00339             this, SLOT(cardMessage(const QCString&,const QByteArray&)) );
00340 
00341     reread();
00342     updateWhatsThis();
00343 }
00344 
00348 FileSelector::~FileSelector()
00349 {
00350     delete d;
00351 }
00352 
00358 int FileSelector::fileCount()
00359 {
00360     return d->files.children().count();;
00361 }
00362 
00369 void FileSelector::createNew()
00370 {
00371     DocLnk f;
00372     emit newSelected( f );
00373     emit closeMe();
00374 }
00375 
00376 void FileSelector::fileClicked( int button, QListViewItem *i, const QPoint &, int )
00377 {
00378     if ( !i )
00379         return;
00380     if ( button == Qt::LeftButton ) {
00381         fileClicked( i );
00382     }
00383 }
00384 
00385 void FileSelector::filePressed( int button, QListViewItem *i, const QPoint &, int )
00386 {
00387     if ( !i || i == d->newDocItem )
00388         return;
00389     if ( button == Qt::RightButton ) {
00390         DocLnk l = ((FileSelectorItem *)i)->file();
00391         LnkProperties prop( &l );
00392         prop.showMaximized();
00393         prop.exec();
00394         reread();
00395     }
00396 }
00397 
00398 void FileSelector::fileClicked( QListViewItem *i )
00399 {
00400     if ( !i )
00401         return;
00402     if ( i == d->newDocItem ) {
00403         createNew();
00404     } else {
00405         emit fileSelected( ( (FileSelectorItem*)i )->file() );
00406         emit closeMe();
00407     }
00408 }
00409 
00410 void FileSelector::typeSelected( const QString &type )
00411 {
00412     d->mimeFilters.clear();
00413     QStringList subFilter = QStringList::split(";", type);
00414     for( QStringList::Iterator it = subFilter.begin(); it != subFilter.end(); ++it )
00415         d->mimeFilters.append( QRegExp(*it, FALSE, TRUE) );
00416     updateView();
00417 }
00418 
00419 void FileSelector::catSelected( int c )
00420 {
00421     d->catId = c;
00422     updateView();
00423 }
00424 
00425 void FileSelector::cardMessage( const QCString &msg, const QByteArray &)
00426 {
00427     if ( msg == "mtabChanged()" )
00428         reread();
00429 }
00430 
00431 
00436 const DocLnk *FileSelector::selected()
00437 {
00438     FileSelectorItem *item = (FileSelectorItem *)view->selectedItem();
00439     if ( item && item != d->newDocItem )
00440         return new DocLnk( item->file() );
00441     return NULL;
00442 }
00443 
00471 void FileSelector::setNewVisible( bool b )
00472 {
00473     if ( d->showNew != b ) {
00474         d->showNew = b;
00475         updateView();
00476         updateWhatsThis();
00477     }
00478 }
00479 
00487 void FileSelector::setCloseVisible( bool b )
00488 {
00489     if (  b )
00490         d->toolbar->show();
00491     else
00492         d->toolbar->hide();
00493 }
00494 
00498 void FileSelector::setTypeComboVisible( bool b ) {
00499     if ( b )
00500         d->typeCombo->show();
00501     else
00502         d->typeCombo->hide();
00503 }
00507 void FileSelector::setCategorySelectVisible( bool b ) {
00508     if ( b )
00509         d->catSelect->show();
00510     else
00511         d->catSelect->hide();
00512 }
00513 
00517 void FileSelector::reread()
00518 {
00519     d->files.clear();
00520     Global::findDocuments(&d->files, filter);
00521     d->typeCombo->reread( d->files, filter );
00522     updateView();
00523 }
00524 
00525 void FileSelector::updateView()
00526 {
00527     FileSelectorItem *item = (FileSelectorItem *)view->selectedItem();
00528     if ( item == d->newDocItem )
00529         item = 0;
00530     QString oldFile;
00531     if ( item )
00532         oldFile = item->file().file();
00533     view->clear();
00534     QListIterator<DocLnk> dit( d->files.children() );
00535     for ( ; dit.current(); ++dit ) {
00536         bool mimeMatch = FALSE;
00537         if ( d->mimeFilters.count() ) {
00538             QValueList<QRegExp>::Iterator it;
00539             for ( it = d->mimeFilters.begin(); it != d->mimeFilters.end(); ++it ) {
00540                 if ( (*it).match((*dit)->type()) >= 0 ) {
00541                     mimeMatch = TRUE;
00542                     break;
00543                 }
00544             }
00545         } else {
00546             mimeMatch = TRUE;
00547         }
00548         if ( mimeMatch &&
00549                 (d->catId == -2 || (*dit)->categories().contains(d->catId) ||
00550                  (d->catId == -1 && (*dit)->categories().isEmpty())) ) {
00551             item = new FileSelectorItem( view, **dit );
00552             if ( item->file().file() == oldFile )
00553                 view->setCurrentItem( item );
00554         }
00555     }
00556 
00557     if ( d->showNew )
00558         d->newDocItem = new NewDocItem( view, DocLnk() );
00559     else
00560         d->newDocItem = 0;
00561 
00562     if ( !view->selectedItem() || view->childCount() == 1 ) {
00563         view->setCurrentItem( view->firstChild() );
00564         view->setSelected( view->firstChild(), TRUE );
00565     }
00566 }
00567 
00568 void FileSelector::updateWhatsThis()
00569 {
00570     QWhatsThis::remove( this );
00571     QString text = tr("Click to select a document from the list");
00572     if ( d->showNew )
00573         text += tr(", or select <b>New Document</b> to create a new document.");
00574     text += tr("<br><br>Click and hold for document properties.");
00575     QWhatsThis::add( this, text );
00576 }
00577 
00578 #include "fileselector.moc"
00579 

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