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