summaryrefslogtreecommitdiff
path: root/core/launcher/launcherview.cpp
Side-by-side diff
Diffstat (limited to 'core/launcher/launcherview.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--core/launcher/launcherview.cpp596
1 files changed, 596 insertions, 0 deletions
diff --git a/core/launcher/launcherview.cpp b/core/launcher/launcherview.cpp
new file mode 100644
index 0000000..68e3245
--- a/dev/null
+++ b/core/launcher/launcherview.cpp
@@ -0,0 +1,596 @@
+/**********************************************************************
+** 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.
+**
+**********************************************************************/
+
+#include "launcherview.h"
+
+#include <qpe/qpeapplication.h>
+#include <qpe/applnk.h>
+#include <qpe/qpedebug.h>
+#include <qpe/categories.h>
+#include <qpe/categoryselect.h>
+#include <qpe/menubutton.h>
+#include <qpe/resource.h>
+#include <qpe/qpetoolbar.h>
+
+#include <qtimer.h>
+#include <qdict.h>
+#include <qfile.h>
+#include <qfileinfo.h>
+#include <qhbox.h>
+#include <qiconview.h>
+#include <qpainter.h>
+#include <qregexp.h>
+#include <qtoolbutton.h>
+
+class LauncherIconView : public QIconView {
+public:
+ LauncherIconView( QWidget* parent, const char* name=0 ) :
+ QIconView(parent,name),
+ tf(""),
+ cf(0),
+ bsy(0)
+ {
+ sortmeth = Name;
+ hidden.setAutoDelete(TRUE);
+ ike = FALSE;
+ }
+
+ ~LauncherIconView()
+ {
+#if 0 // debuggery
+ QListIterator<AppLnk> it(hidden);
+ AppLnk* l;
+ while ((l=it.current())) {
+ ++it;
+ //qDebug("%p: hidden (should remove)",l);
+ }
+#endif
+ }
+
+ QIconViewItem* busyItem() const { return bsy; }
+
+ void updateCategoriesAndMimeTypes();
+
+ void doAutoScroll()
+ {
+ // We don't want rubberbanding (yet)
+ }
+
+ void setBusy(bool on)
+ {
+ QIconViewItem *c = on ? currentItem() : 0;
+ if ( bsy != c ) {
+ QIconViewItem* o = bsy;
+ bsy = c;
+ if ( o ) o->repaint();
+ if ( c ) c->repaint();
+ }
+ }
+
+ bool inKeyEvent() const { return ike; }
+ void keyPressEvent(QKeyEvent* e)
+ {
+ ike = TRUE;
+ if ( e->key() == Key_F33 ) {
+ // "OK" button
+ returnPressed(currentItem());
+ }
+ QIconView::keyPressEvent(e);
+ ike = FALSE;
+ }
+
+ void addItem(AppLnk* app, bool resort=TRUE);
+ bool removeLink(const QString& linkfile);
+
+ QStringList mimeTypes() const;
+ QStringList categories() const;
+
+ void clear()
+ {
+ mimes.clear();
+ cats.clear();
+ QIconView::clear();
+ hidden.clear();
+ }
+
+ void addCatsAndMimes(AppLnk* app)
+ {
+ // QStringList c = app->categories();
+ // for (QStringList::ConstIterator cit=c.begin(); cit!=c.end(); ++cit) {
+ // cats.replace(*cit,(void*)1);
+ // }
+ QString maj=app->type();
+ int sl=maj.find('/');
+ if (sl>=0) {
+ QString k = maj.left(sl);
+ mimes.replace(k,(void*)1);
+ }
+ }
+
+ void drawBackground( QPainter *p, const QRect &r )
+ {
+ // int backgroundMode = QPixmap::defaultDepth() >= 12 ? 1 : 0;
+ int backgroundMode = 2;
+
+ if ( backgroundMode == 1 ) {
+
+ // Double buffer the background
+ static QPixmap *bg = NULL;
+ static QColor bgColor;
+
+ if ( (bg == NULL) || (bgColor != colorGroup().button()) ) {
+ // Create a new background double buffer
+ if (bg == NULL)
+ bg = new QPixmap( width(), height() );
+ bgColor = colorGroup().button();
+ QPainter painter( bg );
+
+ painter.fillRect( QRect( 0, 0, width(), height() ), QBrush( white ) );
+
+ // Overlay the Qtopia logo in the center
+ QImage logo = Resource::loadImage( "qpe-logo" );
+ if ( !logo.isNull() )
+ painter.drawImage( (width() - logo.width()) / 2,
+ (height() - logo.height()) / 2, logo );
+ }
+
+ // Draw the double buffer to the widget (it is tiled for when the icon view is large)
+ p->drawTiledPixmap( r, *bg, QPoint( (r.x() + contentsX()) % bg->width(),
+ (r.y() + contentsY()) % bg->height() ) );
+ } else if ( backgroundMode == 2 ) {
+ static QPixmap *bg = 0;
+ static QColor bgColor;
+ if ( !bg || (bgColor != colorGroup().background()) ) {
+ bgColor = colorGroup().background();
+ bg = new QPixmap( width(), 9 );
+ QPainter painter( bg );
+ for ( int i = 0; i < 3; i++ ) {
+ painter.setPen( white );
+ painter.drawLine( 0, i*3, width()-1, i*3 );
+ painter.drawLine( 0, i*3+1, width()-1, i*3+1 );
+ painter.setPen( colorGroup().background().light(105) );
+ painter.drawLine( 0, i*3+2, width()-1, i*3+2 );
+ }
+ }
+ p->drawTiledPixmap( r, *bg, QPoint( (r.x() + contentsX()) % bg->width(),
+ (r.y() + contentsY()) % bg->height() ) );
+ } else {
+ p->fillRect( r, QBrush( white ) );
+ }
+ }
+
+ void hideOrShowItems(bool resort);
+
+ void setTypeFilter(const QString& typefilter, bool resort)
+ {
+ tf = QRegExp(typefilter,FALSE,TRUE);
+ hideOrShowItems(resort);
+ }
+
+ void setCategoryFilter( int catfilter, bool resort )
+ {
+ Categories cat;
+ cat.load( categoryFileName() );
+ QString str;
+ if ( catfilter == -2 )
+ cf = 0;
+ else
+ cf = catfilter;
+ hideOrShowItems(resort);
+ }
+
+ enum SortMethod { Name, Date, Type };
+
+ void setSortMethod( SortMethod m )
+ {
+ if ( sortmeth != m ) {
+ sortmeth = m;
+ sort();
+ }
+ }
+
+ int compare(const AppLnk* a, const AppLnk* b)
+ {
+ switch (sortmeth) {
+ case Name:
+ return a->name().compare(b->name());
+ case Date: {
+ QFileInfo fa(a->linkFile());
+ if ( !fa.exists() ) fa.setFile(a->file());
+ QFileInfo fb(b->linkFile());
+ if ( !fb.exists() ) fb.setFile(b->file());
+ return fa.lastModified().secsTo(fb.lastModified());
+ }
+ case Type:
+ return a->type().compare(b->type());
+ }
+ return 0;
+ }
+
+protected:
+
+ void styleChange( QStyle &old )
+ {
+ QIconView::styleChange( old );
+ //### duplicated code from LauncherView constructor
+ int dw = QApplication::desktop()->width();
+ setGridX( (dw-13-style().scrollBarExtent().width())/3 ); // tweaked for 8pt+dw=176 and 10pt+dw=240
+ }
+
+private:
+ QList<AppLnk> hidden;
+ QDict<void> mimes;
+ QDict<void> cats;
+ SortMethod sortmeth;
+ QRegExp tf;
+ int cf;
+ QIconViewItem* bsy;
+ bool ike;
+
+};
+
+
+bool LauncherView::bsy=FALSE;
+
+void LauncherView::setBusy(bool on)
+{
+ icons->setBusy(on);
+}
+
+class LauncherItem : public QIconViewItem
+{
+public:
+ LauncherItem( QIconView *parent, AppLnk* applnk );
+ ~LauncherItem()
+ {
+ LauncherIconView* liv = (LauncherIconView*)iconView();
+ if ( liv->busyItem() == this )
+ liv->setBusy(FALSE);
+ delete app;
+ }
+
+ AppLnk* appLnk() const { return app; }
+ AppLnk* takeAppLnk() { AppLnk* r=app; app=0; return r; }
+
+ virtual int compare ( QIconViewItem * i ) const;
+
+ void paintItem( QPainter *p, const QColorGroup &cg )
+ {
+ LauncherIconView* liv = (LauncherIconView*)iconView();
+ QBrush oldBrush( liv->itemTextBackground() );
+ QColorGroup mycg( cg );
+ if ( liv->currentItem() == this ) {
+ liv->setItemTextBackground( cg.brush( QColorGroup::Highlight ) );
+ mycg.setColor( QColorGroup::Text, cg.color( QColorGroup::HighlightedText ) );
+ }
+ QIconViewItem::paintItem(p,mycg);
+ if ( liv->currentItem() == this )
+ liv->setItemTextBackground( oldBrush );
+ if ( liv->busyItem() == this ) {
+ static QPixmap* busypm=0;
+ if ( !busypm )
+ busypm = new QPixmap(Resource::loadPixmap("launching"));
+ p->drawPixmap(x()+(width()-busypm->width())/2, y(),*busypm);
+ }
+ }
+
+protected:
+ AppLnk* app;
+};
+
+
+LauncherItem::LauncherItem( QIconView *parent, AppLnk *applnk )
+ : QIconViewItem( parent, applnk->name(), applnk->bigPixmap() ),
+ app(applnk) // Takes ownership
+{
+}
+
+int LauncherItem::compare ( QIconViewItem * i ) const
+{
+ LauncherIconView* view = (LauncherIconView*)iconView();
+ return view->compare(app,((LauncherItem *)i)->appLnk());
+}
+
+QStringList LauncherIconView::mimeTypes() const
+{
+ QStringList r;
+ QDictIterator<void> it(mimes);
+ while (it.current()) {
+ r.append(it.currentKey());
+ ++it;
+ }
+ r.sort();
+ return r;
+}
+
+void LauncherIconView::addItem(AppLnk* app, bool resort)
+{
+ addCatsAndMimes(app);
+
+ if ( (tf.isEmpty() || tf.match(app->type()) >= 0)
+ && (cf == 0 || app->categories().contains(cf)
+ || cf == -1 && app->categories().count() == 0 ) )
+ (void) new LauncherItem( this, app );
+ else
+ hidden.append(app);
+ if ( resort )
+ sort();
+}
+
+void LauncherIconView::updateCategoriesAndMimeTypes()
+{
+ mimes.clear();
+ cats.clear();
+ LauncherItem* item = (LauncherItem*)firstItem();
+ while (item) {
+ addCatsAndMimes(item->appLnk());
+ item = (LauncherItem*)item->nextItem();
+ }
+ QListIterator<AppLnk> it(hidden);
+ AppLnk* l;
+ while ((l=it.current())) {
+ addCatsAndMimes(l);
+ ++it;
+ }
+}
+
+void LauncherIconView::hideOrShowItems(bool resort)
+{
+ hidden.setAutoDelete(FALSE);
+ QList<AppLnk> links=hidden;
+ hidden.clear();
+ hidden.setAutoDelete(TRUE);
+ LauncherItem* item = (LauncherItem*)firstItem();
+ while (item) {
+ links.append(item->takeAppLnk());
+ item = (LauncherItem*)item->nextItem();
+ }
+ clear();
+ QListIterator<AppLnk> it(links);
+ AppLnk* l;
+ while ((l=it.current())) {
+ addItem(l,FALSE);
+ ++it;
+ }
+ if ( resort )
+ sort();
+}
+
+bool LauncherIconView::removeLink(const QString& linkfile)
+{
+ LauncherItem* item = (LauncherItem*)firstItem();
+ while (item) {
+ if ( item->appLnk()->linkFile() == linkfile ) {
+ delete item;
+ return TRUE;
+ }
+ item = (LauncherItem*)item->nextItem();
+ }
+ QListIterator<AppLnk> it(hidden);
+ AppLnk* l;
+ while ((l=it.current())) {
+ ++it;
+ if ( l->linkFile() == linkfile ) {
+ hidden.removeRef(l);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+LauncherView::LauncherView( QWidget* parent, const char* name, WFlags fl )
+ : QVBox( parent, name, fl )
+{
+ icons = new LauncherIconView( this );
+ setFocusProxy(icons);
+ QPEApplication::setStylusOperation( icons->viewport(), QPEApplication::RightOnHold );
+
+ int dw = QApplication::desktop()->width();
+ icons->setItemsMovable( FALSE );
+ icons->setAutoArrange( TRUE );
+ icons->setSorting( TRUE );
+ icons->setGridX( (dw-13-style().scrollBarExtent().width())/3 ); // tweaked for 8pt+dw=176 and 10pt+dw=240
+ icons->setGridY( fontMetrics().height()*2+24 );
+ icons->setFrameStyle( QFrame::NoFrame );
+ icons->setSpacing( 4 );
+ icons->setMargin( 0 );
+ icons->setSelectionMode( QIconView::Multi );
+ icons->setBackgroundMode( PaletteBase );
+
+ connect( icons, SIGNAL(mouseButtonClicked(int, QIconViewItem *, const QPoint&)),
+ SLOT(itemClicked(int, QIconViewItem *)) );
+ connect( icons, SIGNAL(selectionChanged()),
+ SLOT(selectionChanged()) );
+ connect( icons, SIGNAL(returnPressed(QIconViewItem *)),
+ SLOT(returnPressed(QIconViewItem *)) );
+ connect( icons, SIGNAL(mouseButtonPressed(int, QIconViewItem *, const QPoint&)),
+ SLOT(itemPressed(int, QIconViewItem *)) );
+
+ tools = 0;
+}
+
+LauncherView::~LauncherView()
+{
+}
+
+void LauncherView::setToolsEnabled(bool y)
+{
+ if ( !y != !tools ) {
+ if ( y ) {
+ tools = new QHBox(this);
+
+ // Type filter
+ typemb = new MenuButton(tools);
+ typemb->setLabel(tr("Type: %1"));
+
+ // Category filter
+ catmb = new CategorySelect(tools);
+
+ updateTools();
+ tools->show();
+ } else {
+ delete tools;
+ tools = 0;
+ }
+ }
+}
+
+void LauncherView::updateTools()
+{
+ disconnect( typemb, SIGNAL(selected(const QString&)),
+ this, SLOT(showType(const QString&)) );
+ disconnect( catmb, SIGNAL(signalSelected(int)),
+ this, SLOT(showCategory(int)) );
+
+ icons->updateCategoriesAndMimeTypes();
+
+ QString prev;
+
+ // Type filter
+ QStringList types;
+ types << tr("All");
+ types << "--";
+ types += icons->mimeTypes();
+ prev = typemb->currentText();
+ typemb->clear();
+ typemb->insertItems(types);
+ typemb->select(prev);
+
+ Categories cats( 0 );
+ cats.load( categoryFileName() );
+ QArray<int> vl( 0 );
+ catmb->setCategories( vl, "Document View", tr("Document View") );
+ catmb->setRemoveCategoryEdit( TRUE );
+ catmb->setAllCategories( TRUE );
+
+ connect(typemb, SIGNAL(selected(const QString&)), this, SLOT(showType(const QString&)));
+ connect(catmb, SIGNAL(signalSelected(int)), this, SLOT(showCategory(int)));
+}
+
+void LauncherView::sortBy(int s)
+{
+ icons->setSortMethod((LauncherIconView::SortMethod)s);
+}
+
+void LauncherView::showType(const QString& t)
+{
+ if ( t == tr("All") ) {
+ icons->setTypeFilter("",TRUE);
+ } else {
+ icons->setTypeFilter(t+"/*",TRUE);
+ }
+}
+
+void LauncherView::showCategory( int c )
+{
+ icons->setCategoryFilter( c, TRUE );
+}
+
+void LauncherView::resizeEvent(QResizeEvent *e)
+{
+ QVBox::resizeEvent( e );
+ if ( e->size().width() != e->oldSize().width() )
+ sort();
+}
+
+void LauncherView::populate( AppLnkSet *folder, const QString& typefilter )
+{
+ icons->clear();
+ internalPopulate( folder, typefilter );
+}
+
+void LauncherView::selectionChanged()
+{
+ QIconViewItem* item = icons->currentItem();
+ if ( item && item->isSelected() ) {
+ AppLnk *appLnk = ((LauncherItem *)item)->appLnk();
+ if ( icons->inKeyEvent() ) // not for mouse press
+ emit clicked( appLnk );
+ item->setSelected(FALSE);
+ }
+}
+
+void LauncherView::returnPressed( QIconViewItem *item )
+{
+ if ( item ) {
+ AppLnk *appLnk = ((LauncherItem *)item)->appLnk();
+ emit clicked( appLnk );
+ }
+}
+
+void LauncherView::itemClicked( int btn, QIconViewItem *item )
+{
+ if ( item ) {
+ AppLnk *appLnk = ((LauncherItem *)item)->appLnk();
+ if ( btn == LeftButton ) {
+ // Make sure it's the item we execute that gets highlighted
+ icons->setCurrentItem( item );
+ emit clicked( appLnk );
+ }
+ item->setSelected(FALSE);
+ }
+}
+
+void LauncherView::itemPressed( int btn, QIconViewItem *item )
+{
+ if ( item ) {
+ AppLnk *appLnk = ((LauncherItem *)item)->appLnk();
+ if ( btn == RightButton )
+ emit rightPressed( appLnk );
+/*
+ else if ( btn == LeftButton )
+ emit clicked( appLnk );
+*/
+ item->setSelected(FALSE);
+ }
+}
+
+void LauncherView::internalPopulate( AppLnkSet *folder, const QString& typefilter )
+{
+ QListIterator<AppLnk> it( folder->children() );
+ icons->setTypeFilter(typefilter,FALSE);
+
+ while ( it.current() ) {
+ icons->addItem(*it,FALSE);
+ ++it;
+ }
+
+ icons->sort();
+}
+
+bool LauncherView::removeLink(const QString& linkfile)
+{
+ return icons->removeLink(linkfile);
+}
+
+void LauncherView::sort()
+{
+ icons->sort();
+}
+
+void LauncherView::addItem(AppLnk* app, bool resort)
+{
+ icons->addItem(app,resort);
+}
+
+void LauncherView::setFileSystems(const QList<FileSystem> &)
+{
+ // ### does nothing now...
+}