-rw-r--r-- | core/launcher/launcher.cpp | 53 |
1 files changed, 42 insertions, 11 deletions
diff --git a/core/launcher/launcher.cpp b/core/launcher/launcher.cpp index f9c6c02..1a52f69 100644 --- a/core/launcher/launcher.cpp +++ b/core/launcher/launcher.cpp @@ -1,212 +1,212 @@ /********************************************************************** ** Copyright (c) 2002 Holger zecke Freyther ** Copyright (C) 2000 Trolltech AS. All rights reserved. ** ** This file is part of 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. ** **********************************************************************/ // WARNING: Do *NOT* define this yourself. The SL5xxx from SHARP does NOT // have this class. #define QTOPIA_INTERNAL_FSLP #include <opie/oconfig.h> #include <qpe/qcopenvelope_qws.h> #include <qpe/resource.h> #include <qpe/applnk.h> #include <qpe/config.h> #include <qpe/global.h> #include <qpe/qpeapplication.h> #include <qpe/mimetype.h> #include <qpe/storage.h> #include <qpe/palmtoprecord.h> #include <qdatetime.h> #include <qdir.h> #include <qwindowsystem_qws.h> #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 <qlayout.h> #include <qregexp.h> #include <qmessagebox.h> #include <qframe.h> #include <qpainter.h> #include <qlabel.h> #include <qtextstream.h> #include "launcherview.h" #include "launcher.h" #include "syncdialog.h" #include "desktop.h" #include <qpe/lnkproperties.h> #include "mrulist.h" #include "qrsync.h" #include <stdlib.h> #include <unistd.h> #if defined(_OS_LINUX_) || defined(Q_OS_LINUX) #include <stdio.h> #include <sys/vfs.h> #include <mntent.h> #endif #include <qpe/storage.h> #include "mediummountgui.h" //#define SHOW_ALL // uidGen // uidGen namespace { QStringList configToMime( Config *cfg ){ QStringList mimes; - bool tmpMime; + bool tmpMime = true; cfg->setGroup("mimetypes" ); - tmpMime = cfg->readBoolEntry("all" ,false); + tmpMime = cfg->readBoolEntry("all" ,true); if( tmpMime ){ mimes << QString::null; return mimes; }else{ tmpMime = cfg->readBoolEntry("audio", true ); if(tmpMime ) mimes.append("audio/*" ); tmpMime = cfg->readBoolEntry("image", true ); if(tmpMime ) mimes.append("image/*" ); tmpMime = cfg->readBoolEntry("text", true ); if(tmpMime ) mimes.append("text/*"); tmpMime = cfg->readBoolEntry("video", true ); if(tmpMime ) mimes.append("video/*" ); } return mimes; } } CategoryTabWidget::CategoryTabWidget( QWidget* parent ) : QVBox( parent ) { categoryBar = 0; stack = 0; } void CategoryTabWidget::prevTab() { if ( categoryBar ) { int n = categoryBar->count(); int tab = categoryBar->currentTab(); if ( tab >= 0 ) categoryBar->setCurrentTab( (tab - 1 + n)%n ); } } void CategoryTabWidget::nextTab() { if ( categoryBar ) { int n = categoryBar->count(); int tab = categoryBar->currentTab(); categoryBar->setCurrentTab( (tab + 1)%n ); } } void CategoryTabWidget::addItem( const QString& linkfile ) { int i=0; AppLnk *app = new AppLnk(linkfile); if ( !app->isValid() ) { delete app; return; } if ( !app->file().isEmpty() ) { // A document delete app; app = new DocLnk(linkfile); ((LauncherView*)(stack->widget(ids.count()-1)))->addItem(app); return; } for ( QStringList::Iterator it=ids.begin(); it!=ids.end(); ++it) { if ( !(*it).isEmpty() ) { QRegExp tf(*it,FALSE,TRUE); if ( tf.match(app->type()) >= 0 ) { ((LauncherView*)stack->widget(i))->addItem(app); return; } i++; } } } void CategoryTabWidget::initializeCategories(AppLnkSet* rootFolder, AppLnkSet* docFolder, const QList<FileSystem> &fs) { delete categoryBar; categoryBar = new CategoryTabBar( 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 ); delete stack; stack = new QWidgetStack(this); tabs=0; ids.clear(); QStringList types = rootFolder->types(); for ( QStringList::Iterator it=types.begin(); it!=types.end(); ++it) { if ( !(*it).isEmpty() ) { newView(*it,rootFolder->typePixmap(*it),rootFolder->typeName(*it)); } } QListIterator<AppLnk> it( rootFolder->children() ); AppLnk* l; while ( (l=it.current()) ) { if ( l->type() == "Separator" ) { rootFolder->remove(l); delete l; } else { int i=0; for ( QStringList::Iterator it=types.begin(); it!=types.end(); ++it) { if ( *it == l->type() ) ((LauncherView*)stack->widget(i))->addItem(l,FALSE); i++; } } ++it; } rootFolder->detachChildren(); for (int i=0; i<tabs; i++) ((LauncherView*)stack->widget(i))->sort(); // all documents docview = newView( QString::null, Resource::loadPixmap("DocsIcon"), tr("Documents")); docview->populate( docFolder, QString::null ); docFolder->detachChildren(); docview->setFileSystems(fs); docview->setToolsEnabled(TRUE); @@ -409,308 +409,339 @@ void CategoryTabBar::paintLabel( QPainter* p, const QRect&, // if ( t->id != currentTab() ) //r.moveBy( 1, 1 ); // if ( t->iconSet() ) { // the tab has an iconset, draw it in the right mode QIconSet::Mode mode = (t->isEnabled() && isEnabled()) ? QIconSet::Normal : QIconSet::Disabled; if ( mode == QIconSet::Normal && has_focus ) mode = QIconSet::Active; QPixmap pixmap = t->iconSet()->pixmap( QIconSet::Small, mode ); int pixw = pixmap.width(); int pixh = pixmap.height(); p->drawPixmap( r.left() + 6, r.center().y() - pixh / 2 + 1, pixmap ); r.setLeft( r.left() + pixw + 5 ); } QRect tr = r; if ( r.width() < 20 ) return; if ( t->isEnabled() && isEnabled() ) { #if defined(_WS_WIN32_) if ( colorGroup().brush( QColorGroup::Button ) == colorGroup().brush( QColorGroup::Background ) ) p->setPen( colorGroup().buttonText() ); else p->setPen( colorGroup().foreground() ); #else p->setPen( colorGroup().foreground() ); #endif p->drawText( tr, AlignCenter | AlignVCenter | ShowPrefix, t->text() ); } else { p->setPen( palette().disabled().foreground() ); p->drawText( tr, AlignCenter | AlignVCenter | ShowPrefix, t->text() ); } } //--------------------------------------------------------------------------- Launcher::Launcher( QWidget* parent, const char* name, WFlags fl ) : QMainWindow( parent, name, fl ) { setCaption( tr("Launcher") ); syncDialog = 0; // we have a pretty good idea how big we'll be setGeometry( 0, 0, qApp->desktop()->width(), qApp->desktop()->height() ); tabs = 0; rootFolder = 0; docsFolder = 0; int stamp = uidgen.generate(); // this is our timestamp to see which devices we know //uidgen.store( stamp ); m_timeStamp = QString::number( stamp ); tabs = new CategoryTabWidget( this ); tabs->setMaximumWidth( qApp->desktop()->width() ); setCentralWidget( tabs ); 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 storage = new StorageInfo( this ); connect( storage, SIGNAL( disksChanged() ), SLOT( storageChanged() ) ); updateTabs(); preloadApps(); in_lnk_props = FALSE; got_lnk_change = FALSE; } Launcher::~Launcher() { } static bool isVisibleWindow(int wid) { const QList<QWSWindow> &list = qwsServer->clientWindows(); QWSWindow* w; for (QListIterator<QWSWindow> it(list); (w=it.current()); ++it) { if ( w->winId() == wid ) return !w->isFullyObscured(); } return FALSE; } void Launcher::showMaximized() { if ( isVisibleWindow( winId() ) ) doMaximize(); else QTimer::singleShot( 20, this, SLOT(doMaximize()) ); } void Launcher::doMaximize() { QMainWindow::showMaximized(); } void Launcher::updateMimeTypes() { MimeType::clear(); updateMimeTypes(rootFolder); } void Launcher::updateMimeTypes(AppLnkSet* folder) { for ( QListIterator<AppLnk> it( folder->children() ); it.current(); ++it ) { AppLnk *app = it.current(); if ( app->type() == "Folder" ) updateMimeTypes((AppLnkSet *)app); else { MimeType::registerApp(*app); } } } - +/** This is a HACK.... + * Reason: scanning huge mediums, microdirvers for examples + * consomes time. To avoid that we invented the MediumMountCheck + * + * a) the user globally disabled medium checking. We can ignore + * all removable medium + * b) the user enabled medium checking globally and we need to use this mimefilter + * c) the user enabled medium checking on a per medium bases + * c1) we already checked and its not ask again turns + * c2) we need to ask and then apply the mimefilter + */ void Launcher::loadDocs() // ok here comes a hack belonging to Global:: { - qWarning("loading Documents" ); - qWarning("The currentTimeStamp is: %s", m_timeStamp.latin1() ); delete docsFolder; docsFolder = new DocLnkSet; - qWarning("new DocLnkSet" ); + DocLnkSet *tmp = 0; QString home = QString(getenv("HOME")) + "/Documents"; tmp = new DocLnkSet( home , QString::null); docsFolder->appendFrom( *tmp ); delete tmp; + + Config mediumCfg( "medium"); + mediumCfg.setGroup("main"); + // a) -zecke we don't want to check + if(!mediumCfg.readBoolEntry("use", true ) ) + return; + // find out wich filesystems are new in this round // We will do this by having a timestamp inside each mountpoint // if the current timestamp doesn't match this is a new file system and // come up with our MediumMountGui :) let the hacking begin int stamp = uidgen.generate(); QString newStamp = QString::number( stamp ); // generates newtime Stamp StorageInfo storage; const QList<FileSystem> &fileSystems = storage.fileSystems(); QListIterator<FileSystem> it ( fileSystems ); - - + + // b) + if( mediumCfg.readBoolEntry("global", true ) ){ + QString mime = configToMime(&mediumCfg).join(";"); + for( ; it.current(); ++it ){ + if( (*it)->isRemovable() ){ + tmp = new DocLnkSet( (*it)->path(), mime ); + docsFolder->appendFrom( *tmp ); + delete tmp; + } + } // done + return; // save the else + } + // c) zecke for ( ; it.current(); ++it ) { if ( (*it)->isRemovable() ) { // let's find out if we should search on it - qWarning("%s is removeable", (*it)->path().latin1() ); - OConfig cfg( (*it)->path() + "/.opiestorage.cf"); + Config cfg( (*it)->path() + "/.opiestorage.cf", Config::File); cfg.setGroup("main"); QString stamp = cfg.readEntry("timestamp", QDateTime::currentDateTime().toString() ); + /** This medium is uptodate + */ if( stamp == m_timeStamp ){ // ok we know this card cfg.writeEntry("timestamp", newStamp ); //just write a new timestamp // we need to scan the list now. Hopefully the cache will be there // read the mimetypes from the config and search for documents QStringList mimetypes = configToMime( &cfg); tmp = new DocLnkSet( (*it)->path(), mimetypes.join(";") ); docsFolder->appendFrom( *tmp ); delete tmp; - + }else{ // come up with the gui cause this a new card MediumMountGui medium(&cfg, (*it)->path() ); if( medium.check() ){ // we did not ask before or ask again is off + /** c2) */ if( medium.exec() ){ // he clicked yes so search it // speicher //cfg.read(); // cause of a race we need to reread - fixed + cfg.setGroup("main"); cfg.writeEntry("timestamp", newStamp ); cfg.write(); tmp = new DocLnkSet( (*it)->path(), medium.mimeTypes().join(";" ) ); docsFolder->appendFrom( *tmp ); delete tmp; }// no else + /** c1) */ }else{ // we checked // do something different see what we need to do // let's see if we should check the device cfg.setGroup("main" ); bool check = cfg.readBoolEntry("autocheck", true ); if( check ){ // find the documents tmp = new DocLnkSet( (*it)->path(), configToMime(&cfg ).join(";") ); docsFolder->appendFrom( *tmp ); delete tmp; } } } } } m_timeStamp = newStamp; } void Launcher::updateTabs() { MimeType::updateApplications(); // ### reads all applnks twice delete rootFolder; rootFolder = new AppLnkSet( MimeType::appsFolderName() ); loadDocs(); tabs->initializeCategories(rootFolder, docsFolder, storage->fileSystems()); } void Launcher::updateDocs() { loadDocs(); tabs->updateDocs(docsFolder,storage->fileSystems()); } void Launcher::viewSelected(const QString& s) { setCaption( s + tr(" - Launcher") ); } void Launcher::nextView() { tabs->nextTab(); } void Launcher::select( const AppLnk *appLnk ) { if ( appLnk->type() == "Folder" ) { // Not supported: flat is simpler for the user } else { if ( appLnk->exec().isNull() ) { QMessageBox::information(this,tr("No application"), tr("<p>No application is defined for this document." "<p>Type is %1.").arg(appLnk->type())); return; } tabs->setBusy(TRUE); emit executing( appLnk ); appLnk->execute(); } } void Launcher::externalSelected(const AppLnk *appLnk) { tabs->setBusy(TRUE); emit executing( appLnk ); } void Launcher::properties( AppLnk *appLnk ) { if ( appLnk->type() == "Folder" ) { // Not supported: flat is simpler for the user } else { in_lnk_props = TRUE; got_lnk_change = FALSE; LnkProperties prop(appLnk); connect(&prop, SIGNAL(select(const AppLnk *)), this, SLOT(externalSelected(const AppLnk *))); prop.showMaximized(); prop.exec(); in_lnk_props = FALSE; if ( got_lnk_change ) { updateLink(lnk_change); } } } void Launcher::updateLink(const QString& link) { if (link.isNull()) updateTabs(); else if (link.isEmpty()) updateDocs(); else tabs->updateLink(link); } void Launcher::systemMessage( const QCString &msg, const QByteArray &data) { QDataStream stream( data, IO_ReadOnly ); if ( msg == "closing(QString)" ){ QString app; stream >> app; qWarning("app closed %s", app.latin1() ); MRUList::removeTask( app ); }else if ( msg == "linkChanged(QString)" ) { QString link; stream >> link; if ( in_lnk_props ) { got_lnk_change = TRUE; lnk_change = link; } else { updateLink(link); } } else if ( msg == "busy()" ) { emit busy(); } else if ( msg == "notBusy(QString)" ) { QString app; stream >> app; tabs->setBusy(FALSE); emit notBusy(app); } else if ( msg == "mkdir(QString)" ) { QString dir; stream >> dir; if ( !dir.isEmpty() ) mkdir( dir ); } else if ( msg == "rdiffGenSig(QString,QString)" ) { QString baseFile, sigFile; |