summaryrefslogtreecommitdiff
path: root/core/launcher/launcherview.cpp
authorzecke <zecke>2003-08-28 14:37:27 (UTC)
committer zecke <zecke>2003-08-28 14:37:27 (UTC)
commit245dcac2f79d7409f80da37f9c6c47fff70dc949 (patch) (unidiff)
treeaa5401e3cea0453da32f6062dba6ac454a3457ae /core/launcher/launcherview.cpp
parentf837944e9a404c46efc00e4d5851ea13dbb88ef2 (diff)
downloadopie-245dcac2f79d7409f80da37f9c6c47fff70dc949.zip
opie-245dcac2f79d7409f80da37f9c6c47fff70dc949.tar.gz
opie-245dcac2f79d7409f80da37f9c6c47fff70dc949.tar.bz2
-Make it compile
-apply Opie patches -prepare BusyIndicator changes -add QCOP method for showing the desktop and going to the next tab
Diffstat (limited to 'core/launcher/launcherview.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--core/launcher/launcherview.cpp745
1 files changed, 412 insertions, 333 deletions
diff --git a/core/launcher/launcherview.cpp b/core/launcher/launcherview.cpp
index 7117e0b..85163b6 100644
--- a/core/launcher/launcherview.cpp
+++ b/core/launcher/launcherview.cpp
@@ -20,15 +20,15 @@
20 20
21#include "launcherview.h" 21#include "launcherview.h"
22 22
23#include <qpe/qpeapplication.h> 23#include <qtopia/qpeapplication.h>
24#include <qpe/applnk.h> 24#include <qtopia/applnk.h>
25#include <qpe/qpedebug.h> 25#include <qtopia/qpedebug.h>
26#include <qpe/categories.h> 26#include <qtopia/private/categories.h>
27#include <qpe/categoryselect.h> 27#include <qtopia/categoryselect.h>
28#include <qpe/menubutton.h> 28#include <qtopia/menubutton.h>
29#include <qpe/mimetype.h> 29#include <qtopia/mimetype.h>
30#include <qpe/resource.h> 30#include <qtopia/resource.h>
31#include <qpe/qpetoolbar.h> 31#include <qtopia/qpetoolbar.h>
32//#include <qtopia/private/palmtoprecord.h> 32//#include <qtopia/private/palmtoprecord.h>
33 33
34#include <qtimer.h> 34#include <qtimer.h>
@@ -38,12 +38,21 @@
38#include <qfileinfo.h> 38#include <qfileinfo.h>
39#include <qhbox.h> 39#include <qhbox.h>
40#include <qiconview.h> 40#include <qiconview.h>
41#include <qwidgetstack.h>
41#include <qpainter.h> 42#include <qpainter.h>
42#include <qregexp.h> 43#include <qregexp.h>
43#include <qtoolbutton.h> 44#include <qtoolbutton.h>
44#include <qimage.h> 45#include <qimage.h>
46#include <qlabel.h>
47#include <qobjectlist.h>
48
49
50// These define how the busy icon is animated and highlighted
51#define BRIGHTEN_BUSY_ICON
52//#define ALPHA_FADE_BUSY_ICON
53//#define USE_ANIMATED_BUSY_ICON_OVERLAY
54#define BOUNCE_BUSY_ICON
45 55
46#include <cstdlib>
47 56
48class BgPixmap 57class BgPixmap
49{ 58{
@@ -60,6 +69,43 @@ enum BusyIndicatorType {
60 69
61static QMap<QString,BgPixmap*> *bgCache = 0; 70static QMap<QString,BgPixmap*> *bgCache = 0;
62 71
72static void cleanup_cache()
73{
74 QMap<QString,BgPixmap*>::Iterator it = bgCache->begin();
75 while ( it != bgCache->end() ) {
76 QMap<QString,BgPixmap*>::Iterator curr = it;
77 ++it;
78 delete (*curr);
79 bgCache->remove( curr );
80 }
81 delete bgCache;
82 bgCache = 0;
83}
84
85
86class LauncherItem : public QIconViewItem
87{
88public:
89 LauncherItem( QIconView *parent, AppLnk* applnk, bool bigIcon=TRUE );
90 ~LauncherItem();
91
92 AppLnk *appLnk() const { return app; }
93 AppLnk *takeAppLnk() { AppLnk* r=app; app=0; return r; }
94
95 void animateIcon();
96 void resetIcon();
97
98 virtual int compare ( QIconViewItem * i ) const;
99 void paintItem( QPainter *p, const QColorGroup &cg );
100protected:
101 bool isBigIcon;
102 int iteration;
103 AppLnk* app;
104private:
105 void paintAnimatedIcon( QPainter *p );
106};
107
108
63class LauncherIconView : public QIconView { 109class LauncherIconView : public QIconView {
64public: 110public:
65 LauncherIconView( QWidget* parent, const char* name=0 ) : 111 LauncherIconView( QWidget* parent, const char* name=0 ) :
@@ -67,13 +113,13 @@ public:
67 tf(""), 113 tf(""),
68 cf(0), 114 cf(0),
69 bsy(0), 115 bsy(0),
116 busyTimer(0),
70 bigIcns(TRUE), 117 bigIcns(TRUE),
71 bgColor(white) 118 bgColor(white)
72 { 119 {
73 sortmeth = Name; 120 sortmeth = Name;
74 hidden.setAutoDelete(TRUE); 121 hidden.setAutoDelete(TRUE);
75 ike = FALSE; 122 ike = FALSE;
76 busytimer = 0;
77 calculateGrid( Bottom ); 123 calculateGrid( Bottom );
78 } 124 }
79 125
@@ -88,12 +134,17 @@ public:
88 } 134 }
89#endif 135#endif
90 } 136 }
91
92 void setBusyIndicatorType ( BusyIndicatorType t ) { busyType = t; }
93 137
94 QPixmap* busyPixmap() const { return (QPixmap*)&bpm[abs(busystate)]; }
95 QIconViewItem* busyItem() const { return bsy; } 138 QIconViewItem* busyItem() const { return bsy; }
96 void setBigIcons( bool bi ) { bigIcns = bi; } 139#ifdef USE_ANIMATED_BUSY_ICON_OVERLAY
140 QPixmap busyPixmap() const { return busyPix; }
141#endif
142 void setBigIcons( bool bi ) {
143 bigIcns = bi;
144#ifdef USE_ANIMATED_BUSY_ICON_OVERLAY
145 busyPix.resize(0,0);
146#endif
147 }
97 148
98 void updateCategoriesAndMimeTypes(); 149 void updateCategoriesAndMimeTypes();
99 150
@@ -104,73 +155,31 @@ public:
104 155
105 void setBusy(bool on) 156 void setBusy(bool on)
106 { 157 {
107 QIconViewItem *c = on ? currentItem() : 0; 158#ifdef USE_ANIMATED_BUSY_ICON_OVERLAY
108 159 if ( busyPix.isNull() ) {
109 if ( bsy != c ) { 160 int size = ( bigIcns ) ? AppLnk::bigIconSize() : AppLnk::smallIconSize();
110 QIconViewItem *oldbsy = bsy; 161 busyPix.convertFromImage( Resource::loadImage( "busy" ).smoothScale( size * 16, size ) );
111 bsy = c; 162 }
112 163#endif
113 if ( oldbsy )
114 oldbsy-> repaint ( );
115
116 if ( busytimer ) {
117 killTimer ( busytimer );
118 busytimer = 0;
119 }
120
121 if ( bsy ) {
122 QPixmap *src = bsy-> QIconViewItem::pixmap();
123 for ( int i = 0; i <= 5; i++ ) {
124 QImage img = src->convertToImage();
125 QRgb* rgb;
126 int count;
127 if ( img.depth() == 32 ) {
128 rgb = (QRgb*)img.bits();
129 count = img.bytesPerLine()/sizeof(QRgb)*img.height();
130 } else {
131 rgb = img.colorTable();
132 count = img.numColors();
133 }
134 int rc, gc, bc;
135 int bs = abs ( i * 10 ) + 25;
136 colorGroup().highlight().rgb( &rc, &gc, &bc );
137 rc = rc * bs / 100;
138 gc = gc * bs / 100;
139 bc = bc * bs / 100;
140
141 for ( int r = 0; r < count; r++, rgb++ ) {
142 int ri = rc + qRed ( *rgb ) * ( 100 - bs ) / 100;
143 int gi = gc + qGreen ( *rgb ) * ( 100 - bs ) / 100;
144 int bi = bc + qBlue ( *rgb ) * ( 100 - bs ) / 100;
145 int ai = qAlpha ( *rgb );
146 *rgb = qRgba ( ri, gi, bi, ai );
147 }
148 164
149 bpm [i].convertFromImage( img ); 165 if ( on ) {
150 } 166 busyTimer = startTimer( 100 );
151 167 } else {
152 if ( busyType == BIT_Blinking ) { 168 if ( busyTimer ) {
153 busystate = 0; 169 killTimer( busyTimer );
154 busytimer = startTimer ( 200 ); 170 busyTimer = 0;
155 }
156 else {
157 busystate = 3;
158 }
159 timerEvent ( 0 );
160 } 171 }
161 } 172 }
162 }
163 173
164 virtual void timerEvent ( QTimerEvent *te ) 174 LauncherItem *c = on ? (LauncherItem*)currentItem() : 0;
165 { 175
166 if ( !te || ( te-> timerId ( ) == busytimer )) { 176 if ( bsy != c ) {
167 if ( bsy ) { 177 LauncherItem *oldBusy = bsy;
168 busystate++; 178 bsy = c;
169 if ( busystate > 5 ) 179 if ( oldBusy )
170 busystate = -4; 180 oldBusy->resetIcon();
171 181 if ( bsy )
172 QScrollView::updateContents ( bsy-> pixmapRect ( false )); 182 bsy->animateIcon();
173 }
174 } 183 }
175 } 184 }
176 185
@@ -178,8 +187,13 @@ public:
178 void keyPressEvent(QKeyEvent* e) 187 void keyPressEvent(QKeyEvent* e)
179 { 188 {
180 ike = TRUE; 189 ike = TRUE;
181 if ( e->key() == Key_F33 /* OK button */ || e->key() == Key_Space ) 190 if ( e->key() == Key_F33 /* OK button */ || e->key() == Key_Space ) {
182 returnPressed(currentItem()); 191 if ( (e->state() & ShiftButton) )
192 emit mouseButtonPressed(ShiftButton, currentItem(), QPoint() );
193 else
194 returnPressed(currentItem());
195 }
196
183 QIconView::keyPressEvent(e); 197 QIconView::keyPressEvent(e);
184 ike = FALSE; 198 ike = FALSE;
185 } 199 }
@@ -213,22 +227,11 @@ public:
213 } 227 }
214 } 228 }
215 229
230 void setBackgroundOrigin( QWidget::BackgroundOrigin ) {
231 }
232
216 void setBackgroundPixmap( const QPixmap &pm ) { 233 void setBackgroundPixmap( const QPixmap &pm ) {
217 if ( pm. isNull ( )) { 234 bgPixmap = pm;
218 bgPixmap = pm;
219 }
220 else {
221 // This is need for bg images with alpha channel
222
223 QPixmap tmp ( pm. size ( ), pm. depth ( ));
224
225 QPainter p ( &tmp );
226 p. fillRect ( 0, 0, pm. width ( ), pm. height ( ), bgColor. isValid ( ) ? bgColor : white );
227 p. drawPixmap ( 0, 0, pm );
228 p. end ( );
229
230 bgPixmap = tmp;
231 }
232 } 235 }
233 236
234 void setBackgroundColor( const QColor &c ) { 237 void setBackgroundColor( const QColor &c ) {
@@ -238,8 +241,7 @@ public:
238 void drawBackground( QPainter *p, const QRect &r ) 241 void drawBackground( QPainter *p, const QRect &r )
239 { 242 {
240 if ( !bgPixmap.isNull() ) { 243 if ( !bgPixmap.isNull() ) {
241 //p-> fillRect ( r, bgColor ); 244 p->drawTiledPixmap( r, bgPixmap,
242 p->drawTiledPixmap( r, bgPixmap,
243 QPoint( (r.x() + contentsX()) % bgPixmap.width(), 245 QPoint( (r.x() + contentsX()) % bgPixmap.width(),
244 (r.y() + contentsY()) % bgPixmap.height() ) ); 246 (r.y() + contentsY()) % bgPixmap.height() ) );
245 } else { 247 } else {
@@ -287,7 +289,7 @@ public:
287 { 289 {
288 switch (sortmeth) { 290 switch (sortmeth) {
289 case Name: 291 case Name:
290 return a->name().compare(b->name()); 292 return a->name().lower().compare(b->name().lower());
291 case Date: { 293 case Date: {
292 QFileInfo fa(a->linkFileKnown() ? a->linkFile() : a->file()); 294 QFileInfo fa(a->linkFileKnown() ? a->linkFile() : a->file());
293 QFileInfo fb(b->linkFileKnown() ? b->linkFile() : b->file()); 295 QFileInfo fb(b->linkFileKnown() ? b->linkFile() : b->file());
@@ -299,10 +301,18 @@ public:
299 return 0; 301 return 0;
300 } 302 }
301 303
302 QString getAllDocLinkInfo() const;
303
304protected: 304protected:
305 305
306 void timerEvent( QTimerEvent *te )
307 {
308 if ( te->timerId() == busyTimer ) {
309 if ( bsy )
310 bsy->animateIcon();
311 } else {
312 QIconView::timerEvent( te );
313 }
314 }
315
306 void styleChange( QStyle &old ) 316 void styleChange( QStyle &old )
307 { 317 {
308 QIconView::styleChange( old ); 318 QIconView::styleChange( old );
@@ -334,47 +344,9 @@ protected:
334 } 344 }
335 } 345 }
336 346
347 void focusInEvent( QFocusEvent * ) {}
348 void focusOutEvent( QFocusEvent * ) {}
337 349
338 // flicker free redrawing of busy indicator
339 // code was taken from QScrollView::viewportPaintEvent
340 void viewportPaintEvent( QPaintEvent* pe )
341 {
342 static QPixmap *pix = new QPixmap ( );
343
344 QWidget* vp = viewport();
345
346 if ( vp-> size ( ) != pix-> size ( ))
347 pix-> resize ( vp-> size ( ));
348
349 QPainter p(pix, vp);
350 QRect r = pe->rect();
351 if ( clipper ( ) != vp ) {
352 QRect rr(
353 -vp->x(), -vp->y(),
354 clipper()->width(), clipper()->height()
355 );
356 r &= rr;
357 if ( r.isValid() ) {
358 int ex = r.x() + vp->x() + contentsX();
359 int ey = r.y() + vp->y() + contentsY();
360 int ew = r.width();
361 int eh = r.height();
362 drawContentsOffset(&p,
363 contentsX()+vp->x(),
364 contentsY()+vp->y(),
365 ex, ey, ew, eh);
366 }
367 } else {
368 r &= clipper()->rect();
369 int ex = r.x() + contentsX();
370 int ey = r.y() + contentsY();
371 int ew = r.width();
372 int eh = r.height();
373 drawContentsOffset(&p, contentsX(), contentsY(), ex, ey, ew, eh);
374 }
375 bitBlt ( vp, r.topLeft(), pix, r );
376 }
377
378private: 350private:
379 QList<AppLnk> hidden; 351 QList<AppLnk> hidden;
380 QDict<void> mimes; 352 QDict<void> mimes;
@@ -382,15 +354,15 @@ private:
382 SortMethod sortmeth; 354 SortMethod sortmeth;
383 QRegExp tf; 355 QRegExp tf;
384 int cf; 356 int cf;
385 QIconViewItem* bsy; 357 LauncherItem* bsy;
358 int busyTimer;
386 bool ike; 359 bool ike;
387 bool bigIcns; 360 bool bigIcns;
388 QPixmap bgPixmap; 361 QPixmap bgPixmap;
389 QPixmap bpm [6];
390 QColor bgColor; 362 QColor bgColor;
391 int busytimer; 363#ifdef USE_ANIMATED_BUSY_ICON_OVERLAY
392 int busystate; 364 QPixmap busyPix;
393 BusyIndicatorType busyType; 365#endif
394}; 366};
395 367
396 368
@@ -401,63 +373,133 @@ void LauncherView::setBusy(bool on)
401 icons->setBusy(on); 373 icons->setBusy(on);
402} 374}
403 375
404class LauncherItem : public QIconViewItem 376void LauncherView::setBusyIndicatorType( const QString& type ) {
377 /* ### FIXME */
378}
379
380LauncherItem::LauncherItem( QIconView *parent, AppLnk *applnk, bool bigIcon )
381 : QIconViewItem( parent, applnk->name(),
382 bigIcon ? applnk->bigPixmap() :applnk->pixmap() ),
383 isBigIcon( bigIcon ),
384 iteration(0),
385 app(applnk) // Takes ownership
405{ 386{
406public: 387}
407 LauncherItem( QIconView *parent, AppLnk* applnk, bool bigIcon=TRUE );
408 ~LauncherItem()
409 {
410 LauncherIconView* liv = (LauncherIconView*)iconView();
411 if ( liv->busyItem() == this )
412 liv->setBusy(FALSE);
413 delete app;
414 }
415 388
416 AppLnk* appLnk() const { return app; } 389LauncherItem::~LauncherItem()
417 AppLnk* takeAppLnk() { AppLnk* r=app; app=0; return r; } 390{
391 LauncherIconView* liv = (LauncherIconView*)iconView();
392 if ( liv->busyItem() == this )
393 liv->setBusy(FALSE);
394 delete app;
395}
418 396
419 virtual int compare ( QIconViewItem * i ) const; 397int LauncherItem::compare ( QIconViewItem * i ) const
398{
399 LauncherIconView* view = (LauncherIconView*)iconView();
400 return view->compare(app,((LauncherItem *)i)->appLnk());
401}
420 402
421 void paintItem( QPainter *p, const QColorGroup &cg ) 403void LauncherItem::paintItem( QPainter *p, const QColorGroup &cg )
422 { 404{
423 LauncherIconView* liv = (LauncherIconView*)iconView(); 405 LauncherIconView* liv = (LauncherIconView*)iconView();
424 QBrush oldBrush( liv->itemTextBackground() ); 406 QBrush oldBrush( liv->itemTextBackground() );
425 QColorGroup mycg( cg ); 407 QColorGroup mycg( cg );
426 if ( liv->currentItem() == this ) { 408 if ( liv->currentItem() == this ) {
427 liv->setItemTextBackground( cg.brush( QColorGroup::Highlight ) ); 409 liv->setItemTextBackground( cg.brush( QColorGroup::Highlight ) );
428 mycg.setColor( QColorGroup::Text, cg.color( QColorGroup::HighlightedText ) ); 410 mycg.setColor( QColorGroup::Text, cg.color( QColorGroup::HighlightedText ) );
429 }
430 QIconViewItem::paintItem(p,mycg);
431 if ( liv->currentItem() == this )
432 liv->setItemTextBackground( oldBrush );
433 } 411 }
434 412
435 virtual QPixmap* pixmap () const 413 QIconViewItem::paintItem(p,mycg);
436 {
437 const LauncherIconView* liv = (LauncherIconView*)iconView();
438 if ( (const LauncherItem *)liv->busyItem() == this )
439 return liv->busyPixmap();
440 return QIconViewItem::pixmap();
441 }
442 414
443protected: 415 // Paint animation overlay
444 AppLnk* app; 416 if ( liv->busyItem() == this )
445}; 417 paintAnimatedIcon(p);
446 418
419 if ( liv->currentItem() == this )
420 liv->setItemTextBackground( oldBrush );
421}
447 422
448LauncherItem::LauncherItem( QIconView *parent, AppLnk *applnk, bool bigIcon ) 423void LauncherItem::paintAnimatedIcon( QPainter *p )
449 : QIconViewItem( parent, applnk->name(),
450 bigIcon ? applnk->bigPixmap() :applnk->pixmap() ),
451 app(applnk) // Takes ownership
452{ 424{
425 LauncherIconView* liv = (LauncherIconView*)iconView();
426 int pic = iteration % 16;
427 int w = pixmap()->width(), h = pixmap()->height();
428 QPixmap dblBuf( w, h + 4 );
429 QPainter p2( &dblBuf );
430 int x1, y1;
431 if ( liv->itemTextPos() == QIconView::Bottom ) {
432 x1 = x() + (width() - w) / 2 - liv->contentsX();
433 y1 = y() - liv->contentsY();
434 } else {
435 x1 = x() - liv->contentsX();
436 y1 = y() + (height() - h) / 2 - liv->contentsY();
437 }
438 y1 -= 2;
439 p2.translate(-x1,-y1);
440 liv->drawBackground( &p2, QRect(x1,y1,w,h+4) );
441 int bounceY = 2;
442#ifdef BOUNCE_BUSY_ICON
443 bounceY = 4 - ((iteration+2)%8);
444 bounceY = bounceY < 0 ? -bounceY : bounceY;
445#endif
446 p2.drawPixmap( x1, y1 + bounceY, *pixmap() );
447#ifdef USE_ANIMATED_BUSY_ICON_OVERLAY
448 p2.drawPixmap( x1, y1 + bounceY, liv->busyPixmap(), w * pic, 0, w, h );
449#endif
450 p->drawPixmap( x1, y1, dblBuf );
453} 451}
454 452
455int LauncherItem::compare ( QIconViewItem * i ) const 453void LauncherItem::animateIcon()
456{ 454{
457 LauncherIconView* view = (LauncherIconView*)iconView(); 455 LauncherIconView* liv = (LauncherIconView*)iconView();
458 return view->compare(app,((LauncherItem *)i)->appLnk()); 456
457 if ( liv->busyItem() != this || !app )
458 return;
459
460 // Highlight the icon
461 if ( iteration == 0 ) {
462 QPixmap src = isBigIcon ? app->bigPixmap() : app->pixmap();
463 QImage img = src.convertToImage();
464 QRgb *rgb;
465 int count;
466 if ( img.depth() == 32 ) {
467 rgb = (QRgb*)img.bits();
468 count = img.bytesPerLine()/sizeof(QRgb)*img.height();
469 } else {
470 rgb = img.colorTable();
471 count = img.numColors();
472 }
473 for ( int r = 0; r < count; r++, rgb++ ) {
474#if defined(BRIGHTEN_BUSY_ICON)
475 QColor c(*rgb);
476 int h, s, v;
477 c.hsv(&h,&s,&v);
478 c.setHsv(h,QMAX(s-24,0),QMIN(v+48,255));
479 *rgb = qRgba(c.red(),c.green(),c.blue(),qAlpha(*rgb));
480#elif defined(ALPHA_FADE_BUSY_ICON)
481 *rgb = qRgba(qRed(*rgb),qGreen(*rgb),qBlue(*rgb),qAlpha(*rgb)/2);
482#endif
483 }
484 src.convertFromImage( img );
485 setPixmap( src );
486 }
487
488 iteration++;
489
490 // Paint animation overlay
491 QPainter p( liv->viewport() );
492 paintAnimatedIcon( &p );
493}
494
495void LauncherItem::resetIcon()
496{
497 iteration = 0;
498 setPixmap( isBigIcon ? app->bigPixmap() : app->pixmap() );
459} 499}
460 500
501//===========================================================================
502
461QStringList LauncherIconView::mimeTypes() const 503QStringList LauncherIconView::mimeTypes() const
462{ 504{
463 QStringList r; 505 QStringList r;
@@ -503,6 +545,7 @@ void LauncherIconView::updateCategoriesAndMimeTypes()
503 545
504void LauncherIconView::hideOrShowItems(bool resort) 546void LauncherIconView::hideOrShowItems(bool resort)
505{ 547{
548 viewport()->setUpdatesEnabled( FALSE );
506 hidden.setAutoDelete(FALSE); 549 hidden.setAutoDelete(FALSE);
507 QList<AppLnk> links=hidden; 550 QList<AppLnk> links=hidden;
508 hidden.clear(); 551 hidden.clear();
@@ -512,7 +555,6 @@ void LauncherIconView::hideOrShowItems(bool resort)
512 links.append(item->takeAppLnk()); 555 links.append(item->takeAppLnk());
513 item = (LauncherItem*)item->nextItem(); 556 item = (LauncherItem*)item->nextItem();
514 } 557 }
515 viewport()->setUpdatesEnabled( FALSE );
516 clear(); 558 clear();
517 QListIterator<AppLnk> it(links); 559 QListIterator<AppLnk> it(links);
518 AppLnk* l; 560 AppLnk* l;
@@ -520,9 +562,9 @@ void LauncherIconView::hideOrShowItems(bool resort)
520 addItem(l,FALSE); 562 addItem(l,FALSE);
521 ++it; 563 ++it;
522 } 564 }
523 viewport()->setUpdatesEnabled( TRUE );
524 if ( resort && !autoArrange() ) 565 if ( resort && !autoArrange() )
525 sort(); 566 sort();
567 viewport()->setUpdatesEnabled( TRUE );
526} 568}
527 569
528bool LauncherIconView::removeLink(const QString& linkfile) 570bool LauncherIconView::removeLink(const QString& linkfile)
@@ -533,20 +575,22 @@ bool LauncherIconView::removeLink(const QString& linkfile)
533 DocLnk dl(linkfile); 575 DocLnk dl(linkfile);
534 while (item) { 576 while (item) {
535 l = item->appLnk(); 577 l = item->appLnk();
536 if ( ( l->linkFileKnown() && ( l->linkFile() == linkfile )) 578 LauncherItem *nextItem = (LauncherItem *)item->nextItem();
537 || ( l->fileKnown() && ( l->file() == linkfile )) 579 if ( l->linkFileKnown() && l->linkFile() == linkfile
538 || ( dl.fileKnown() && l->fileKnown() && ( dl.file() == l->file() )) ) { 580 || l->fileKnown() && (
581 l->file() == linkfile
582 || dl.isValid() && dl.file() == l->file() ) ) {
539 delete item; 583 delete item;
540 did = TRUE; 584 did = TRUE;
541 } 585 }
542 item = (LauncherItem*)item->nextItem(); 586 item = nextItem;
543 } 587 }
544 QListIterator<AppLnk> it(hidden); 588 QListIterator<AppLnk> it(hidden);
545 while ((l=it.current())) { 589 while ((l=it.current())) {
546 ++it; 590 ++it;
547 if ( ( l->linkFileKnown() && ( l->linkFile() == linkfile )) 591 if ( l->linkFileKnown() && l->linkFile() == linkfile
548 || ( l->file() == linkfile ) 592 || l->file() == linkfile
549 || ( dl.fileKnown() && ( dl.file() == l->file() )) ) { 593 || dl.isValid() && dl.file() == l->file() ) {
550 hidden.removeRef(l); 594 hidden.removeRef(l);
551 did = TRUE; 595 did = TRUE;
552 } 596 }
@@ -554,62 +598,12 @@ bool LauncherIconView::removeLink(const QString& linkfile)
554 return did; 598 return did;
555} 599}
556 600
557static QString docLinkInfo(const Categories& cats, DocLnk* doc)
558{
559 QString contents;
560
561 QFileInfo fi( doc->file() );
562 if ( !fi.exists() )
563 return contents;
564
565 if ( doc->linkFileKnown() ) {
566 QString lfn = doc->linkFile();
567 QFile f( lfn );
568 if ( f.open( IO_ReadOnly ) ) {
569 QTextStream ts( &f );
570 ts.setEncoding( QTextStream::UnicodeUTF8 );
571 contents += ts.read();
572 f.close();
573 goto calcsize;
574 }
575 }
576
577 contents += "[Desktop Entry]\n";
578 contents += "Categories = " // No tr
579 + cats.labels("Document View", doc->categories()).join(";") + "\n"; // No tr
580 contents += "File = "+doc->file()+"\n"; // No tr
581 contents += "Name = "+doc->name()+"\n"; // No tr
582 contents += "Type = "+doc->type()+"\n"; // No tr
583
584calcsize:
585 contents += QString("Size = %1\n").arg( fi.size() ); // No tr
586 return contents;
587}
588
589QString LauncherIconView::getAllDocLinkInfo() const
590{
591 QString contents;
592 LauncherItem* item = (LauncherItem*)firstItem();
593 Categories cats;
594 while (item) {
595 DocLnk* doc = (DocLnk*)item->appLnk();
596 contents += docLinkInfo(cats,doc);
597 item = (LauncherItem*)item->nextItem();
598 }
599 QListIterator<AppLnk> it(hidden);
600 DocLnk* doc;
601 while ((doc=(DocLnk*)it.current())) {
602 contents += docLinkInfo(cats,doc);
603 ++it;
604 }
605 return contents;
606}
607
608//=========================================================================== 601//===========================================================================
609 602
610LauncherView::LauncherView( QWidget* parent, const char* name, WFlags fl ) 603LauncherView::LauncherView( QWidget* parent, const char* name, WFlags fl )
611 : QVBox( parent, name, fl ) 604 : QVBox( parent, name, fl )
612{ 605{
606 catmb = 0;
613 icons = new LauncherIconView( this ); 607 icons = new LauncherIconView( this );
614 setFocusProxy(icons); 608 setFocusProxy(icons);
615 QPEApplication::setStylusOperation( icons->viewport(), QPEApplication::RightOnHold ); 609 QPEApplication::setStylusOperation( icons->viewport(), QPEApplication::RightOnHold );
@@ -640,6 +634,13 @@ LauncherView::LauncherView( QWidget* parent, const char* name, WFlags fl )
640 634
641LauncherView::~LauncherView() 635LauncherView::~LauncherView()
642{ 636{
637 if ( bgCache && bgCache->contains( bgName ) )
638 (*bgCache)[bgName]->ref--;
639}
640
641void LauncherView::hideIcons()
642{
643 icons->hide();
643} 644}
644 645
645void LauncherView::setToolsEnabled(bool y) 646void LauncherView::setToolsEnabled(bool y)
@@ -650,12 +651,16 @@ void LauncherView::setToolsEnabled(bool y)
650 651
651 // Type filter 652 // Type filter
652 typemb = new QComboBox(tools); 653 typemb = new QComboBox(tools);
654 QSizePolicy p = typemb->sizePolicy();
655 p.setHorData(QSizePolicy::Expanding);
656 typemb->setSizePolicy(p);
653 657
654 // Category filter 658 // Category filter
655 catmb = new CategorySelect(tools);
656
657 updateTools(); 659 updateTools();
658 tools->show(); 660 tools->show();
661
662 // Always show vscrollbar
663 icons->setVScrollBarMode( QScrollView::AlwaysOn );
659 } else { 664 } else {
660 delete tools; 665 delete tools;
661 tools = 0; 666 tools = 0;
@@ -667,9 +672,10 @@ void LauncherView::updateTools()
667{ 672{
668 disconnect( typemb, SIGNAL(activated(int)), 673 disconnect( typemb, SIGNAL(activated(int)),
669 this, SLOT(showType(int)) ); 674 this, SLOT(showType(int)) );
670 disconnect( catmb, SIGNAL(signalSelected(int)), 675 if ( catmb ) disconnect( catmb, SIGNAL(signalSelected(int)),
671 this, SLOT(showCategory(int)) ); 676 this, SLOT(showCategory(int)) );
672 677
678 // ### I want to remove this
673 icons->updateCategoriesAndMimeTypes(); 679 icons->updateCategoriesAndMimeTypes();
674 680
675 QString prev; 681 QString prev;
@@ -689,9 +695,9 @@ void LauncherView::updateTools()
689 } else { 695 } else {
690 t[0] = t[0].upper(); 696 t[0] = t[0].upper();
691 } 697 }
692 types += tr("%1 files").arg(t); 698 types += t;
693 } 699 }
694 types << tr("All types of file"); 700 types << tr("All types");
695 prev = typemb->currentText(); 701 prev = typemb->currentText();
696 typemb->clear(); 702 typemb->clear();
697 typemb->insertStringList(types); 703 typemb->insertStringList(types);
@@ -704,6 +710,9 @@ void LauncherView::updateTools()
704 if ( prev.isNull() ) 710 if ( prev.isNull() )
705 typemb->setCurrentItem(typemb->count()-1); 711 typemb->setCurrentItem(typemb->count()-1);
706 712
713 int pcat = catmb ? catmb->currentCategory() : -2;
714 if ( !catmb )
715 catmb = new CategorySelect(tools);
707 Categories cats( 0 ); 716 Categories cats( 0 );
708 cats.load( categoryFileName() ); 717 cats.load( categoryFileName() );
709 QArray<int> vl( 0 ); 718 QArray<int> vl( 0 );
@@ -711,6 +720,11 @@ void LauncherView::updateTools()
711 tr("Document View") ); 720 tr("Document View") );
712 catmb->setRemoveCategoryEdit( TRUE ); 721 catmb->setRemoveCategoryEdit( TRUE );
713 catmb->setAllCategories( TRUE ); 722 catmb->setAllCategories( TRUE );
723 catmb->setCurrentCategory(pcat);
724
725 // if type has changed we need to redisplay
726 if ( typemb->currentText() != prev )
727 showType( typemb->currentItem() );
714 728
715 connect(typemb, SIGNAL(activated(int)), this, SLOT(showType(int))); 729 connect(typemb, SIGNAL(activated(int)), this, SLOT(showType(int)));
716 connect(catmb, SIGNAL(signalSelected(int)), this, SLOT(showCategory(int))); 730 connect(catmb, SIGNAL(signalSelected(int)), this, SLOT(showCategory(int)));
@@ -758,17 +772,75 @@ void LauncherView::setViewMode( ViewMode m )
758 } 772 }
759} 773}
760 774
775//
776// User images may require scaling.
777//
778QImage LauncherView::loadBackgroundImage(QString &bgName)
779{
780 QImageIO imgio;
781 QSize ds = qApp->desktop()->size(); // should be launcher, not desktop
782 bool further_scaling = TRUE;
783
784 imgio.setFileName( bgName );
785 imgio.setParameters("GetHeaderInformation");
786
787 if (imgio.read() == FALSE) {
788 return imgio.image();
789 }
790
791 if (imgio.image().width() < ds.width() &&
792 imgio.image().height() < ds.height()) {
793 further_scaling = FALSE;
794 }
795
796 if (!imgio.image().bits()) {
797 //
798 // Scale and load. Note we don't scale up.
799 //
800 QString param( "Scale( %1, %2, ScaleMin )" ); // No tr
801 imgio.setParameters(further_scaling ?
802 param.arg(ds.width()).arg(ds.height()).latin1() :
803 "");
804 imgio.read();
805 } else {
806 if (further_scaling) {
807 intt1 = imgio.image().width() * ds.height();
808 int t2 = imgio.image().height() * ds.width();
809 int dsth = ds.height();
810 int dstw = ds.width();
811
812 if (t1 > t2) {
813 dsth = t2 / imgio.image().width();
814 } else {
815 dstw = t1 / imgio.image().height();
816 }
817
818 //
819 // Loader didn't scale for us. Do it manually.
820 //
821 return imgio.image().smoothScale(dstw, dsth);
822 }
823 }
824
825 return imgio.image();
826}
827
761void LauncherView::setBackgroundType( BackgroundType t, const QString &val ) 828void LauncherView::setBackgroundType( BackgroundType t, const QString &val )
762{ 829{
763 if ( !bgCache ) 830 if ( !bgCache ) {
764 bgCache = new QMap<QString,BgPixmap*>; 831 bgCache = new QMap<QString,BgPixmap*>;
832 qAddPostRoutine( cleanup_cache );
833 }
834
765 if ( bgCache->contains( bgName ) ) 835 if ( bgCache->contains( bgName ) )
766 (*bgCache)[bgName]->ref--; 836 (*bgCache)[bgName]->ref--;
837 bgName = "";
838
839 QPixmap bg;
767 840
768 switch ( t ) { 841 switch ( t ) {
769 case Ruled: { 842 case Ruled: {
770 bgName = QString("Ruled_%1").arg(colorGroup().background().name()); // No tr 843 bgName = QString("Ruled_%1").arg(colorGroup().background().name()); // No tr
771 QPixmap bg;
772 if ( bgCache->contains( bgName ) ) { 844 if ( bgCache->contains( bgName ) ) {
773 (*bgCache)[bgName]->ref++; 845 (*bgCache)[bgName]->ref++;
774 bg = (*bgCache)[bgName]->pm; 846 bg = (*bgCache)[bgName]->pm;
@@ -785,55 +857,63 @@ void LauncherView::setBackgroundType( BackgroundType t, const QString &val )
785 painter.end(); 857 painter.end();
786 bgCache->insert( bgName, new BgPixmap(bg) ); 858 bgCache->insert( bgName, new BgPixmap(bg) );
787 } 859 }
788 icons->setBackgroundPixmap( bg );
789 break; 860 break;
790 } 861 }
791 862
792 case SolidColor:
793 icons->setBackgroundPixmap( QPixmap() );
794 if ( val.isEmpty() ) {
795 icons->setBackgroundColor( colorGroup().base() );
796 } else {
797 icons->setBackgroundColor( val );
798 }
799 bgName = "";
800 break;
801
802 case Image: 863 case Image:
803 bgName = val; 864 if (!val.isEmpty()) {
804 if ( bgCache->contains( bgName ) ) { 865 bgName = val;
805 (*bgCache)[bgName]->ref++; 866 if ( bgCache->contains( bgName ) ) {
806 icons->setBackgroundPixmap( (*bgCache)[bgName]->pm ); 867 (*bgCache)[bgName]->ref++;
807 } else { 868 bg = (*bgCache)[bgName]->pm;
808 QPixmap bg( Resource::loadPixmap( val ) ); 869 } else {
809 if ( bg.isNull() ) { 870 QString imgFile = bgName;
810 QImageIO imgio; 871 bool tile = FALSE;
811 imgio.setFileName( bgName ); 872 if ( imgFile[0]!='/' || !QFile::exists(imgFile) ) {
812 QSize ds = qApp->desktop()->size(); 873 imgFile = Resource::findPixmap( imgFile );
813 QString param( "Scale( %1, %2, ScaleMin )" ); // No tr 874 tile = TRUE;
814 imgio.setParameters( param.arg(ds.width()).arg(ds.height()).latin1() ); 875 }
815 imgio.read(); 876 QImage img = loadBackgroundImage(imgFile);
816 bg = imgio.image(); 877
878
879 if ( img.depth() == 1 )
880 img = img.convertDepth(8);
881 img.setAlphaBuffer(FALSE);
882 bg.convertFromImage(img);
883 bgCache->insert( bgName, new BgPixmap(bg) );
817 } 884 }
818 bgCache->insert( bgName, new BgPixmap(bg) );
819 icons->setBackgroundPixmap( bg );
820 } 885 }
821 break; 886 break;
887
888 case SolidColor:
889 default:
890 break;
822 } 891 }
823 892
824 // remove unreferenced backgrounds. 893 const QObjectList *list = queryList( "QWidget", 0, FALSE );
825 QMap<QString,BgPixmap*>::Iterator it = bgCache->begin(); 894 QObject *obj;
826 while ( it != bgCache->end() ) { 895 for ( QObjectListIt it( *list ); (obj=it.current()); ++it ) {
827 QMap<QString,BgPixmap*>::Iterator curr = it; 896 if ( obj->isWidgetType() ) {
828 ++it; 897 QWidget *w = (QWidget*)obj;
829 if ( (*curr)->ref == 0 ) { 898 w->setBackgroundPixmap( bg );
830 delete (*curr); 899 if ( bgName.isEmpty() ) {
831 bgCache->remove( curr ); 900 // Solid Color
901 if ( val.isEmpty() )
902 w->setBackgroundColor( colorGroup().base() );
903 else
904 w->setBackgroundColor( val );
905 } else {
906 // Ruled or Image pixmap
907 w->setBackgroundOrigin( ParentOrigin );
908 }
832 } 909 }
833 } 910 }
911 delete list;
834 912
835 bgType = t; 913 bgType = t;
836 icons->viewport()->update(); 914 icons->viewport()->update();
915
916 QTimer::singleShot( 1000, this, SLOT(flushBgCache()) );
837} 917}
838 918
839void LauncherView::setTextColor( const QColor &tc ) 919void LauncherView::setTextColor( const QColor &tc )
@@ -848,11 +928,13 @@ void LauncherView::setTextColor( const QColor &tc )
848void LauncherView::setViewFont( const QFont &f ) 928void LauncherView::setViewFont( const QFont &f )
849{ 929{
850 icons->setFont( f ); 930 icons->setFont( f );
931 icons->hideOrShowItems( FALSE );
851} 932}
852 933
853void LauncherView::unsetViewFont( ) 934void LauncherView::clearViewFont()
854{ 935{
855 icons->unsetFont( ); 936 icons->unsetFont();
937 icons->hideOrShowItems( FALSE );
856} 938}
857 939
858void LauncherView::resizeEvent(QResizeEvent *e) 940void LauncherView::resizeEvent(QResizeEvent *e)
@@ -862,17 +944,6 @@ void LauncherView::resizeEvent(QResizeEvent *e)
862 sort(); 944 sort();
863} 945}
864 946
865void LauncherView::populate( AppLnkSet *folder, const QString& typefilter )
866{
867 icons->clear();
868 internalPopulate( folder, typefilter );
869}
870
871QString LauncherView::getAllDocLinkInfo() const
872{
873 return icons->getAllDocLinkInfo();
874}
875
876void LauncherView::selectionChanged() 947void LauncherView::selectionChanged()
877{ 948{
878 QIconViewItem* item = icons->currentItem(); 949 QIconViewItem* item = icons->currentItem();
@@ -911,32 +982,15 @@ void LauncherView::itemPressed( int btn, QIconViewItem *item )
911 AppLnk *appLnk = ((LauncherItem *)item)->appLnk(); 982 AppLnk *appLnk = ((LauncherItem *)item)->appLnk();
912 if ( btn == RightButton ) 983 if ( btn == RightButton )
913 emit rightPressed( appLnk ); 984 emit rightPressed( appLnk );
914/* 985 else if ( btn == ShiftButton )
915 else if ( btn == LeftButton ) 986 emit rightPressed( appLnk );
916 emit clicked( appLnk );
917*/
918 item->setSelected(FALSE); 987 item->setSelected(FALSE);
919 } 988 }
920} 989}
921 990
922void LauncherView::internalPopulate( AppLnkSet *folder, const QString& typefilter ) 991void LauncherView::removeAllItems()
923{ 992{
924 QListIterator<AppLnk> it( folder->children() ); 993 icons->clear();
925 icons->setTypeFilter(typefilter,FALSE);
926
927 while ( it.current() ) {
928 // show only the icons for existing files
929 if (QFile(it.current()->file()).exists() || ( it.current()->file().left(4) == "http" )) {
930 icons->addItem(*it,FALSE);
931 }
932 else {
933 //maybe insert some .desktop file deletion code later
934 //maybe dir specific
935 }
936 ++it;
937 }
938
939 icons->sort();
940} 994}
941 995
942bool LauncherView::removeLink(const QString& linkfile) 996bool LauncherView::removeLink(const QString& linkfile)
@@ -944,6 +998,18 @@ bool LauncherView::removeLink(const QString& linkfile)
944 return icons->removeLink(linkfile); 998 return icons->removeLink(linkfile);
945} 999}
946 1000
1001void LauncherView::setSortEnabled( bool v )
1002{
1003 icons->setSorting( v );
1004 if ( v )
1005 sort();
1006}
1007
1008void LauncherView::setUpdatesEnabled( bool u )
1009{
1010 icons->setUpdatesEnabled( u );
1011}
1012
947void LauncherView::sort() 1013void LauncherView::sort()
948{ 1014{
949 icons->sort(); 1015 icons->sort();
@@ -954,11 +1020,6 @@ void LauncherView::addItem(AppLnk* app, bool resort)
954 icons->addItem(app,resort); 1020 icons->addItem(app,resort);
955} 1021}
956 1022
957void LauncherView::setFileSystems(const QList<FileSystem> &)
958{
959 // ### does nothing now...
960}
961
962void LauncherView::paletteChange( const QPalette &p ) 1023void LauncherView::paletteChange( const QPalette &p )
963{ 1024{
964 icons->unsetPalette(); 1025 icons->unsetPalette();
@@ -970,12 +1031,30 @@ void LauncherView::paletteChange( const QPalette &p )
970 icons->setPalette( QPalette(cg,cg,cg) ); 1031 icons->setPalette( QPalette(cg,cg,cg) );
971} 1032}
972 1033
1034void LauncherView::fontChanged(const QFont&)
1035{
1036 qDebug("LauncherView::fontChanged()");
1037 icons->hideOrShowItems( FALSE );
1038}
973 1039
974void LauncherView::setBusyIndicatorType ( const QString &type ) 1040void LauncherView::relayout(void)
975{ 1041{
976 if ( type. lower ( ) == "blink" ) 1042 icons->hideOrShowItems(FALSE);
977 icons-> setBusyIndicatorType ( BIT_Blinking ); 1043}
978 else 1044
979 icons-> setBusyIndicatorType ( BIT_Normal ); 1045void LauncherView::flushBgCache()
1046{
1047 if ( !bgCache )
1048 return;
1049 // remove unreferenced backgrounds.
1050 QMap<QString,BgPixmap*>::Iterator it = bgCache->begin();
1051 while ( it != bgCache->end() ) {
1052 QMap<QString,BgPixmap*>::Iterator curr = it;
1053 ++it;
1054 if ( (*curr)->ref == 0 ) {
1055 delete (*curr);
1056 bgCache->remove( curr );
1057 }
1058 }
980} 1059}
981 1060