documentlist.cpp

来自「Trolltech公司发布的图形界面操作系统。可在qt-embedded-2.3」· C++ 代码 · 共 418 行

CPP
418
字号
/************************************************************************ Copyright (C) 2000-2002 Trolltech AS.  All rights reserved.**** This file is part of the Qtopia Environment.**** This file may be distributed and/or modified under the terms of the** GNU General Public License version 2 as published by the Free Software** Foundation and appearing in the file LICENSE.GPL included in the** packaging of this file.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.**** See http://www.trolltech.com/gpl/ for GPL licensing information.**** Contact info@trolltech.com if any conditions of this licensing are** not clear to you.************************************************************************/#include <qtopia/qpeapplication.h>#include <qtopia/applnk.h>#include <qtopia/resource.h>#include <qtopia/global.h>#include <qtopia/storage.h>#include <qpainter.h>#include <qimage.h>#include <qcopchannel_qws.h>#include <qfile.h>#include <qfileinfo.h>#include <qdir.h>#include <qlistview.h>#include <qlist.h>#include <qtimer.h>#include <qpixmap.h>#include "playlistselection.h"#include "documentlist.h"static const int MAX_SEARCH_DEPTH = 10;class AppDocumentListPrivate {public:    AppDocumentListPrivate();    ~AppDocumentListPrivate();    void initialize( const QString &mimefilter );    QString mimeFilter;    QFileInfo *nextFile();    const DocLnk *iterate();    bool store( DocLnk* dl );    DocLnkSet dls;    QDict<void> reference;    QDictIterator<void> *dit;    enum { Find, RemoveKnownFiles, MakeUnknownFiles, Done } state;    QValueList<QRegExp> mimeFilters;    QStringList docPaths;    unsigned int docPathsSearched;    int searchDepth;    QDir *listDirs[MAX_SEARCH_DEPTH];    const QFileInfoList *lists[MAX_SEARCH_DEPTH];    unsigned int listPositions[MAX_SEARCH_DEPTH];    QCopChannel *systemChannel;    StorageInfo *storage;    int tid;};AppDocumentListPrivate::AppDocumentListPrivate() {}void AppDocumentListPrivate::initialize( const QString &mimefilter ) {    mimeFilter = mimefilter;    // Reset    dls.clear();    docPaths.clear();    reference.clear();    mimeFilters.clear();    // Break up filter in to regexps    QStringList subFilter = QStringList::split(";", mimefilter);    for( QStringList::Iterator it = subFilter.begin(); it != subFilter.end(); ++ it )	mimeFilters.append( QRegExp(*it, FALSE, TRUE) );    QDir docDir( QPEApplication::documentDir() );    if ( docDir.exists() )	docPaths += QPEApplication::documentDir();    int i = 1;    const QList<FileSystem> &fs = storage->fileSystems();    QListIterator<FileSystem> it( fs );    for ( ; it.current(); ++it ) 	if ( (*it)->isRemovable() ) {	    docPaths += (*it)->path();	    i++;	}    docPathsSearched = 0;    searchDepth = -1;    state = Find;    dit = 0;}AppDocumentListPrivate::~AppDocumentListPrivate(){    delete dit;}QFileInfo *AppDocumentListPrivate::nextFile( ){    while ( TRUE ) {	while ( searchDepth < 0 ) {	    // go to next base path	    if ( docPathsSearched >= docPaths.count() ) {		// end of base paths		return NULL;	    } else {		QDir dir( docPaths[docPathsSearched] );//qDebug("now using base path: %s", docPaths[docPathsSearched].latin1() );		docPathsSearched++;		if ( !dir.exists( ".Qtopia-ignore" ) ) {		    listDirs[0] = new QDir( dir );		    lists[0] = listDirs[0]->entryInfoList();		    listPositions[0] = 0;		    searchDepth = 0;		}	    }	}	const QFileInfoList *fil = lists[searchDepth];	QFileInfoList *fl = (QFileInfoList *)fil;	unsigned int pos = listPositions[searchDepth];	if ( pos >= fl->count() ) {	    // go up a depth	    delete listDirs[searchDepth];	    lists[searchDepth] = NULL;	    listPositions[searchDepth] = 0;	    searchDepth--;	} else {	    const QFileInfo *fi = fl->at(pos);	    listPositions[searchDepth]++;	    QString bn = fi->fileName();	    if ( bn[0] != '.' ) {		if ( fi->isDir()  ) {		    if ( bn != "CVS" && bn != "Qtopia" && bn != "QtPalmtop" ) { 			// go down a depth			QDir dir( fi->filePath() );//qDebug("now going in to path: %s", bn.latin1() );			if ( !dir.exists( ".Qtopia-ignore" ) ) {			    if ( searchDepth < MAX_SEARCH_DEPTH - 1 ) {				searchDepth++;				listDirs[searchDepth] = new QDir( dir );				lists[searchDepth] = listDirs[searchDepth]->entryInfoList();				listPositions[searchDepth] = 0;			    }			}		    }		} else {		    return fl->at(pos);		}	    }	}    }    return NULL;}bool AppDocumentListPrivate::store( DocLnk* dl ){    bool mtch = FALSE;    if ( mimeFilters.count() == 0 ) {	mtch = TRUE;    } else {	for ( QValueList<QRegExp>::ConstIterator it = mimeFilters.begin();	    !mtch && it != mimeFilters.end(); ++ it )	{	    if ( (*it).match(dl->type()) >= 0 )		mtch = TRUE;	}    }    if ( mtch ) {	dls.add( dl ); // store	return TRUE;    }    // don't store - delete    delete dl;    return FALSE;}const DocLnk *AppDocumentListPrivate::iterate(){    if ( state == Find ) {	//qDebug("state Find");	QFileInfo *fi;	while ( (fi = nextFile()) ) {	    if ( fi->extension(FALSE) == "desktop" ) { // No tr		DocLnk* dl = new DocLnk( fi->filePath() );		if ( store(dl) )		    return dl;	    } else {		if ( !reference.find( fi->filePath() ) ) {		    reference.insert( fi->filePath(), (void*)2 );		}	    }	}	state = RemoveKnownFiles;    }    if ( state == RemoveKnownFiles ) {	//qDebug("state RemoveKnownFiles");	const QList<DocLnk> &list = dls.children();	for ( QListIterator<DocLnk> it( list ); it.current(); ++it ) {	    reference.remove( (*it)->file() );	    // ### check if this needs a delete	}	dit = new QDictIterator<void>(reference);	state = MakeUnknownFiles;    }    if ( state == MakeUnknownFiles ) {	//qDebug("state MakeUnknownFiles");	for (void* c; (c=dit->current()); ++(*dit) ) {	    if ( c == (void*)2 ) {		DocLnk* dl = new DocLnk;		QFileInfo fi( dit->currentKey() );		dl->setFile( fi.filePath() );		dl->setName( fi.baseName() );		if ( store(dl) ) {		    ++*dit;		    return dl;		}	    }	}	delete dit;	dit = 0;	state = Done;    }    //qDebug("state Done");    return NULL;}AppDocumentList::AppDocumentList( const QString &mimefilter, QObject *parent, const char *name ) : QObject( parent, name ){    d = new AppDocumentListPrivate();    d->storage = new StorageInfo( this );    d->initialize( mimefilter );    d->tid = 0;    connect( d->storage, SIGNAL( disksChanged() ), SLOT( storageChanged() ) );    d->systemChannel = new QCopChannel( "QPE/System", this );    connect( d->systemChannel, SIGNAL(received(const QCString &, const QByteArray &)),	 this, SLOT(systemMessage( const QCString &, const QByteArray &)) );}void AppDocumentList::add( const DocLnk& doc ) {    if ( QFile::exists( doc.file() ) )	emit added( doc );}void AppDocumentList::start() {    resume();}void AppDocumentList::pause() {    killTimer( d->tid );    d->tid = 0;}void AppDocumentList::resume() {    if ( d->tid == 0 )	d->tid = startTimer( 1 );}void AppDocumentList::resend(){    // Re-emits all the added items to the list (firstly letting everyone know to    // clear what they have as it is being sent again)    pause();    emit allRemoved();    QTimer::singleShot( 5, this, SLOT( resendWorker() ) );}void AppDocumentList::resendWorker(){    const QList<DocLnk> &list = d->dls.children();    for ( QListIterator<DocLnk> it( list ); it.current(); ++it ) 	add( *(*it) );    resume();}void AppDocumentList::rescan(){    pause();    emit allRemoved();    d->initialize( d->mimeFilter );    resume();}AppDocumentList::~AppDocumentList( ){    delete d->systemChannel;    delete d;}void AppDocumentList::systemMessage( const QCString &msg, const QByteArray &data ){    if ( msg == "linkChanged(QString)" ) {	QDataStream stream( data, IO_ReadOnly );        QString arg;        stream >> arg;	qDebug( "linkchanged( %s )", arg.latin1() );	pause();	const QList<DocLnk> &list = d->dls.children();	QListIterator<DocLnk> it( list );	while ( it.current() ) {	    DocLnk *doc = it.current();	    ++it;	    if ( ( doc->linkFileKnown() && doc->linkFile() == arg )		|| ( doc->fileKnown() && doc->file() == arg ) ) {		qDebug( "found old link" );		DocLnk* dl = new DocLnk( arg );		// add new one if it exists and matches the mimetype		if ( d->store( dl ) ) {		    // Existing link has been changed, send old link ref and a ref		    // to the new link		    qDebug( "change case" );		    emit changed( *doc, *dl );		} else {		    // Link has been removed or doesn't match the mimetypes any more		    // so we aren't interested in it, so take it away from the list		    qDebug( "removal case" );		    emit removed( *doc );		}		d->dls.remove( doc ); // remove old link from docLnkSet		delete doc;		resume();		return;	    }	}	// Didn't find existing link, must be new	DocLnk* dl = new DocLnk( arg );	if ( d->store( dl ) ) {	    // Add if it's a link we are interested in	    qDebug( "add case" );	    add( *dl );	}	resume();    }}void AppDocumentList::storageChanged(){    // ### Optimization opportunity    // Could be a bit more intelligent and somehow work out which    // mtab entry has changed and then only scan that and add and remove    // links appropriately.    rescan();}void AppDocumentList::timerEvent( QTimerEvent *te ){    if ( te->timerId() == d->tid ) {	// Do 10 at a time	for (int i = 0; i < 10; i++ ) {	    const DocLnk *lnk = d->iterate();	    if ( lnk ) {		add( *lnk );	    } else {		// stop when done		pause();		emit doneForNow();		break;	    }	}    }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?