summaryrefslogtreecommitdiff
path: root/core/launcher/launcherview.cpp
Unidiff
Diffstat (limited to 'core/launcher/launcherview.cpp') (more/less context) (show 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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#include "launcherview.h"
22
23#include <qpe/qpeapplication.h>
24#include <qpe/applnk.h>
25#include <qpe/qpedebug.h>
26#include <qpe/categories.h>
27#include <qpe/categoryselect.h>
28#include <qpe/menubutton.h>
29#include <qpe/resource.h>
30#include <qpe/qpetoolbar.h>
31
32#include <qtimer.h>
33#include <qdict.h>
34#include <qfile.h>
35#include <qfileinfo.h>
36#include <qhbox.h>
37#include <qiconview.h>
38#include <qpainter.h>
39#include <qregexp.h>
40#include <qtoolbutton.h>
41
42class LauncherIconView : public QIconView {
43public:
44 LauncherIconView( QWidget* parent, const char* name=0 ) :
45 QIconView(parent,name),
46 tf(""),
47 cf(0),
48 bsy(0)
49 {
50 sortmeth = Name;
51 hidden.setAutoDelete(TRUE);
52 ike = FALSE;
53 }
54
55 ~LauncherIconView()
56 {
57#if 0 // debuggery
58 QListIterator<AppLnk> it(hidden);
59 AppLnk* l;
60 while ((l=it.current())) {
61 ++it;
62 //qDebug("%p: hidden (should remove)",l);
63 }
64#endif
65 }
66
67 QIconViewItem* busyItem() const { return bsy; }
68
69 void updateCategoriesAndMimeTypes();
70
71 void doAutoScroll()
72 {
73 // We don't want rubberbanding (yet)
74 }
75
76 void setBusy(bool on)
77 {
78 QIconViewItem *c = on ? currentItem() : 0;
79 if ( bsy != c ) {
80 QIconViewItem* o = bsy;
81 bsy = c;
82 if ( o ) o->repaint();
83 if ( c ) c->repaint();
84 }
85 }
86
87 bool inKeyEvent() const { return ike; }
88 void keyPressEvent(QKeyEvent* e)
89 {
90 ike = TRUE;
91 if ( e->key() == Key_F33 ) {
92 // "OK" button
93 returnPressed(currentItem());
94 }
95 QIconView::keyPressEvent(e);
96 ike = FALSE;
97 }
98
99 void addItem(AppLnk* app, bool resort=TRUE);
100 bool removeLink(const QString& linkfile);
101
102 QStringList mimeTypes() const;
103 QStringList categories() const;
104
105 void clear()
106 {
107 mimes.clear();
108 cats.clear();
109 QIconView::clear();
110 hidden.clear();
111 }
112
113 void addCatsAndMimes(AppLnk* app)
114 {
115 // QStringList c = app->categories();
116 // for (QStringList::ConstIterator cit=c.begin(); cit!=c.end(); ++cit) {
117 // cats.replace(*cit,(void*)1);
118 // }
119 QString maj=app->type();
120 int sl=maj.find('/');
121 if (sl>=0) {
122 QString k = maj.left(sl);
123 mimes.replace(k,(void*)1);
124 }
125 }
126
127 void drawBackground( QPainter *p, const QRect &r )
128 {
129 //int backgroundMode = QPixmap::defaultDepth() >= 12 ? 1 : 0;
130 int backgroundMode = 2;
131
132 if ( backgroundMode == 1 ) {
133
134 // Double buffer the background
135 static QPixmap *bg = NULL;
136 static QColor bgColor;
137
138 if ( (bg == NULL) || (bgColor != colorGroup().button()) ) {
139 // Create a new background double buffer
140 if (bg == NULL)
141 bg = new QPixmap( width(), height() );
142 bgColor = colorGroup().button();
143 QPainter painter( bg );
144
145 painter.fillRect( QRect( 0, 0, width(), height() ), QBrush( white ) );
146
147 // Overlay the Qtopia logo in the center
148 QImage logo = Resource::loadImage( "qpe-logo" );
149 if ( !logo.isNull() )
150 painter.drawImage( (width() - logo.width()) / 2,
151 (height() - logo.height()) / 2, logo );
152 }
153
154 // Draw the double buffer to the widget (it is tiled for when the icon view is large)
155 p->drawTiledPixmap( r, *bg, QPoint( (r.x() + contentsX()) % bg->width(),
156 (r.y() + contentsY()) % bg->height() ) );
157 } else if ( backgroundMode == 2 ) {
158 static QPixmap *bg = 0;
159 static QColor bgColor;
160 if ( !bg || (bgColor != colorGroup().background()) ) {
161 bgColor = colorGroup().background();
162 bg = new QPixmap( width(), 9 );
163 QPainter painter( bg );
164 for ( int i = 0; i < 3; i++ ) {
165 painter.setPen( white );
166 painter.drawLine( 0, i*3, width()-1, i*3 );
167 painter.drawLine( 0, i*3+1, width()-1, i*3+1 );
168 painter.setPen( colorGroup().background().light(105) );
169 painter.drawLine( 0, i*3+2, width()-1, i*3+2 );
170 }
171 }
172 p->drawTiledPixmap( r, *bg, QPoint( (r.x() + contentsX()) % bg->width(),
173 (r.y() + contentsY()) % bg->height() ) );
174 } else {
175 p->fillRect( r, QBrush( white ) );
176 }
177 }
178
179 void hideOrShowItems(bool resort);
180
181 void setTypeFilter(const QString& typefilter, bool resort)
182 {
183 tf = QRegExp(typefilter,FALSE,TRUE);
184 hideOrShowItems(resort);
185 }
186
187 void setCategoryFilter( int catfilter, bool resort )
188 {
189 Categories cat;
190 cat.load( categoryFileName() );
191 QString str;
192 if ( catfilter == -2 )
193 cf = 0;
194 else
195 cf = catfilter;
196 hideOrShowItems(resort);
197 }
198
199 enum SortMethod { Name, Date, Type };
200
201 void setSortMethod( SortMethod m )
202 {
203 if ( sortmeth != m ) {
204 sortmeth = m;
205 sort();
206 }
207 }
208
209 int compare(const AppLnk* a, const AppLnk* b)
210 {
211 switch (sortmeth) {
212 case Name:
213 return a->name().compare(b->name());
214 case Date: {
215 QFileInfo fa(a->linkFile());
216 if ( !fa.exists() ) fa.setFile(a->file());
217 QFileInfo fb(b->linkFile());
218 if ( !fb.exists() ) fb.setFile(b->file());
219 return fa.lastModified().secsTo(fb.lastModified());
220 }
221 case Type:
222 return a->type().compare(b->type());
223 }
224 return 0;
225 }
226
227protected:
228
229 void styleChange( QStyle &old )
230 {
231 QIconView::styleChange( old );
232 //### duplicated code from LauncherView constructor
233 int dw = QApplication::desktop()->width();
234 setGridX( (dw-13-style().scrollBarExtent().width())/3 ); // tweaked for 8pt+dw=176 and 10pt+dw=240
235 }
236
237private:
238 QList<AppLnk> hidden;
239 QDict<void> mimes;
240 QDict<void> cats;
241 SortMethod sortmeth;
242 QRegExp tf;
243 int cf;
244 QIconViewItem* bsy;
245 bool ike;
246
247};
248
249
250bool LauncherView::bsy=FALSE;
251
252void LauncherView::setBusy(bool on)
253{
254 icons->setBusy(on);
255}
256
257class LauncherItem : public QIconViewItem
258{
259public:
260 LauncherItem( QIconView *parent, AppLnk* applnk );
261 ~LauncherItem()
262 {
263 LauncherIconView* liv = (LauncherIconView*)iconView();
264 if ( liv->busyItem() == this )
265 liv->setBusy(FALSE);
266 delete app;
267 }
268
269 AppLnk* appLnk() const { return app; }
270 AppLnk* takeAppLnk() { AppLnk* r=app; app=0; return r; }
271
272 virtual int compare ( QIconViewItem * i ) const;
273
274 void paintItem( QPainter *p, const QColorGroup &cg )
275 {
276 LauncherIconView* liv = (LauncherIconView*)iconView();
277 QBrush oldBrush( liv->itemTextBackground() );
278 QColorGroup mycg( cg );
279 if ( liv->currentItem() == this ) {
280 liv->setItemTextBackground( cg.brush( QColorGroup::Highlight ) );
281 mycg.setColor( QColorGroup::Text, cg.color( QColorGroup::HighlightedText ) );
282 }
283 QIconViewItem::paintItem(p,mycg);
284 if ( liv->currentItem() == this )
285 liv->setItemTextBackground( oldBrush );
286 if ( liv->busyItem() == this ) {
287 static QPixmap* busypm=0;
288 if ( !busypm )
289 busypm = new QPixmap(Resource::loadPixmap("launching"));
290 p->drawPixmap(x()+(width()-busypm->width())/2, y(),*busypm);
291 }
292 }
293
294protected:
295 AppLnk* app;
296};
297
298
299LauncherItem::LauncherItem( QIconView *parent, AppLnk *applnk )
300 : QIconViewItem( parent, applnk->name(), applnk->bigPixmap() ),
301 app(applnk) // Takes ownership
302{
303}
304
305int LauncherItem::compare ( QIconViewItem * i ) const
306{
307 LauncherIconView* view = (LauncherIconView*)iconView();
308 return view->compare(app,((LauncherItem *)i)->appLnk());
309}
310
311QStringList LauncherIconView::mimeTypes() const
312{
313 QStringList r;
314 QDictIterator<void> it(mimes);
315 while (it.current()) {
316 r.append(it.currentKey());
317 ++it;
318 }
319 r.sort();
320 return r;
321}
322
323void LauncherIconView::addItem(AppLnk* app, bool resort)
324{
325 addCatsAndMimes(app);
326
327 if ( (tf.isEmpty() || tf.match(app->type()) >= 0)
328 && (cf == 0 || app->categories().contains(cf)
329 || cf == -1 && app->categories().count() == 0 ) )
330 (void) new LauncherItem( this, app );
331 else
332 hidden.append(app);
333 if ( resort )
334 sort();
335}
336
337void LauncherIconView::updateCategoriesAndMimeTypes()
338{
339 mimes.clear();
340 cats.clear();
341 LauncherItem* item = (LauncherItem*)firstItem();
342 while (item) {
343 addCatsAndMimes(item->appLnk());
344 item = (LauncherItem*)item->nextItem();
345 }
346 QListIterator<AppLnk> it(hidden);
347 AppLnk* l;
348 while ((l=it.current())) {
349 addCatsAndMimes(l);
350 ++it;
351 }
352}
353
354void LauncherIconView::hideOrShowItems(bool resort)
355{
356 hidden.setAutoDelete(FALSE);
357 QList<AppLnk> links=hidden;
358 hidden.clear();
359 hidden.setAutoDelete(TRUE);
360 LauncherItem* item = (LauncherItem*)firstItem();
361 while (item) {
362 links.append(item->takeAppLnk());
363 item = (LauncherItem*)item->nextItem();
364 }
365 clear();
366 QListIterator<AppLnk> it(links);
367 AppLnk* l;
368 while ((l=it.current())) {
369 addItem(l,FALSE);
370 ++it;
371 }
372 if ( resort )
373 sort();
374}
375
376bool LauncherIconView::removeLink(const QString& linkfile)
377{
378 LauncherItem* item = (LauncherItem*)firstItem();
379 while (item) {
380 if ( item->appLnk()->linkFile() == linkfile ) {
381 delete item;
382 return TRUE;
383 }
384 item = (LauncherItem*)item->nextItem();
385 }
386 QListIterator<AppLnk> it(hidden);
387 AppLnk* l;
388 while ((l=it.current())) {
389 ++it;
390 if ( l->linkFile() == linkfile ) {
391 hidden.removeRef(l);
392 return TRUE;
393 }
394 }
395 return FALSE;
396}
397
398LauncherView::LauncherView( QWidget* parent, const char* name, WFlags fl )
399 : QVBox( parent, name, fl )
400{
401 icons = new LauncherIconView( this );
402 setFocusProxy(icons);
403 QPEApplication::setStylusOperation( icons->viewport(), QPEApplication::RightOnHold );
404
405 int dw = QApplication::desktop()->width();
406 icons->setItemsMovable( FALSE );
407 icons->setAutoArrange( TRUE );
408 icons->setSorting( TRUE );
409 icons->setGridX( (dw-13-style().scrollBarExtent().width())/3 ); // tweaked for 8pt+dw=176 and 10pt+dw=240
410 icons->setGridY( fontMetrics().height()*2+24 );
411 icons->setFrameStyle( QFrame::NoFrame );
412 icons->setSpacing( 4 );
413 icons->setMargin( 0 );
414 icons->setSelectionMode( QIconView::Multi );
415 icons->setBackgroundMode( PaletteBase );
416
417 connect( icons, SIGNAL(mouseButtonClicked(int, QIconViewItem *, const QPoint&)),
418 SLOT(itemClicked(int, QIconViewItem *)) );
419 connect( icons, SIGNAL(selectionChanged()),
420 SLOT(selectionChanged()) );
421 connect( icons, SIGNAL(returnPressed(QIconViewItem *)),
422 SLOT(returnPressed(QIconViewItem *)) );
423 connect( icons, SIGNAL(mouseButtonPressed(int, QIconViewItem *, const QPoint&)),
424 SLOT(itemPressed(int, QIconViewItem *)) );
425
426 tools = 0;
427}
428
429LauncherView::~LauncherView()
430{
431}
432
433void LauncherView::setToolsEnabled(bool y)
434{
435 if ( !y != !tools ) {
436 if ( y ) {
437 tools = new QHBox(this);
438
439 // Type filter
440 typemb = new MenuButton(tools);
441 typemb->setLabel(tr("Type: %1"));
442
443 // Category filter
444 catmb = new CategorySelect(tools);
445
446 updateTools();
447 tools->show();
448 } else {
449 delete tools;
450 tools = 0;
451 }
452 }
453}
454
455void LauncherView::updateTools()
456{
457 disconnect( typemb, SIGNAL(selected(const QString&)),
458 this, SLOT(showType(const QString&)) );
459 disconnect( catmb, SIGNAL(signalSelected(int)),
460 this, SLOT(showCategory(int)) );
461
462 icons->updateCategoriesAndMimeTypes();
463
464 QString prev;
465
466 // Type filter
467 QStringList types;
468 types << tr("All");
469 types << "--";
470 types += icons->mimeTypes();
471 prev = typemb->currentText();
472 typemb->clear();
473 typemb->insertItems(types);
474 typemb->select(prev);
475
476 Categories cats( 0 );
477 cats.load( categoryFileName() );
478 QArray<int> vl( 0 );
479 catmb->setCategories( vl, "Document View", tr("Document View") );
480 catmb->setRemoveCategoryEdit( TRUE );
481 catmb->setAllCategories( TRUE );
482
483 connect(typemb, SIGNAL(selected(const QString&)), this, SLOT(showType(const QString&)));
484 connect(catmb, SIGNAL(signalSelected(int)), this, SLOT(showCategory(int)));
485}
486
487void LauncherView::sortBy(int s)
488{
489 icons->setSortMethod((LauncherIconView::SortMethod)s);
490}
491
492void LauncherView::showType(const QString& t)
493{
494 if ( t == tr("All") ) {
495 icons->setTypeFilter("",TRUE);
496 } else {
497 icons->setTypeFilter(t+"/*",TRUE);
498 }
499}
500
501void LauncherView::showCategory( int c )
502{
503 icons->setCategoryFilter( c, TRUE );
504}
505
506void LauncherView::resizeEvent(QResizeEvent *e)
507{
508 QVBox::resizeEvent( e );
509 if ( e->size().width() != e->oldSize().width() )
510 sort();
511}
512
513void LauncherView::populate( AppLnkSet *folder, const QString& typefilter )
514{
515 icons->clear();
516 internalPopulate( folder, typefilter );
517}
518
519void LauncherView::selectionChanged()
520{
521 QIconViewItem* item = icons->currentItem();
522 if ( item && item->isSelected() ) {
523 AppLnk *appLnk = ((LauncherItem *)item)->appLnk();
524 if ( icons->inKeyEvent() ) // not for mouse press
525 emit clicked( appLnk );
526 item->setSelected(FALSE);
527 }
528}
529
530void LauncherView::returnPressed( QIconViewItem *item )
531{
532 if ( item ) {
533 AppLnk *appLnk = ((LauncherItem *)item)->appLnk();
534 emit clicked( appLnk );
535 }
536}
537
538void LauncherView::itemClicked( int btn, QIconViewItem *item )
539{
540 if ( item ) {
541 AppLnk *appLnk = ((LauncherItem *)item)->appLnk();
542 if ( btn == LeftButton ) {
543 // Make sure it's the item we execute that gets highlighted
544 icons->setCurrentItem( item );
545 emit clicked( appLnk );
546 }
547 item->setSelected(FALSE);
548 }
549}
550
551void LauncherView::itemPressed( int btn, QIconViewItem *item )
552{
553 if ( item ) {
554 AppLnk *appLnk = ((LauncherItem *)item)->appLnk();
555 if ( btn == RightButton )
556 emit rightPressed( appLnk );
557/*
558 else if ( btn == LeftButton )
559 emit clicked( appLnk );
560*/
561 item->setSelected(FALSE);
562 }
563}
564
565void LauncherView::internalPopulate( AppLnkSet *folder, const QString& typefilter )
566{
567 QListIterator<AppLnk> it( folder->children() );
568 icons->setTypeFilter(typefilter,FALSE);
569
570 while ( it.current() ) {
571 icons->addItem(*it,FALSE);
572 ++it;
573 }
574
575 icons->sort();
576}
577
578bool LauncherView::removeLink(const QString& linkfile)
579{
580 return icons->removeLink(linkfile);
581}
582
583void LauncherView::sort()
584{
585 icons->sort();
586}
587
588void LauncherView::addItem(AppLnk* app, bool resort)
589{
590 icons->addItem(app,resort);
591}
592
593void LauncherView::setFileSystems(const QList<FileSystem> &)
594{
595 // ### does nothing now...
596}