-rw-r--r-- | core/launcher/documentlist.cpp | 8 | ||||
-rw-r--r-- | core/launcher/launcher.cpp | 10 | ||||
-rw-r--r-- | core/launcher/launcher.h | 2 | ||||
-rw-r--r-- | core/launcher/serverinterface.h | 2 |
4 files changed, 20 insertions, 2 deletions
diff --git a/core/launcher/documentlist.cpp b/core/launcher/documentlist.cpp index 59dd721..19ceb0f 100644 --- a/core/launcher/documentlist.cpp +++ b/core/launcher/documentlist.cpp @@ -1,788 +1,792 @@ /********************************************************************** ** 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 "documentlist.h" #include "serverinterface.h" #include "mediadlg.h" /* OPIE */ #include <opie2/oglobal.h> #include <opie2/odebug.h> #include <qtopia/config.h> #include <qtopia/mimetype.h> #include <qtopia/resource.h> #include <qtopia/private/categories.h> #include <qtopia/qpeapplication.h> #include <qtopia/applnk.h> #include <qtopia/storage.h> #ifdef Q_WS_QWS #include <qtopia/qcopenvelope_qws.h> #endif using namespace Opie::Core; /* QT */ #include <qtimer.h> #include <qfileinfo.h> #include <qtextstream.h> #include <qfile.h> #include <qdir.h> #include <qpainter.h> #include <qimage.h> #include <qcopchannel_qws.h> #include <qlistview.h> #include <qlist.h> #include <qpixmap.h> AppLnkSet *DocumentList::appLnkSet = 0; static const int MAX_SEARCH_DEPTH = 10; class DocumentListPrivate : public QObject { Q_OBJECT public: DocumentListPrivate( ServerInterface *gui ); ~DocumentListPrivate(); void initialize(); const QString nextFile(); const DocLnk *iterate(); bool store( DocLnk* dl ); void estimatedPercentScanned(); void appendDocpath(FileSystem*); - + DocLnkSet dls; QDict<void> reference; QDictIterator<void> *dit; enum { Find, RemoveKnownFiles, MakeUnknownFiles, Done } state; QStringList docPaths; unsigned int docPathsSearched; int searchDepth; QDir *listDirs[MAX_SEARCH_DEPTH]; const QFileInfoList *lists[MAX_SEARCH_DEPTH]; unsigned int listPositions[MAX_SEARCH_DEPTH]; StorageInfo *storage; int tid; ServerInterface *serverGui; bool needToSendAllDocLinks; bool sendAppLnks; bool sendDocLnks; bool scanDocs; }; /* * scandocs will be read from Config */ DocumentList::DocumentList( ServerInterface *serverGui, bool /*scanDocs*/, QObject *parent, const char *name ) : QObject( parent, name ) { appLnkSet = new AppLnkSet( MimeType::appsFolderName() ); d = new DocumentListPrivate( serverGui ); d->needToSendAllDocLinks = false; Config cfg( "Launcher" ); cfg.setGroup( "DocTab" ); d->scanDocs = cfg.readBoolEntry( "Enable", true ); odebug << "DocumentList::DocumentList() : scanDocs = " << d->scanDocs << "" << oendl; QTimer::singleShot( 10, this, SLOT( startInitialScan() ) ); } void DocumentList::startInitialScan() { reloadAppLnks(); reloadDocLnks(); } DocumentList::~DocumentList() { delete appLnkSet; delete d; } void DocumentList::add( const DocLnk& doc ) { if ( d->serverGui && QFile::exists( doc.file() ) ) d->serverGui->documentAdded( doc ); } void DocumentList::start() { resume(); } void DocumentList::pause() { //odebug << "pause " << d->tid << "" << oendl; killTimer( d->tid ); d->tid = 0; } void DocumentList::resume() { if ( d->tid == 0 ) { d->tid = startTimer( 20 ); //odebug << "resumed " << d->tid << "" << oendl; } } /* void DocumentList::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 DocumentList::resendWorker() { const QList<DocLnk> &list = d->dls.children(); for ( QListIterator<DocLnk> it( list ); it.current(); ++it ) add( *(*it) ); resume(); } */ void DocumentList::rescan() { //odebug << "rescan" << oendl; pause(); d->initialize(); resume(); } void DocumentList::timerEvent( QTimerEvent *te ) { if ( te->timerId() == d->tid ) { // Do 3 at a time + if ( d->serverGui ) + d->serverGui->aboutToAddBegin(); for (int i = 0; i < 3; i++ ) { const DocLnk *lnk = d->iterate(); if ( lnk ) { add( *lnk ); } else { // stop when done pause(); if ( d->serverGui ) d->serverGui->documentScanningProgress( 100 ); if ( d->needToSendAllDocLinks ) sendAllDocLinks(); break; } - } + } + if ( d->serverGui ) + d->serverGui->aboutToAddEnd(); } } void DocumentList::reloadAppLnks() { if ( d->sendAppLnks && d->serverGui ) { d->serverGui->applicationScanningProgress( 0 ); d->serverGui->allApplicationsRemoved(); } delete appLnkSet; appLnkSet = new AppLnkSet( MimeType::appsFolderName() ); if ( d->sendAppLnks && d->serverGui ) { static QStringList prevTypeList; QStringList types = appLnkSet->types(); for ( QStringList::Iterator ittypes=types.begin(); ittypes!=types.end(); ++ittypes) { if ( !(*ittypes).isEmpty() ) { if ( !prevTypeList.contains(*ittypes) ) { QString name = appLnkSet->typeName(*ittypes); QPixmap pm = appLnkSet->typePixmap(*ittypes); QPixmap bgPm = appLnkSet->typeBigPixmap(*ittypes); if (pm.isNull()) { QImage img( Resource::loadImage( "UnknownDocument" ) ); pm = img.smoothScale( AppLnk::smallIconSize(), AppLnk::smallIconSize() ); bgPm = img.smoothScale( AppLnk::bigIconSize(), AppLnk::bigIconSize() ); } //odebug << "adding type " << (*ittypes) << "" << oendl; // ### our current launcher expects docs tab to be last d->serverGui->typeAdded( *ittypes, name.isNull() ? (*ittypes) : name, pm, bgPm ); } prevTypeList.remove(*ittypes); } } for ( QStringList::Iterator ittypes=prevTypeList.begin(); ittypes!=prevTypeList.end(); ++ittypes) { //odebug << "removing type " << (*ittypes) << "" << oendl; d->serverGui->typeRemoved(*ittypes); } prevTypeList = types; } QListIterator<AppLnk> itapp( appLnkSet->children() ); AppLnk* l; while ( (l=itapp.current()) ) { ++itapp; if ( d->sendAppLnks && d->serverGui ) d->serverGui->applicationAdded( l->type(), *l ); } if ( d->sendAppLnks && d->serverGui ) d->serverGui->applicationScanningProgress( 100 ); } void DocumentList::reloadDocLnks() { if ( !d->scanDocs ) return; if ( d->sendDocLnks && d->serverGui ) { d->serverGui->documentScanningProgress( 0 ); d->serverGui->allDocumentsRemoved(); } rescan(); } void DocumentList::linkChanged( QString arg ) { //odebug << "linkchanged( " << arg << " )" << oendl; if ( arg.isNull() || OGlobal::isAppLnkFileName( arg ) ) { reloadAppLnks(); } else { 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 ) ) { //odebug << "found old link" << oendl; 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 //odebug << "change case" << oendl; if ( d->serverGui ) d->serverGui->documentChanged( *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 //odebug << "removal case" << oendl; if ( d->serverGui ) d->serverGui->documentRemoved( *doc ); } d->dls.remove( doc ); // remove old link from docLnkSet delete doc; 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 //odebug << "add case" << oendl; add( *dl ); } } } void DocumentList::restoreDone() { reloadAppLnks(); reloadDocLnks(); } void DocumentList::DiffAppLnks() { static AppLnkSet *appLnkSet2; appLnkSet2 = new AppLnkSet( MimeType::appsFolderName() ); if ( d->sendAppLnks && d->serverGui ) { static QStringList prevTypeList = appLnkSet->types(); QStringList types = appLnkSet2->types(); for ( QStringList::Iterator ittypes=types.begin(); ittypes!=types.end(); ++ittypes) { if ( !(*ittypes).isEmpty() ) { if ( !prevTypeList.contains(*ittypes) ) { QString name = appLnkSet2->typeName(*ittypes); QPixmap pm = appLnkSet2->typePixmap(*ittypes); QPixmap bgPm = appLnkSet2->typeBigPixmap(*ittypes); if (pm.isNull()) { QImage img( Resource::loadImage( "UnknownDocument" ) ); pm = img.smoothScale( AppLnk::smallIconSize(), AppLnk::smallIconSize() ); bgPm = img.smoothScale( AppLnk::bigIconSize(), AppLnk::bigIconSize() ); } odebug << "adding type " << (*ittypes) << "" << oendl; // ### our current launcher expects docs tab to be last d->serverGui->typeAdded( *ittypes, name.isNull() ? (*ittypes) : name, pm, bgPm ); } prevTypeList.remove(*ittypes); } } for ( QStringList::Iterator ittypes=prevTypeList.begin(); ittypes!=prevTypeList.end(); ++ittypes) { odebug << "removing type " << (*ittypes) << "" << oendl; d->serverGui->typeRemoved(*ittypes); } prevTypeList = types; } QListIterator<AppLnk> it1( appLnkSet->children() ); QListIterator<AppLnk> it2( appLnkSet2->children() ); AppLnk *i; AppLnk *j; bool found; while ( (j=it2.current()) ) { it1 = appLnkSet->children(); found = false; while ( (i=it1.current()) ){ if (strcmp(i->name().ascii(),j->name().ascii()) == 0) found = true; ++it1; } if (!found) { qDebug("Item %s needs to be added",j->name().ascii() ); d->serverGui->applicationAdded( j->type(), *j ); } ++it2; } it1 = appLnkSet->children(); while ( (i=it1.current()) ) { it2 = appLnkSet2->children(); found = false; while ( (j=it2.current()) ){ if (strcmp(i->name().ascii(),j->name().ascii()) == 0) found = true; ++it2; } if (!found) { qDebug("Item %s needs to be removed",i->name().ascii() ); d->serverGui->applicationRemoved( i->type(), *i ); } ++it1; } delete appLnkSet; appLnkSet = appLnkSet2; } void DocumentList::storageChanged() { QTime t; // ### can implement better t.start(); DiffAppLnks(); // reloadAppLnks(); qDebug("Reload App links took %i ms",t.elapsed() ); reloadDocLnks(); // odebug << "Reload links took " << t.elapsed() << " ms " << oendl; qDebug("Reload All links took %i ms",t.elapsed() ); // ### 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 DocumentList::sendAllDocLinks() { if ( d->tid != 0 ) { // We are in the middle of scanning, set a flag so // we do this when we finish our scanning d->needToSendAllDocLinks = true; return; } QString contents; Categories cats; for ( QListIterator<DocLnk> it( d->dls.children() ); it.current(); ++it ) { DocLnk *doc = it.current(); QFileInfo fi( doc->file() ); if ( !fi.exists() ) continue; bool fake = !doc->linkFileKnown(); if ( !fake ) { QFile f( doc->linkFile() ); if ( f.open( IO_ReadOnly ) ) { QTextStream ts( &f ); ts.setEncoding( QTextStream::UnicodeUTF8 ); contents += ts.read(); f.close(); } else fake = TRUE; } if (fake) { contents += "[Desktop Entry]\n"; // No tr contents += "Categories = " + // No tr cats.labels("Document View",doc->categories()).join(";") + "\n"; // No tr contents += "Name = "+doc->name()+"\n"; // No tr contents += "Type = "+doc->type()+"\n"; // No tr } contents += "File = "+doc->file()+"\n"; // No tr // (resolves path) contents += QString("Size = %1\n").arg( fi.size() ); // No tr } //odebug << "sending length " << contents.length() << "" << oendl; #ifndef QT_NO_COP QCopEnvelope e( "QPE/Desktop", "docLinks(QString)" ); e << contents; #endif //odebug << "================ \n\n" << contents << "\n\n===============" << oendl; d->needToSendAllDocLinks = false; } DocumentListPrivate::DocumentListPrivate( ServerInterface *gui ) { storage = new StorageInfo( this ); serverGui = gui; if ( serverGui ) { sendAppLnks = serverGui->requiresApplications(); sendDocLnks = serverGui->requiresDocuments(); } else { sendAppLnks = false; sendDocLnks = false; } for ( int i = 0; i < MAX_SEARCH_DEPTH; i++ ) { listDirs[i] = 0; lists[i] = 0; listPositions[i] = 0; } initialize(); tid = 0; } void DocumentListPrivate::appendDocpath(FileSystem*fs) { QDir defPath(fs->path()+"/Documents"); QFileInfo f(fs->path()+"/.opiestorage.cf"); if (!f.exists()) { Mediadlg dlg(fs); if (QDialog::Accepted != QPEApplication::execDialog( &dlg )) { return; } } Config conf(f.filePath(), Config::File ); conf.setGroup("main"); if (!conf.readBoolEntry("check",false)) { return; } conf.setGroup("subdirs"); bool read_all = conf.readBoolEntry("wholemedia",true); if (read_all) { docPaths+=fs->path(); return; } QStringList subDirs = conf.readListEntry("subdirs",':'); if (subDirs.isEmpty()) { if (defPath.exists()) { docPaths+=defPath.path(); } return; } for (unsigned c = 0; c < subDirs.count();++c) { QDir docDir(QString(fs->path()+"/"+subDirs[c])); if (docDir.exists()) { docPaths+=docDir.path(); } } } void DocumentListPrivate::initialize() { // Reset dls.clear(); docPaths.clear(); reference.clear(); 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() ) { appendDocpath((*it)); ++i; } } for ( int i = 0; i < MAX_SEARCH_DEPTH; ++i ) { if ( listDirs[i] ) { delete listDirs[i]; listDirs[i] = 0; } lists[i] = 0; listPositions[i] = 0; } docPathsSearched = 0; searchDepth = -1; state = Find; dit = 0; } DocumentListPrivate::~DocumentListPrivate() { for ( int i = 0; i < MAX_SEARCH_DEPTH; i++ ) if ( listDirs[i] ) delete listDirs[i]; delete dit; } void DocumentListPrivate::estimatedPercentScanned() { double overallProgress = 0.0; double levelWeight = 75.0; int topCount = docPaths.count(); if ( topCount > 1 ) { levelWeight = levelWeight / topCount; overallProgress += (docPathsSearched - 1) * levelWeight; } for ( int d = 0; d <= searchDepth; d++ ) { if ( listDirs[d] ) { int items = lists[d]->count(); if ( items > 1 ) { levelWeight = levelWeight / items; // Take in to account "." and ".." overallProgress += (listPositions[d] - 3) * levelWeight; } } else { break; } } // odebug << "overallProgress: " << overallProgress << "" << oendl; if ( serverGui ) serverGui->documentScanningProgress( (int)overallProgress ); } const QString DocumentListPrivate::nextFile() { while ( TRUE ) { while ( searchDepth < 0 ) { // go to next base path if ( docPathsSearched >= docPaths.count() ) { // end of base paths return QString::null; } else { QDir dir( docPaths[docPathsSearched] ); // odebug << "now using base path: " << docPaths[docPathsSearched] << "" << oendl; 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]; if (!fil) { return QString::null; } QFileInfoList *fl = (QFileInfoList *)fil; unsigned int pos = listPositions[searchDepth]; if ( pos >= fl->count() ) { // go up a depth delete listDirs[searchDepth]; listDirs[searchDepth] = 0; lists[searchDepth] = 0; 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() ); // odebug << "now going in to path: " << bn << "" << oendl; 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 { estimatedPercentScanned(); return fl->at(pos)->filePath(); } } } } return QString::null; } bool DocumentListPrivate::store( DocLnk* dl ) { // if ( dl->fileKnown() && !dl->file().isEmpty() ) { if ( dl && dl->fileKnown() ) { dls.add( dl ); // store return TRUE; } // don't store - delete delete dl; return FALSE; } #define MAGIC_NUMBER ((void*)2) const DocLnk *DocumentListPrivate::iterate() { if ( state == Find ) { //odebug << "state Find" << oendl; QString file = nextFile(); while ( !file.isNull() ) { if ( file.right(8) == ".desktop" ) { // No tr DocLnk* dl = new DocLnk( file ); if ( store(dl) ) return dl; } else { reference.insert( file, MAGIC_NUMBER ); } file = nextFile(); } state = RemoveKnownFiles; if ( serverGui ) serverGui->documentScanningProgress( 75 ); } static int iterationI; static int iterationCount; if ( state == RemoveKnownFiles ) { //odebug << "state RemoveKnownFiles" << oendl; const QList<DocLnk> &list = dls.children(); for ( QListIterator<DocLnk> it( list ); it.current(); ++it ) { reference.remove( (*it)->file() ); // ### does this need to be deleted? } dit = new QDictIterator<void>(reference); state = MakeUnknownFiles; iterationI = 0; iterationCount = dit->count(); } if ( state == MakeUnknownFiles ) { //odebug << "state MakeUnknownFiles" << oendl; for (void* c; (c=dit->current()); ++(*dit) ) { if ( c == MAGIC_NUMBER ) { DocLnk* dl = new DocLnk; QFileInfo fi( dit->currentKey() ); dl->setFile( fi.filePath() ); dl->setName( fi.baseName() ); if ( store(dl) ) { ++*dit; iterationI++; if ( serverGui ) serverGui->documentScanningProgress( 75 + (25*iterationI)/iterationCount ); return dl; } } iterationI++; } delete dit; dit = 0; state = Done; } //odebug << "state Done" << oendl; return NULL; } #include "documentlist.moc" diff --git a/core/launcher/launcher.cpp b/core/launcher/launcher.cpp index bf2287d..6afbcd8 100644 --- a/core/launcher/launcher.cpp +++ b/core/launcher/launcher.cpp @@ -1,776 +1,786 @@ /********************************************************************** ** 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 "startmenu.h" #include "taskbar.h" #include "serverinterface.h" #include "launcherview.h" #include "launcher.h" #include "server.h" /* OPIE */ #include <opie2/odebug.h> #include <qtopia/global.h> #ifdef Q_WS_QWS #include <qtopia/qcopenvelope_qws.h> #endif #include <qtopia/resource.h> #include <qtopia/applnk.h> #include <qtopia/config.h> #include <qtopia/qpeapplication.h> #include <qtopia/mimetype.h> #include <qtopia/private/categories.h> #define QTOPIA_INTERNAL_FSLP #include <qtopia/lnkproperties.h> /* QT */ #include <qdir.h> #ifdef Q_WS_QWS #include <qkeyboard_qws.h> #include <qwindowsystem_qws.h> #endif #include <qtimer.h> #include <qcombobox.h> #include <qvbox.h> #include <qlayout.h> #include <qstyle.h> #include <qpushbutton.h> #include <qtabbar.h> #include <qwidgetstack.h> #include <qregexp.h> #include <qmessagebox.h> #include <qframe.h> #include <qpainter.h> #include <qlabel.h> #include <qtextstream.h> #include <qpopupmenu.h> /* STD */ #include <stdlib.h> #include <assert.h> #if defined(_OS_LINUX_) || defined(Q_OS_LINUX) #include <unistd.h> #include <stdio.h> #include <sys/vfs.h> #include <mntent.h> #endif static bool isVisibleWindow( int ); //=========================================================================== LauncherTabWidget::LauncherTabWidget( Launcher* parent ) : QVBox( parent ), docview( 0 ) { docLoadingWidgetEnabled = false; docLoadingWidget = 0; docLoadingWidgetProgress = 0; launcher = parent; categoryBar = new LauncherTabBar( this ); QPalette pal = categoryBar->palette(); pal.setColor( QColorGroup::Light, pal.color(QPalette::Active,QColorGroup::Shadow) ); pal.setColor( QColorGroup::Background, pal.active().background().light(110) ); categoryBar->setPalette( pal ); stack = new QWidgetStack(this); connect( categoryBar, SIGNAL(selected(int)), this, SLOT(raiseTabWidget()) ); categoryBar->show(); stack->show(); #if defined(Q_WS_QWS) && !defined(QT_NO_COP) QCopChannel *channel = new QCopChannel( "QPE/Launcher", this ); connect( channel, SIGNAL(received(const QCString&,const QByteArray&)), this, SLOT(launcherMessage(const QCString&,const QByteArray&)) ); connect( qApp, SIGNAL(appMessage(const QCString&,const QByteArray&)), this, SLOT(appMessage(const QCString&,const QByteArray&))); #endif createDocLoadingWidget(); } void LauncherTabWidget::createDocLoadingWidget() { // Construct the 'doc loading widget' shown when finding documents // ### LauncherView class needs changing to be more generic so // this widget can change its background similar to the iconviews // so the background for this matches docLoadingWidget = new LauncherView( stack ); docLoadingWidget->hideIcons(); QVBox *docLoadingVBox = new QVBox( docLoadingWidget ); docLoadingVBox->setSpacing( 20 ); docLoadingVBox->setMargin( 10 ); QWidget *space1 = new QWidget( docLoadingVBox ); docLoadingVBox->setStretchFactor( space1, 1 ); QLabel *waitPixmap = new QLabel( docLoadingVBox ); waitPixmap->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)5, (QSizePolicy::SizeType)5, waitPixmap->sizePolicy().hasHeightForWidth() ) ); waitPixmap->setPixmap( Resource::loadPixmap( "bigwait" ) ); waitPixmap->setAlignment( int( QLabel::AlignCenter ) ); Config cfg( "Launcher" ); cfg.setGroup( "DocTab" ); bool docTabEnabled = cfg.readBoolEntry( "Enable", true ); QLabel *textLabel = new QLabel( docLoadingVBox ); textLabel->setAlignment( int( QLabel::AlignCenter ) ); docLoadingWidgetProgress = new QProgressBar( docLoadingVBox ); docLoadingWidgetProgress->setProgress( 0 ); docLoadingWidgetProgress->setCenterIndicator( TRUE ); docLoadingWidgetProgress->setBackgroundMode( NoBackground ); // No flicker setProgressStyle(); if ( docTabEnabled ) { textLabel->setText( tr( "<b>Finding Documents...</b>" ) ); } else { textLabel->setText( tr( "<b>The Documents Tab<p>has been disabled.<p>" "Use Settings->Launcher->DocTab<p>to reenable it.</b></center>" ) ); docLoadingWidgetProgress->hide(); docLoadingWidgetEnabled = true; } QWidget *space2 = new QWidget( docLoadingVBox ); docLoadingVBox->setStretchFactor( space2, 1 ); cfg.setGroup( "Tab Documents" ); // No tr setTabViewAppearance( docLoadingWidget, cfg ); stack->addWidget( docLoadingWidget, 0 ); } void LauncherTabWidget::initLayout() { layout()->activate(); docView()->setFocus(); categoryBar->showTab("Documents"); } void LauncherTabWidget::appMessage(const QCString& message, const QByteArray&) { if ( message == "nextView()" ) categoryBar->nextTab(); } void LauncherTabWidget::raiseTabWidget() { if ( categoryBar->currentView() == docView() && docLoadingWidgetEnabled ) { stack->raiseWidget( docLoadingWidget ); docLoadingWidget->updateGeometry(); } else { stack->raiseWidget( categoryBar->currentView() ); } } void LauncherTabWidget::tabProperties() { LauncherView *view = categoryBar->currentView(); QPopupMenu *m = new QPopupMenu( this ); m->insertItem( tr("Icon View"), LauncherView::Icon ); m->insertItem( tr("List View"), LauncherView::List ); m->setItemChecked( (int)view->viewMode(), TRUE ); int rv = m->exec( QCursor::pos() ); if ( rv >= 0 && rv != view->viewMode() ) { view->setViewMode( (LauncherView::ViewMode)rv ); } delete m; } void LauncherTabWidget::deleteView( const QString& id ) { LauncherTab *t = categoryBar->launcherTab(id); if ( t ) { stack->removeWidget( t->view ); delete t->view; categoryBar->removeTab( t ); } } LauncherView* LauncherTabWidget::newView( const QString& id, const QPixmap& pm, const QString& label ) { LauncherView* view = new LauncherView( stack ); connect( view, SIGNAL(clicked(const AppLnk*)), this, SIGNAL(clicked(const AppLnk*))); connect( view, SIGNAL(rightPressed(AppLnk*)), this, SIGNAL(rightPressed(AppLnk*))); int n = categoryBar->count(); stack->addWidget( view, n ); LauncherTab *tab = new LauncherTab( id, view, pm, label ); categoryBar->insertTab( tab, n-1 ); if ( id == "Documents" ) docview = view; odebug << "inserting " << id << " at " << n-1 << "" << oendl; Config cfg("Launcher"); setTabAppearance( tab, cfg ); cfg.setGroup( "GUI" ); view->setBusyIndicatorType( cfg.readEntry( "BusyType", QString::null ) ); return view; } LauncherView *LauncherTabWidget::view( const QString &id ) { LauncherTab *t = categoryBar->launcherTab(id); if ( !t ) return 0; return t->view; } LauncherView *LauncherTabWidget::docView() { return docview; } void LauncherTabWidget::setLoadingWidgetEnabled( bool v ) { if ( v != docLoadingWidgetEnabled && docLoadingWidget ) { docLoadingWidgetEnabled = v; raiseTabWidget(); } } void LauncherTabWidget::setLoadingProgress( int percent ) { docLoadingWidgetProgress->setProgress( (percent / 4) * 4 ); } // ### this function could more to LauncherView void LauncherTabWidget::setTabViewAppearance( LauncherView *v, Config &cfg ) { // View QString view = cfg.readEntry( "View", "Icon" ); if ( view == "List" ) // No tr v->setViewMode( LauncherView::List ); QString bgType = cfg.readEntry( "BackgroundType", "Image" ); if ( bgType == "Image" ) { // No tr QString pm = cfg.readEntry( "BackgroundImage", "launcher/opie-background" ); v->setBackgroundType( LauncherView::Image, pm ); } else if ( bgType == "SolidColor" ) { QString c = cfg.readEntry( "BackgroundColor" ); v->setBackgroundType( LauncherView::SolidColor, c ); } else { v->setBackgroundType( LauncherView::Ruled, QString::null ); } QString textCol = cfg.readEntry( "TextColor" ); if ( textCol.isEmpty() ) v->setTextColor( QColor() ); else v->setTextColor( QColor(textCol) ); // bool customFont = cfg.readBoolEntry( "CustomFont", FALSE ); QStringList font = cfg.readListEntry( "Font", ',' ); if ( font.count() == 4 ) v->setViewFont( QFont(font[0], font[1].toInt(), font[2].toInt(), font[3].toInt()!=0) ); // ### FIXME TabColor TabTextColor } // ### Could move to LauncherTab void LauncherTabWidget::setTabAppearance( LauncherTab *tab, Config &cfg ) { cfg.setGroup( QString( "Tab %1" ).arg(tab->type) ); // No tr setTabViewAppearance( tab->view, cfg ); // Tabs QString tabCol = cfg.readEntry( "TabColor" ); if ( tabCol.isEmpty() ) tab->bgColor = QColor(); else tab->bgColor = QColor(tabCol); QString tabTextCol = cfg.readEntry( "TabTextColor" ); if ( tabTextCol.isEmpty() ) tab->fgColor = QColor(); else tab->fgColor = QColor(tabTextCol); } void LauncherTabWidget::paletteChange( const QPalette &p ) { QVBox::paletteChange( p ); QPalette pal = palette(); pal.setColor( QColorGroup::Light, pal.color(QPalette::Active,QColorGroup::Shadow) ); pal.setColor( QColorGroup::Background, pal.active().background().light(110) ); categoryBar->setPalette( pal ); categoryBar->update(); } void LauncherTabWidget::styleChange( QStyle & ) { QTimer::singleShot( 0, this, SLOT(setProgressStyle()) ); } void LauncherTabWidget::setProgressStyle() { if (docLoadingWidgetProgress) { docLoadingWidgetProgress->setFrameShape( QProgressBar::Box ); docLoadingWidgetProgress->setFrameShadow( QProgressBar::Plain ); docLoadingWidgetProgress->setMargin( 1 ); docLoadingWidgetProgress->setLineWidth( 1 ); } } void LauncherTabWidget::setBusy(bool on) { if ( on ) currentView()->setBusy(TRUE); else { for ( int i = 0; i < categoryBar->count(); i++ ) { LauncherView *view = ((LauncherTab *)categoryBar->tab(i))->view; view->setBusy( FALSE ); } } } void LauncherTabWidget::setBusyIndicatorType( const QString& str ) { for (int i = 0; i < categoryBar->count(); i++ ) { LauncherView* view = static_cast<LauncherTab*>( categoryBar->tab(i) )->view; view->setBusyIndicatorType( str ); } } LauncherView *LauncherTabWidget::currentView(void) { return (LauncherView*)stack->visibleWidget(); } void LauncherTabWidget::launcherMessage( const QCString &msg, const QByteArray &data) { QDataStream stream( data, IO_ReadOnly ); if ( msg == "setTabView(QString,int)" ) { QString id; stream >> id; int mode; stream >> mode; if ( view(id) ) view(id)->setViewMode( (LauncherView::ViewMode)mode ); } else if ( msg == "setTabBackground(QString,int,QString)" ) { QString id; stream >> id; int mode; stream >> mode; QString pixmapOrColor; stream >> pixmapOrColor; if ( view(id) ) view(id)->setBackgroundType( (LauncherView::BackgroundType)mode, pixmapOrColor ); if ( id == "Documents" ) docLoadingWidget->setBackgroundType( (LauncherView::BackgroundType)mode, pixmapOrColor ); } else if ( msg == "setTextColor(QString,QString)" ) { QString id; stream >> id; QString color; stream >> color; if ( view(id) ) view(id)->setTextColor( QColor(color) ); if ( id == "Documents" ) docLoadingWidget->setTextColor( QColor(color) ); } else if ( msg == "setFont(QString,QString,int,int,int)" ) { QString id; stream >> id; QString fam; stream >> fam; int size; stream >> size; int weight; stream >> weight; int italic; stream >> italic; if ( view(id) ) { if ( !fam.isEmpty() ) { view(id)->setViewFont( QFont(fam, size, weight, italic!=0) ); odebug << "setFont: " << fam << ", " << size << ", " << weight << ", " << italic << "" << oendl; } else { view(id)->clearViewFont(); } } }else if ( msg == "setBusyIndicatorType(QString)" ) { QString type; stream >> type; setBusyIndicatorType( type ); }else if ( msg == "home()" ) { if ( isVisibleWindow( static_cast<QWidget*>(parent())->winId() ) ) { if (categoryBar) categoryBar->nextTab(); }else static_cast<QWidget*>(parent())->raise(); } } //--------------------------------------------------------------------------- Launcher::Launcher() : QMainWindow( 0, "PDA User Interface", QWidget::WStyle_Customize | QWidget::WGroupLeader ) { tabs = 0; tb = 0; Config cfg( "Launcher" ); cfg.setGroup( "DocTab" ); docTabEnabled = cfg.readBoolEntry( "Enable", true ); } void Launcher::createGUI() { setCaption( tr("Launcher") ); // we have a pretty good idea how big we'll be setGeometry( 0, 0, qApp->desktop()->width(), qApp->desktop()->height() ); tb = new TaskBar; tabs = new LauncherTabWidget( this ); setCentralWidget( tabs ); ServerInterface::dockWidget( tb, ServerInterface::Bottom ); tb->show(); qApp->installEventFilter( this ); connect( qApp, SIGNAL(symbol()), this, SLOT(toggleSymbolInput()) ); connect( qApp, SIGNAL(numLockStateToggle()), this, SLOT(toggleNumLockState()) ); connect( qApp, SIGNAL(capsLockStateToggle()), this, SLOT(toggleCapsLockState()) ); connect( tb, SIGNAL(tabSelected(const QString&)), this, SLOT(showTab(const QString&)) ); connect( tabs, SIGNAL(selected(const QString&)), this, SLOT(viewSelected(const QString&)) ); connect( tabs, SIGNAL(clicked(const AppLnk*)), this, SLOT(select(const AppLnk*))); connect( tabs, SIGNAL(rightPressed(AppLnk*)), this, SLOT(properties(AppLnk*))); #if defined(Q_WS_QWS) && !defined(QT_NO_COP) QCopChannel* sysChannel = new QCopChannel( "QPE/System", this ); connect( sysChannel, SIGNAL(received(const QCString&,const QByteArray&)), this, SLOT(systemMessage(const QCString&,const QByteArray&)) ); #endif // all documents QImage img( Resource::loadImage( "DocsIcon" ) ); QPixmap pm; pm = img.smoothScale( AppLnk::smallIconSize(), AppLnk::smallIconSize() ); // It could add this itself if it handles docs tabs->newView("Documents", pm, tr("Documents") )->setToolsEnabled( TRUE ); QTimer::singleShot( 0, tabs, SLOT( initLayout() ) ); qApp->setMainWidget( this ); QTimer::singleShot( 500, this, SLOT( makeVisible() ) ); } Launcher::~Launcher() { if ( tb ) destroyGUI(); } bool Launcher::requiresDocuments() const { Config cfg( "Launcher" ); cfg.setGroup( "DocTab" ); return cfg.readBoolEntry( "Enable", true ); } void Launcher::makeVisible() { showMaximized(); } void Launcher::destroyGUI() { delete tb; tb = 0; delete tabs; tabs =0; } bool Launcher::eventFilter( QObject*, QEvent *ev ) { #ifdef QT_QWS_CUSTOM if ( ev->type() == QEvent::KeyPress ) { QKeyEvent *ke = (QKeyEvent *)ev; if ( ke->key() == Qt::Key_F11 ) { // menu key QWidget *active = qApp->activeWindow(); if ( active && active->isPopup() ) active->close(); else { Global::terminateBuiltin("calibrate"); // No tr tb->launchStartMenu(); } return TRUE; } } #else Q_UNUSED(ev); #endif return FALSE; } void Launcher::toggleSymbolInput() { tb->toggleSymbolInput(); } void Launcher::toggleNumLockState() { tb->toggleNumLockState(); } void Launcher::toggleCapsLockState() { tb->toggleCapsLockState(); } static bool isVisibleWindow(int wid) { #ifdef Q_WS_QWS const QList<QWSWindow> &list = qwsServer->clientWindows(); QWSWindow* w; for (QListIterator<QWSWindow> it(list); (w=it.current()); ++it) { if ( w->winId() == wid ) return !w->isFullyObscured(); } #endif return FALSE; } void Launcher::viewSelected(const QString& s) { setCaption( s + tr(" - Launcher") ); } void Launcher::showTab(const QString& id) { tabs->categoryBar->showTab(id); raise(); } void Launcher::select( const AppLnk *appLnk ) { if ( appLnk->type() == "Folder" ) { // No tr // Not supported: flat is simpler for the user } else { if ( appLnk->exec().isNull() ) { int i = QMessageBox::information(this,tr("No application"), tr("<p>No application is defined for this document." "<p>Type is %1.").arg(appLnk->type()), tr("OK"), tr("View as text"), 0, 0, 1); /* ### Fixme */ if ( i == 1 ) Global::execute("textedit",appLnk->file()); return; } tabs->setBusy(TRUE); emit executing( appLnk ); appLnk->execute(); } } void Launcher::properties( AppLnk *appLnk ) { if ( appLnk->type() == "Folder" ) { // No tr // Not supported: flat is simpler for the user } else { /* ### libqtopia FIXME also moving docLnks... */ LnkProperties prop(appLnk,0 ); QPEApplication::execDialog( &prop ); } } void Launcher::storageChanged( const QList<FileSystem> &fs ) { // ### update combo boxes if we had a combo box for the storage type } void Launcher::systemMessage( const QCString &msg, const QByteArray &data) { QDataStream stream( data, IO_ReadOnly ); if ( msg == "busy()" ) { tb->startWait(); } else if ( msg == "notBusy(QString)" ) { QString app; stream >> app; tabs->setBusy(FALSE); tb->stopWait(app); } else if (msg == "applyStyle()") { tabs->currentView()->relayout(); } } // These are the update functions from the server void Launcher::typeAdded( const QString& type, const QString& name, const QPixmap& pixmap, const QPixmap& ) { tabs->newView( type, pixmap, name ); ids.append( type ); /* this will be called in applicationScanningProgress with value 100! */ // tb->refreshStartMenu(); static bool first = TRUE; if ( first ) { first = FALSE; tabs->categoryBar->showTab(type); } tabs->view( type )->setUpdatesEnabled( FALSE ); tabs->view( type )->setSortEnabled( FALSE ); } void Launcher::typeRemoved( const QString& type ) { tabs->view( type )->removeAllItems(); tabs->deleteView( type ); ids.remove( type ); /* this will be called in applicationScanningProgress with value 100! */ // tb->refreshStartMenu(); } void Launcher::applicationAdded( const QString& type, const AppLnk& app ) { if ( app.type() == "Separator" ) // No tr return; LauncherView *view = tabs->view( type ); if ( view ) view->addItem( new AppLnk( app ), FALSE ); else qWarning("addAppLnk: No view for type %s. Can't add app %s!", type.latin1(),app.name().latin1() ); MimeType::registerApp( app ); } void Launcher::applicationRemoved( const QString& type, const AppLnk& app ) { LauncherView *view = tabs->view( type ); if ( view ) view->removeLink( app.linkFile() ); else owarn << "removeAppLnk: No view for " << type << "!" << oendl; } void Launcher::allApplicationsRemoved() { MimeType::clear(); for ( QStringList::ConstIterator it=ids.begin(); it!= ids.end(); ++it) tabs->view( (*it) )->removeAllItems(); } void Launcher::documentAdded( const DocLnk& doc ) { tabs->docView()->addItem( new DocLnk( doc ), FALSE ); } +void Launcher::aboutToAddBegin() +{ + tabs->docView()->setUpdatesEnabled( false ); +} + +void Launcher::aboutToAddEnd() +{ + tabs->docView()->setUpdatesEnabled( true ); +} + void Launcher::showLoadingDocs() { tabs->docView()->hide(); } void Launcher::showDocTab() { if ( tabs->categoryBar->currentView() == tabs->docView() ) tabs->docView()->show(); } void Launcher::documentRemoved( const DocLnk& doc ) { tabs->docView()->removeLink( doc.linkFile() ); } void Launcher::documentChanged( const DocLnk& oldDoc, const DocLnk& newDoc ) { documentRemoved( oldDoc ); documentAdded( newDoc ); } void Launcher::allDocumentsRemoved() { tabs->docView()->removeAllItems(); } void Launcher::applicationStateChanged( const QString& name, ApplicationState state ) { tb->setApplicationState( name, state ); } void Launcher::applicationScanningProgress( int percent ) { switch ( percent ) { case 0: { for ( QStringList::ConstIterator it=ids.begin(); it!= ids.end(); ++it) { tabs->view( (*it) )->setUpdatesEnabled( FALSE ); tabs->view( (*it) )->setSortEnabled( FALSE ); } break; } case 100: { for ( QStringList::ConstIterator it=ids.begin(); it!= ids.end(); ++it) { tabs->view( (*it) )->setUpdatesEnabled( TRUE ); tabs->view( (*it) )->setSortEnabled( TRUE ); } tb->refreshStartMenu(); break; } default: break; } } void Launcher::documentScanningProgress( int percent ) { switch ( percent ) { case 0: { tabs->setLoadingProgress( 0 ); tabs->setLoadingWidgetEnabled( TRUE ); tabs->docView()->setUpdatesEnabled( FALSE ); tabs->docView()->setSortEnabled( FALSE ); break; } case 100: { tabs->docView()->updateTools(); tabs->docView()->setSortEnabled( TRUE ); tabs->docView()->setUpdatesEnabled( TRUE ); tabs->setLoadingWidgetEnabled( FALSE ); break; } default: tabs->setLoadingProgress( percent ); break; } } diff --git a/core/launcher/launcher.h b/core/launcher/launcher.h index 4f3ff8c..29bd7db 100644 --- a/core/launcher/launcher.h +++ b/core/launcher/launcher.h @@ -1,157 +1,159 @@ /********************************************************************** ** 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. ** **********************************************************************/ #ifndef LAUNCHER_H #define LAUNCHER_H #include <qtopia/config.h> #include <qtopia/storage.h> #include <qtopia/applnk.h> #include <qmainwindow.h> #include <qstringlist.h> #include <qprogressbar.h> #include <qvbox.h> #include <qlist.h> #include <qdict.h> #include "launcherview.h" #include "launchertab.h" #include "serverinterface.h" class QWidgetStack; class TaskBar; class Launcher; class LauncherTabWidget : public QVBox { // can't use a QTabWidget, since it won't let us set the frame style. Q_OBJECT public: LauncherTabWidget( Launcher* parent ); void updateDocs(AppLnkSet* docFolder); void setBusy(bool on); LauncherView *currentView(void); LauncherView* newView( const QString&, const QPixmap& pm, const QString& label ); void deleteView( const QString& ); void setTabViewAppearance( LauncherView *v, Config &cfg ); void setTabAppearance( LauncherTab *, Config &cfg ); LauncherView *view( const QString & ); LauncherView *docView(); void createDocLoadingWidget(); void setLoadingWidgetEnabled( bool v ); void setLoadingProgress( int percent ); LauncherTabBar* categoryBar; void setBusyIndicatorType( const QString& type ); signals: void selected(const QString&); void clicked(const AppLnk*); void rightPressed(AppLnk*); protected slots: void raiseTabWidget(); void tabProperties(); void initLayout(); private slots: void launcherMessage( const QCString &, const QByteArray &); void appMessage( const QCString &, const QByteArray &); void setProgressStyle(); protected: void paletteChange( const QPalette &p ); void styleChange( QStyle & ); private: Launcher *launcher; LauncherView *docview; QWidgetStack *stack; LauncherView *docLoadingWidget; QProgressBar *docLoadingWidgetProgress; bool docLoadingWidgetEnabled; }; class Launcher : public QMainWindow, public ServerInterface { Q_OBJECT public: Launcher(); ~Launcher(); // implementing ServerInterface void createGUI(); void destroyGUI(); void typeAdded( const QString& type, const QString& name, const QPixmap& pixmap, const QPixmap& bgPixmap ); void typeRemoved( const QString& type ); void applicationAdded( const QString& type, const AppLnk& doc ); void applicationRemoved( const QString& type, const AppLnk& doc ); void allApplicationsRemoved(); void applicationStateChanged( const QString& name, ApplicationState state ); void documentAdded( const DocLnk& doc ); void documentRemoved( const DocLnk& doc ); + void aboutToAddBegin(); + void aboutToAddEnd(); void allDocumentsRemoved(); void documentChanged( const DocLnk& oldDoc, const DocLnk& newDoc ); void storageChanged( const QList<FileSystem> & ); void applicationScanningProgress( int percent ); void documentScanningProgress( int percent ); bool requiresApplications() const { return TRUE; } bool requiresDocuments() const; void showLoadingDocs(); void showDocTab(); QStringList idList() const { return ids; } public slots: void viewSelected(const QString&); void showTab(const QString&); void select( const AppLnk * ); void properties( AppLnk * ); void makeVisible(); signals: void executing( const AppLnk * ); private slots: void systemMessage( const QCString &, const QByteArray &); void toggleSymbolInput(); void toggleNumLockState(); void toggleCapsLockState(); protected: bool eventFilter( QObject *o, QEvent *ev ); private: void updateApps(); void loadDocs(); void updateDocs(); void updateTabs(); LauncherTabWidget *tabs; QStringList ids; TaskBar *tb; bool docTabEnabled; }; #endif // LAUNCHERVIEW_H diff --git a/core/launcher/serverinterface.h b/core/launcher/serverinterface.h index e57ea51..132766f 100644 --- a/core/launcher/serverinterface.h +++ b/core/launcher/serverinterface.h @@ -1,72 +1,74 @@ /********************************************************************** ** 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. ** **********************************************************************/ #ifndef SERVER_INTERFACE_H #define SERVER_INTERFACE_H #include <qstring.h> #include <qpixmap.h> #include <qwidget.h> #include <qtopia/applnk.h> #include <qtopia/storage.h> class ServerInterface { public: virtual ~ServerInterface(); virtual void createGUI() = 0; virtual void destroyGUI() = 0; // These notify of the application categories, like what is used in the current launcher tabs, // for example "Applications", "Games" etc. virtual void typeAdded( const QString& type, const QString& name, const QPixmap& pixmap, const QPixmap& bgPixmap ) = 0; virtual void typeRemoved( const QString& type ) = 0; // These functions notify when an application is added or removed and to which category it belongs virtual void applicationAdded( const QString& type, const AppLnk& doc ) = 0; virtual void applicationRemoved( const QString& type, const AppLnk& doc ) = 0; virtual void allApplicationsRemoved() = 0; // Useful for wait icons, or running application lists etc enum ApplicationState { Launching, Running, Terminated }; virtual void applicationStateChanged( const QString& name, ApplicationState state ) = 0; static const AppLnkSet& appLnks(); // These functions notify of adding, removal and changes of document links used in the documents tab for example + virtual void aboutToAddBegin() {} + virtual void aboutToAddEnd() {} virtual void documentAdded( const DocLnk& doc ) = 0; virtual void documentRemoved( const DocLnk& doc ) = 0; virtual void allDocumentsRemoved() = 0; virtual void documentChanged( const DocLnk& oldDoc, const DocLnk& newDoc ) = 0; virtual void storageChanged( const QList<FileSystem> & ) = 0; virtual void applicationScanningProgress( int percent ) = 0; virtual void documentScanningProgress( int percent ) = 0; // Tells the server if the GUI needs to be updated about documents or applnks virtual bool requiresApplications() const = 0; virtual bool requiresDocuments() const = 0; enum DockArea { Top, Bottom, Left, Right }; static void dockWidget( QWidget *w, DockArea placement ); }; #endif // SERVER_INTERFACE_H |