summaryrefslogtreecommitdiff
Side-by-side diff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--ChangeLog2
-rw-r--r--core/launcher/launcher.cpp8
-rw-r--r--core/launcher/launcherview.cpp28
-rw-r--r--core/launcher/launcherview.h3
-rw-r--r--core/settings/launcher/tabssettings.cpp13
-rw-r--r--core/settings/launcher/tabssettings.h2
6 files changed, 43 insertions, 13 deletions
diff --git a/ChangeLog b/ChangeLog
index fe763a5..8ac976d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,221 +1,223 @@
2005-??-?? Opie 1.2.0
New Features
------------
+ * Launcher: Support a static background pixmap (mickeyl)
+ * LauncherSettings: Choose whether to have a static background pixmap (mickeyl)
Fixed Bugs
----------
* #1236 - VCards contained empty home and work address entries causing Palms to crash (eilers)
* #1474 - Implement GUI for Scrollbars on the Left in Appearance (zecke)
* #1482 - Fix double '/' in paths (zecke)
* #1536 - Autosave of custom locations in opie backup (ar)
* #1539 - Fixed displaying too long path in the delete dialog in opie-eye (zecke)
* #1540 - Implemented deletion of DocLnks in opie-eye (zecke)
* #1542 - Fix Todo crash when priority < 1 or > 5 (drw)
* #1554 - Fixed Opie-Console name in .desktop file (mickeyl)
* #1556 - Start to look for sound files in /opt/QtPalmtop/sounds (zecke)
* #1558 - Fixed opie-login breaking opie startup (mickeyl)
* n.a. - PackageManager - fixed where last package in status file was not shown as installed when it should be (drw)
Internal
--------
* Work around bug in Qt/Embedded 2.3.10: qt_version() returns 231 (mickeyl)
* Killed the need for weak symbols in QtE (zecke)
2005-02-03 Opie 1.1.9
New Features
------------
* Number of icon columns in Launcher is customizable through Launcher.conf (hrw,zecke,mickeyl)
* Number of icon columns in Launcher is customizable through LauncherSettings (mickeyl)
* Usability enhancements in OpieIRC (skyhusker)
Fixed Bugs
----------
* #1501 - Fixed bug in todo sql backend (eilers)
* #1505 - Added more Swap sizes in memoryapplet (mickeyl)
* #1525 - Hopefully fixed double alarms and not removing alarms set with the Clock application (zecke)
* #1533 - Security Owner Dialog (shown in case of unsuccessfull authentiacation) wasn't able to display information in non latin1 encoding (zecke)
* n.a. - Removed hard coded font sizes in a couple of inputmethods (mickeyl)
* n.a. - Removed MediumDlg appearing prior to FirstUsage wizard (i.e. calibration) (mickeyl)
* n.a. - Fixed numerous buglets in OpieIRC (skyhusker)
Internal
--------
* Added the Qtopia 1.7 SDK macros for quick-apps to easa compilation of 3rd party apps against our headers (mickeyl)
* You can now use the Opie build system in combination with a OpenEmbedded staging area which makes a nice cross development environment (mickeyl)
* Made Opie compilable with Qt/Embedded 2.3.10 (ar)
* Changed Launcher to get default orientation from ODevice w/ QWS_DISPLAY overriding (mickeyl)
* Build tree cleanups (mickeyl)
2004-11-26 Opie 1.1.8
New Features
------------
* PackageManager supports installation of local ipkg files (drw)
* PackageManager supports linking of applications to root (drw)
* PackageManager supports src/gz feeds (drw,wimpie)
* Added a syslog information tab to sysinfo (mickeyl)
* Added new, more consistent, PIM icons + a GIMP teplate (ar)
Fixed Bugs
----------
* #1017 - Tetrix doesn't display correctly for high resolution screens (drw)
* #1269 - VCards were imported into personal area if it was activated (eilers)
* #1464 - Packagemanager dont set active filter after install a package (drw)
* #1479 - Improved VCard-Parser to import VCards created by Evolution 2 and Apple Addressbook (eilers)
* #1493 - Fixed one column layout bug of the launcher (hrw)
* n.a. - PackageManager - (Minor UI tweak) in filter dialog, when option is enabled, set focus to widget that corresponds to that option (drw)
* n.a. - PackageManager - (Minor UI tweak) fix double entry in source feed configuration when adding a new feed (drw)
* n.a. - Battery Applet - fix sizing of battery info popup (drw,mickeyl)
Internal
--------
* Moved libopie1 to unsupported (mickeyl)
* Implemented generic queryByExample() with incremental searching. A lot of internal changes of the Pim2-library (eilers)
* Added fast and full featured and incremental sorted() for SQL addressbook backend (eilers)
2004-11-14 Opie 1.1.7
New Features
------------
* libOpieDB now uses SQLite V3 instead V2. Remember to upgrade your database files! (eilers)
* Backup now uses the busy indicator when backing up and restore (ar)
* OpiePlayer2 gained adding of Directories to the playlist (zecke)
* OpiePlayer2 better error handling (zecke)
* OpiePlayer2 progress indication while streaming (zecke)
* OpiePlayer2 ported to use libxine 1.0.0-rc6a (brad,zecke)
* Ported brightnessapplet from Qtopia 1.7 (mickeyl)
* Opie-Eye got a Digital Camera File Backend (alwin,zecke)
* Support for Tuxpad1 of Tradesquare.NL (mickeyl,zecke)
* Opie-Console use Custom Font and Size in a Profile (harlekin)
* Opie-Console transparently log the Output and Input to a file (harlekin)
* Added new O-menu icon to lock the PDA immediately: opie-lockapplet (clem)
* Opie-Security now hides the plugin-based authentication tabs if no auth. plugin package is installed (clem)
* Opie-Security gained a 'test authentication' button (clem)
* Opie-Eye got a more unique layout (menubar), a slideshow, user can setup some defaults
* Opie-Mail improve the handling of POP mail boxes (alwin)
* Both Opie-Eye and Opie-Mail were greatly improved due the hard work of Rajko Albrecht(alwin)
* Opie IRC - backports of the 'NeIRC fork' (zecke)
Fixed Bugs
----------
* #501 - Pickboard is able to show 'Umlaute' (TT,zecke)
* #608 - Make Opie usable for left handed users (zecke)
* #957 - Import of VCards/VTodos/VEvents with BASE64 encoding (ljp,zecke)
* #1245 - Opie-Go 'paused' (zecke)
* #1358 - DocTab didn't show any MimeTypes (was fixed earlier) (zecke)
* #1380 - QDateBookAccess::remove() doesn't remove entries (eilers, zecke)
* #1395 - Build VNC Backend with gcc3.4
* #1440 - The icon of opie-mobilemsg is missing (CoreDump)
* #1426 - Add missing opie-bartender Icon (CoreDump)
* #1445 - Opie-Sheet Has No Icon (CoreDump)
* #1448 - Brightness Applet added (mickeyl)
* #1450 - ZSame didn't clear the bonus item after winning a game (zecke)
* #1482 - Fix OFileSelector to be able to sort by size (zecke)
* n.a. - Opie-mail: fixed some crasher, some layout-problems
* n.a. - Converted applications to not hardcode /opt/QtPalmtop but to use QPEApplication::qpeDir (zecke)
* n.a. - Converted usage of qpeDir() not to include a '/' as first charachter of the string (zecke)
* n.a. - Build system: Enable distcc and ccache when crosscompiling too, and use them everywhere we can (clem)
* n.a. - Build system: Fix deps in several config.in (and fix scripts/deps.pl too) to stop breaking builds, especially with make -j highNumber (clem)
* n.a. - Removed hardcoded icon size in a couple of applets (mickeyl)
Internal
--------
* Opie-Qashmoney has been moved to unsupported (mickeyl)
* Opie-Ubrowser has been moved to unsupported (mickeyl)
2004-09-17 Opie 1.1.6
New Features
------------
* Fifteen gained configurable number of items (zecke)
* Fifteen can have custom background images (zecke)
* Added daemonizing capabilities to QWS Server [via Qt/Embedded] (mickeyl)
* Integrated the new security framework into libopie2 (zecke,clem)
* Converted the launcher to use the new security framework (zecke)
* Backup can now handle custom locations for backup and restore (ar)
* Implemented right-on-hold feedback (wimpie,zecke)
* Lots of new features in opie-reader (tim,pohly)
* Build system cleanups (schurig)
Fixed Bugs
--------
* #1005 - Fixed backup to CompactFlash (ar)
* #1167 - Fixed Opie write crashing on more text than one page (ar)
* #1225 - Fixed repeated light flashing on Zaurus with keyz (mickeyl)
* #1359 - Fixed bookmarks in Gutenbrowser (ljp)
* #1361 - Fixed auto upercase in Opie-Addressbook (eilers)
* #1370 - Pimconverter now reacts on cancel key (eilers)
* #1376 - Bring back the capslock/numlock display (zecke)
* #1383 - Language settings now warns about losing open apps (Markus Litz)
* #1393 - Fixed line wrap issues in opie-console for the default profile (mickeyl)
* #1394 - Fixed oversized headline in opie-login (coredump)
* #1396 - Opie-console captures the escape key and vim is working (zecke)
* #1401 - Scrollbar is now only visible if necessary in DocTab (mickeyl)
2004-07-06 Opie 1.1.4
New Features
------------
* Added four themes courtesy Robert Griebl (http://www.softforge.de/zstyle)
* Added Conversion tool for pim-data (eilers)
* Introduced new OPimAccessFactory and OBackendFactory which simplyfies database access (eilers)
* Modified the PIM API for providing generic use of OPimRecords (eilers)
* Clicking on the application symbol now iterates over the application's top level widgets if already raised (zecke)
Fixed Bugs
--------
* #1068 - Country Drop Down Box Off Screen
* #1291 - Opie tinykate does not open .desktop files (ar)
* #1291 - Opie sheet not saving correctly (ar)
* #1294 - Opie does not know about British Summer Time
* #1314 - Drawpad initialization (mickeyl)
* #1317 - Packagemanager crashes on hold-down or install (chicken)
* #1321 - Batteryapplet graphic glitch (harlekin)
* #1324 - ZSafe not starting up (mickeyl)
* #1328 - Personal Home Address fields is trimmed to 1char (eilers)
* #1327 - Opie-mail ipk does not depend on libopiedb2 (chicken)
* #1345 - Networksettingsplugin wlan plugin dependency on libpcap0 (mickeyl)
* #1348 - Datebook dependency on libopiedb2 (chicken)
* #1328 - Switched SQLDatabase and VCards char encoding from latin1 to unicode (eilers)
2004-04-25 Opie 1.1.3
* Introduced first implementation of SQL-Support using SQLite (eilers)
* Added a new Gutenberg Project reader app - opie-gutenbrowser (ljp)
* Added a real system graffiti character set (brad)
* Added Generic Keyconfig Widget (zecke)
* Improved Screenshotapplet and Drawpad integration. You can now open a screenshot in drawpad and take notes (zecke)
* Added new Bible reader app - opie-dagger (drw)
* Added a new Image Viewer. Work is ongoing (zecke,alwin)
* Added namespace usage in libopie2 and everywhere (zecke,alwin)
* Enabled the possibility to pass command line arguments to applications (mickeyl)
* Added an about applet showing some credits and information about Opie (mickeyl)
* Added benchmarking functionality to sysinfo (mickeyl)
* Added applet and configuration application for switching hardware keyboard layouts (alwin)
* Ported applications from libopie1 to libopie2* (drw,ar,alwin)
* Imported fullscreen and font improvements from the Qkonsole fork to embeddedkonsole (waspe)
* Clean-up of package information in control files (drw)
* Repaired mediummount which was broken since integrating the quicklauncher (alwin)
* Improved big-screen support (zecke,ar)
* Improved multikeyboard support, added keyboard layout switching applet (mouse)
* Added a new mail client based on libetpan (harlekin,alwin,jgf)
* Added new package manager - opie-packagemanager (drw)
* Improved light-n-power for C7x0 (mickeyl)
* Added automatic rotation support for C7x0 (treke)
* Split libopie1 up into a set of smaller - functionally grouped - libraries (mickeyl)
* Added scanning the wireless network neighbourhood to networksettings (mickeyl)
2003-11-29 Opie 1.0.3
* Released as Version 1.0.3
* Improved i18n (various contributors)
* Reduced application startup time by integrating the TT quicklauncher (zecke,harlekin)
* Made the Documents Tab optional (mickeyl)
* Integrated basic support for HP iPAQ 54xx and the Jornada 5xx (chicken)
2003-08-04 Opie 1.0.0
* Released as Version 1.0.0
* Including a PPP module for easy dial up (tille,harlekin,zecke)
diff --git a/core/launcher/launcher.cpp b/core/launcher/launcher.cpp
index 4255b44..4ec5f4c 100644
--- a/core/launcher/launcher.cpp
+++ b/core/launcher/launcher.cpp
@@ -1,819 +1,827 @@
/**********************************************************************
** 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 ),docTabEnabled(true),m_DocumentTabId(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" );
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;
m_DocumentTabId = n;
}
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 );
v->setColNumber( cfg.readNumEntry( "Columns", 0 ) );
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 );
}
}
/*
* FIXME
* The following NULL check is triggered by inserting, then removing a tab on the fly
* as you would if you had removable media (which I do). Without this check
* the first app launched after a tab removal causes qpe to Segfault.
* This obviously has a more sinister cause, but this works around it with no
* obvious adverse effects. Please FIXME
* bkc - 17/6/2004
*
*/
void LauncherTabWidget::setBusy(bool on)
{
if ( on )
currentView()->setBusy(TRUE);
else {
for ( int i = 0; i < categoryBar->count(); i++ ) {
if (categoryBar->tab(i)) {
LauncherView *view = ((LauncherTab *)categoryBar->tab(i))->view;
view->setBusy( FALSE );
} else {
odebug << "Averting Disaster with tab " << i << " == NULL! " << oendl;
}
}
}
}
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 == "setIconColumns(QString,int)" ) {
QString id;
stream >> id;
int number;
stream >> number;
if ( view(id ) )
view(id)->setColNumber( number );
} 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();
}
} else if (msg=="doctabEnabled(int)") {
int id; stream >> id;
odebug << "Doctab enabled " << id << oendl;
reCheckDoctab(id);
+ } else if ( msg == "setStaticBackground(bool)" ) {
+ int set; stream >> set;
+ odebug << "setStaticBackground " << set << oendl;
+ for (int i = 0; i < categoryBar->count(); i++ )
+ {
+ LauncherView* view = static_cast<LauncherTab*>( categoryBar->tab(i) )->view;
+ view->iconView()->setStaticBackgroundPicture( set );
+ }
}
}
void LauncherTabWidget::reCheckDoctab(int how)
{
if ((bool)how == docTabEnabled) {
/* nothing to do */
return;
}
if (docLoadingWidget) {
stack->removeWidget(docLoadingWidget);
delete docLoadingWidget;
docLoadingWidget = 0;
}
createDocLoadingWidget();
{
QCopEnvelope( "QPE/System", "reforceDocuments()" );
odebug << "Sending doc rescan" << oendl;
}
}
//---------------------------------------------------------------------------
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( 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;
}
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 );
if (QPEApplication::execDialog( &prop )==QDialog::Accepted && tabs->currentView()==tabs->docView()) {
}
}
}
void Launcher::storageChanged( const QList<FileSystem> & )
{
// ### 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
owarn << "addAppLnk: No view for type " << type.latin1() << ". Can't add app "
<< 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 )
{
#if 0
documentRemoved( oldDoc );
documentAdded( newDoc );
// tabs->docView()->updateTools();
#else
tabs->docView()->changeItem(oldDoc,new DocLnk(newDoc));
#endif
}
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/launcherview.cpp b/core/launcher/launcherview.cpp
index e7229ee..a4c7561 100644
--- a/core/launcher/launcherview.cpp
+++ b/core/launcher/launcherview.cpp
@@ -1,1250 +1,1260 @@
/**********************************************************************
** 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 "launcherview.h"
/* OPIE */
#include <opie2/odebug.h>
#include <qpe/config.h>
#include <qtopia/qpeapplication.h>
#include <qtopia/private/categories.h>
#include <qtopia/categoryselect.h>
#include <qtopia/mimetype.h>
#include <qtopia/resource.h>
using namespace Opie::Core;
#include <qpe/qcopenvelope_qws.h>
/* QT */
#include <qtimer.h>
#include <qfileinfo.h>
#include <qiconview.h>
#include <qobjectlist.h>
// These define how the busy icon is animated and highlighted
#define BRIGHTEN_BUSY_ICON
//#define ALPHA_FADE_BUSY_ICON
//#define USE_ANIMATED_BUSY_ICON_OVERLAY
#define BOUNCE_BUSY_ICON
typedef QMap<QString,QPixmap>::Iterator pixiter;
class BgPixmap
{
public:
BgPixmap( const QPixmap &p ) : pm(p), ref(1) {}
QPixmap pm;
int ref;
};
static QMap<QString,BgPixmap*> *bgCache = 0;
static void cleanup_cache()
{
QMap<QString,BgPixmap*>::Iterator it = bgCache->begin();
while ( it != bgCache->end() ) {
QMap<QString,BgPixmap*>::Iterator curr = it;
++it;
delete (*curr);
bgCache->remove( curr );
}
delete bgCache;
bgCache = 0;
}
class LauncherItem : public QIconViewItem
{
public:
enum iconstate_t {
BASE_ICON,
WAITING_ICON,
EYE_ICON
};
LauncherItem( QIconView *parent, AppLnk* applnk, bool bigIcon=TRUE );
~LauncherItem();
AppLnk *appLnk() const { return app; }
AppLnk *takeAppLnk() { AppLnk* r=app; app=0; return r; }
void animateIcon();
void resetIcon();
bool isEyeImage()const{return m_EyeImage;}
virtual int compare ( QIconViewItem * i ) const;
void paintItem( QPainter *p, const QColorGroup &cg );
void setBusyIndicatorType ( BusyIndicatorType t ) { busyType = t; }
void setEyePixmap(const QPixmap&aIcon);
virtual QPixmap*pixmap()const;
protected:
bool isBigIcon;
int iteration;
AppLnk* app;
private:
void paintAnimatedIcon( QPainter *p );
BusyIndicatorType busyType;
int psize;
bool m_EyeImage;
iconstate_t m_EyeImageSet;
};
LauncherItem::LauncherItem( QIconView *parent, AppLnk *applnk, bool bigIcon )
: QIconViewItem( parent, applnk->name(),
bigIcon ? applnk->bigPixmap() :applnk->pixmap() ),
isBigIcon( bigIcon ),
iteration(0),
app(applnk), // Takes ownership
psize( (bigIcon ? applnk->bigPixmap().width() :applnk->pixmap().width() ) ),
m_EyeImage(false),
m_EyeImageSet(BASE_ICON)
{
if (applnk->type().lower().startsWith("image/") && applnk->exec().contains("opie-eye",false)) {
m_EyeImage = true;
QMap<QString,QPixmap>::Iterator it = LauncherIconView::sm_EyeCache->find(applnk->file());
if (it != LauncherIconView::sm_EyeCache->end()) {
m_EyeImageSet = EYE_ICON;
setPixmap(*it);
}
}
}
LauncherItem::~LauncherItem()
{
LauncherIconView* liv = (LauncherIconView*)iconView();
if ( liv->busyItem() == this )
liv->setBusy(FALSE);
delete app;
}
QPixmap*LauncherItem::pixmap()const
{
if (m_EyeImage && m_EyeImageSet == BASE_ICON) {
LauncherIconView* liv = (LauncherIconView*)iconView();
liv->requestEyePix(this);
}
return QIconViewItem::pixmap();
}
int LauncherItem::compare ( QIconViewItem * i ) const
{
LauncherIconView* view = (LauncherIconView*)iconView();
return view->compare(app,((LauncherItem *)i)->appLnk());
}
void LauncherItem::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);
// Paint animation overlay
if ( liv->busyItem() == this )
paintAnimatedIcon(p);
if ( liv->currentItem() == this )
liv->setItemTextBackground( oldBrush );
}
void LauncherItem::paintAnimatedIcon( QPainter *p )
{
LauncherIconView* liv = (LauncherIconView*)iconView();
int pic = iteration % 16;
int w = pixmap()->width(), h = pixmap()->height();
QPixmap dblBuf( w, h + 4 );
QPainter p2( &dblBuf );
int x1, y1;
if ( liv->itemTextPos() == QIconView::Bottom ) {
x1 = x() + (width() - w) / 2 - liv->contentsX();
y1 = y() - liv->contentsY();
} else {
x1 = x() - liv->contentsX();
y1 = y() + (height() - h) / 2 - liv->contentsY();
}
y1 -= 2;
p2.translate(-x1,-y1);
liv->drawBackground( &p2, QRect(x1,y1,w,h+4) );
int bounceY = 2;
#ifdef BOUNCE_BUSY_ICON
if ( busyType == BIT_Animated ) {
bounceY = 4 - ((iteration+2)%8);
bounceY = bounceY < 0 ? -bounceY : bounceY;
}
#endif
p2.drawPixmap( x1, y1 + bounceY, *pixmap() );
#ifdef USE_ANIMATED_BUSY_ICON_OVERLAY
p2.drawPixmap( x1, y1 + bounceY, liv->busyPixmap(), w * pic, 0, w, h );
#else
Q_UNUSED( pic )
#endif
p->drawPixmap( x1, y1, dblBuf );
}
void LauncherItem::animateIcon()
{
LauncherIconView* liv = (LauncherIconView*)iconView();
if ( liv->busyItem() != this || !app )
return;
// Highlight the icon
if ( iteration == 0 ) {
QPixmap src;
pixiter it;
if (isEyeImage() && (it=LauncherIconView::sm_EyeCache->find(appLnk()->file()))!=LauncherIconView::sm_EyeCache->end()) {
src = (*it);
} else {
src = ((isBigIcon ? app->bigPixmap() : app->pixmap()));
}
QImage img = src.convertToImage();
QRgb *rgb;
int count;
if ( img.depth() == 32 ) {
rgb = (QRgb*)img.bits();
count = img.bytesPerLine()/sizeof(QRgb)*img.height();
} else {
rgb = img.colorTable();
count = img.numColors();
}
for ( int r = 0; r < count; r++, rgb++ ) {
#if defined(BRIGHTEN_BUSY_ICON)
QColor c(*rgb);
int h, s, v;
c.hsv(&h,&s,&v);
c.setHsv(h,QMAX(s-24,0),QMIN(v+48,255));
*rgb = qRgba(c.red(),c.green(),c.blue(),qAlpha(*rgb));
#elif defined(ALPHA_FADE_BUSY_ICON)
*rgb = qRgba(qRed(*rgb),qGreen(*rgb),qBlue(*rgb),qAlpha(*rgb)/2);
#endif
}
src.convertFromImage( img );
setPixmap( src );
}
iteration++;
// Paint animation overlay
QPainter p( liv->viewport() );
paintAnimatedIcon( &p );
}
void LauncherItem::resetIcon()
{
iteration = 0;
if (isEyeImage()) {
QMap<QString,QPixmap>::Iterator it = LauncherIconView::sm_EyeCache->find(appLnk()->file());
if (it != LauncherIconView::sm_EyeCache->end()) {
setPixmap(*it);
return;
}
}
setPixmap(isBigIcon ? app->bigPixmap() : app->pixmap());
}
void LauncherItem::setEyePixmap(const QPixmap&aIcon)
{
if (!isEyeImage()) return;
setPixmap(aIcon);
m_EyeImageSet = EYE_ICON;
}
//===========================================================================
// Implemantation of LauncherIconview start
//===========================================================================
QMap<QString,QPixmap>* LauncherIconView::sm_EyeCache=0;
LauncherIconView::LauncherIconView( QWidget* parent, const char* name )
: QIconView(parent,name),tf(""),cf(0),bsy(0),busyTimer(0),bigIcns(TRUE),bgColor(white),numColumns(0)
{
m_EyeCallBack = 0;
if (!sm_EyeCache) sm_EyeCache = new QMap<QString,QPixmap>();
sortmeth = Name;
hidden.setAutoDelete(TRUE);
ike = FALSE;
calculateGrid( Bottom );
connect(&m_eyeTimer,SIGNAL(timeout()),this,SLOT(stopEyeTimer()));
Config config( "Launcher" );
config.setGroup( "GUI" );
- staticBackground = config.readEntry( "StaticBackground", false );
- if ( staticBackground )
- {
- setStaticBackground( true );
- verticalScrollBar()->setTracking( false );
- }
+ setStaticBackgroundPicture( config.readBoolEntry( "StaticBackground", true ) );
}
LauncherIconView::~LauncherIconView()
{
odebug << "LauncherIconView::~LauncherIconView()" << oendl;
#if 0 // debuggery
QListIterator<AppLnk> it(hidden);
AppLnk* l;
while ((l=it.current())) {
++it;
//odebug << "" << l << ": hidden (should remove)" << oendl;
}
#endif
}
+void LauncherIconView::setStaticBackgroundPicture( bool enable )
+{
+ staticBackground = enable;
+ if ( staticBackground )
+ {
+ setStaticBackground( true );
+ verticalScrollBar()->setTracking( false );
+ }
+ else
+ {
+ setStaticBackground( false );
+ verticalScrollBar()->setTracking( true );
+ }
+}
+
int LauncherIconView::compare(const AppLnk* a, const AppLnk* b)
{
switch (sortmeth) {
case Name:
return a->name().lower().compare(b->name().lower());
case Date: {
QFileInfo fa(a->linkFileKnown() ? a->linkFile() : a->file());
QFileInfo fb(b->linkFileKnown() ? b->linkFile() : b->file());
return fa.lastModified().secsTo(fb.lastModified());
}
case Type:
return a->type().compare(b->type());
}
return 0;
}
void LauncherIconView::setSortMethod( SortMethod m )
{
if ( sortmeth != m ) {
sortmeth = m;
sort();
}
}
void LauncherIconView::setCategoryFilter( int catfilter, bool resort )
{
if ( catfilter == -2 )
cf = 0;
else
cf = catfilter;
hideOrShowItems(resort);
}
void LauncherIconView::setTypeFilter(const QString& typefilter, bool resort)
{
tf = QRegExp(typefilter,FALSE,TRUE);
hideOrShowItems(resort);
}
void LauncherIconView::setItemTextPos( ItemTextPos pos )
{
calculateGrid( pos );
QIconView::setItemTextPos( pos );
}
void LauncherIconView::drawBackground( QPainter *p, const QRect &r )
{
if ( bgPixmap.isNull() )
{
p->fillRect( r, bgColor );
}
else
{
if ( staticBackground )
{
- p->drawPixmap( r.x(), r.y(), bgPixmap, r.x(), r.y(), r.width(), r.height() );
+ p->drawTiledPixmap( r, bgPixmap, QPoint( r.x() % bgPixmap.width(), r.y() % bgPixmap.height() ) );
}
else
{
- p->drawTiledPixmap( r, bgPixmap, QPoint( (r.x() + contentsX()) % bgPixmap.width(),
- (r.y() + contentsY()) % bgPixmap.height() ) );
+ p->drawTiledPixmap( r, bgPixmap, QPoint( (r.x() + contentsX()) % bgPixmap.width(),
+ (r.y() + contentsY()) % bgPixmap.height() ) );
}
}
}
void LauncherIconView::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;
k = maj.left(12) == "application/" ? maj : maj.left(sl);
mimes.replace(k,(void*)1);
}
}
void LauncherIconView::setBusy(bool on)
{
#ifdef USE_ANIMATED_BUSY_ICON_OVERLAY
if ( busyPix.isNull() ) {
int size = ( bigIcns ) ? AppLnk::bigIconSize() : AppLnk::smallIconSize();
busyPix.convertFromImage( Resource::loadImage( "busy" ).smoothScale( size * 16, size ) );
}
#endif
if ( on ) {
busyTimer = startTimer( 100 );
} else {
if ( busyTimer ) {
killTimer( busyTimer );
busyTimer = 0;
}
}
LauncherItem *c = on ? (LauncherItem*)currentItem() : 0;
if ( bsy != c ) {
LauncherItem *oldBusy = bsy;
bsy = c;
if ( oldBusy ) {
oldBusy->resetIcon();
}
if ( bsy ) {
bsy->setBusyIndicatorType( busyType ) ;
bsy->animateIcon();
}
}
}
void LauncherIconView::clear()
{
mimes.clear();
cats.clear();
QIconView::clear();
hidden.clear();
}
QStringList LauncherIconView::mimeTypes() const
{
QStringList r;
QDictIterator<void> it(mimes);
while (it.current()) {
r.append(it.currentKey());
++it;
}
r.sort();
return r;
}
LauncherItem*LauncherIconView::findDocItem(const QString&fname)
{
LauncherItem* item = (LauncherItem*)firstItem();
while (item) {
if (item->appLnk()->file()==fname) {
break;
}
item = (LauncherItem*)item->nextItem();
}
return item;
}
void LauncherIconView::setEyePixmap(const QPixmap&aPixmap,const QString&aFile,int width)
{
int s = ( bigIcns ) ? AppLnk::bigIconSize() : AppLnk::smallIconSize();
if (s!=width) return;
LauncherItem*item = findDocItem(aFile);
if (!item||!item->isEyeImage()) return;
(*sm_EyeCache)[aFile]=aPixmap;
item->setEyePixmap(aPixmap);
}
void LauncherIconView::checkCallback()
{
if (!m_EyeCallBack) {
m_EyeCallBack = new LauncherThumbReceiver();
connect(m_EyeCallBack,SIGNAL(sig_Thumbnail(const QPixmap&,const QString&,int)),
this,SLOT(setEyePixmap(const QPixmap&,const QString&,int)));
}
m_eyeTimer.changeInterval(600000);
}
void LauncherIconView::addCheckItem(AppLnk* app)
{
LauncherItem*item = new LauncherItem( this, app, bigIcns );
if (item->isEyeImage()) {
checkCallback();
}
}
void LauncherIconView::requestEyePix(const LauncherItem*item)
{
if (!item) return;
if (item->isEyeImage()) {
checkCallback();
int s = ( bigIcns ) ? AppLnk::bigIconSize() : AppLnk::smallIconSize();
m_EyeCallBack->requestThumb(item->appLnk()->file(),s,s);
}
}
void LauncherIconView::stopEyeTimer()
{
if (m_EyeCallBack) {
disconnect(m_EyeCallBack,SIGNAL(sig_Thumbnail(const QPixmap&,const QString&,int)),
this,SLOT(setEyePixmap(const QPixmap&,const QString&,int)));
delete m_EyeCallBack;
m_EyeCallBack=0;
}
m_eyeTimer.stop();
}
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)
{
viewport()->setUpdatesEnabled( FALSE );
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 && !autoArrange() )
sort();
viewport()->setUpdatesEnabled( TRUE );
}
bool LauncherIconView::removeLink(const QString& linkfile,bool removeCache)
{
LauncherItem* item = (LauncherItem*)firstItem();
AppLnk* l;
bool did = FALSE;
DocLnk dl(linkfile);
while (item) {
l = item->appLnk();
LauncherItem *nextItem = (LauncherItem *)item->nextItem();
if ( l->linkFileKnown() && l->linkFile() == linkfile || l->fileKnown() &&
( l->file() == linkfile || dl.isValid() && dl.file() == l->file() ) ) {
if (removeCache) sm_EyeCache->remove(l->file());
delete item;
did = TRUE;
}
item = nextItem;
}
QListIterator<AppLnk> it(hidden);
while ((l=it.current())) {
++it;
if ( l->linkFileKnown() && l->linkFile() == linkfile
|| l->file() == linkfile
|| dl.isValid() && dl.file() == l->file() ) {
hidden.removeRef(l);
did = TRUE;
}
}
return did;
}
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 ) ) {
addCheckItem(app);
} else {
hidden.append(app);
}
if ( resort ){
sort();
}
}
void LauncherIconView::changeItem(const AppLnk&old,AppLnk*nlink)
{
QString oldfile = old.file();
QString newfile = nlink->file();
if (newfile != oldfile) {
QMap<QString,QPixmap>::Iterator it = sm_EyeCache->find(oldfile);
if (it != sm_EyeCache->end()) {
(*sm_EyeCache)[newfile]=(*it);
}
removeLink(old.linkFile());
} else {
removeLink(old.linkFile(),false);
}
addItem(nlink,false);
}
void LauncherIconView::timerEvent( QTimerEvent *te )
{
if ( te->timerId() == busyTimer ) {
if ( bsy )
bsy->animateIcon();
} else {
QIconView::timerEvent( te );
}
}
void LauncherIconView::setBigIcons( bool bi )
{
sm_EyeCache->clear();
bigIcns = bi;
#ifdef USE_ANIMATED_BUSY_ICON_OVERLAY
busyPix.resize(0,0);
#endif
}
QIconViewItem* LauncherIconView::busyItem() const
{
return bsy;
}
void LauncherIconView::setBusyIndicatorType ( BusyIndicatorType t ) { busyType = t; }
void LauncherIconView::calculateGrid( ItemTextPos pos )
{
int dw = QApplication::desktop()->width();
int viewerWidth = dw-style().scrollBarExtent().width();
if ( pos == Bottom ) {
if( !numColumns ) {
if ( viewerWidth <= 200 ) numColumns = 2;
else if ( viewerWidth >= 400 ) numColumns = viewerWidth/96;
else numColumns = 3;
}
setSpacing( 4 );
setGridX( (viewerWidth-(numColumns+1)*spacing())/numColumns );
setGridY( fontMetrics().height()*2+24 );
} else {
if( !numColumns ) {
if ( viewerWidth < 150 ) numColumns = 1;
else if ( viewerWidth >= 400 ) numColumns = viewerWidth/150;
else numColumns = 2;
}
setSpacing( 2 );
setGridX( (viewerWidth-(numColumns+1)*spacing())/numColumns );
setGridY( fontMetrics().height()+2 );
}
}
void LauncherIconView::styleChange( QStyle &old )
{
QIconView::styleChange( old );
calculateGrid( itemTextPos() );
}
void LauncherIconView::keyPressEvent(QKeyEvent* e)
{
ike = TRUE;
if ( e->key() == Key_F33 /* OK button */ || e->key() == Key_Space ) {
if ( (e->state() & ShiftButton) )
emit mouseButtonPressed(ShiftButton, currentItem(), QPoint() );
else
returnPressed(currentItem());
}
QIconView::keyPressEvent(e);
ike = FALSE;
}
//===========================================================================
// Implemantation of LauncherIconview end
//===========================================================================
//===========================================================================
LauncherView::LauncherView( QWidget* parent, const char* name, WFlags fl )
: QVBox( parent, name, fl )
{
catmb = 0;
icons = new LauncherIconView( this );
setFocusProxy(icons);
QPEApplication::setStylusOperation( icons->viewport(), QPEApplication::RightOnHold );
icons->setItemsMovable( FALSE );
icons->setAutoArrange( TRUE );
icons->setSorting( TRUE );
icons->setFrameStyle( QFrame::NoFrame );
icons->setMargin( 0 );
icons->setSelectionMode( QIconView::NoSelection );
icons->setBackgroundMode( PaletteBase );
icons->setResizeMode( QIconView::Adjust );
vmode = (ViewMode)-1;
setViewMode( Icon );
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;
setBackgroundType( Ruled, QString::null );
}
LauncherView::~LauncherView()
{
if ( bgCache && bgCache->contains( bgName ) )
(*bgCache)[bgName]->ref--;
}
bool LauncherView::bsy=FALSE;
void LauncherView::setBusy(bool on)
{
icons->setBusy(on);
}
void LauncherView::setBusyIndicatorType( const QString& type ) {
if ( type. lower ( ) == "animated" )
icons->setBusyIndicatorType( BIT_Animated ) ;
else
icons->setBusyIndicatorType( BIT_Normal ) ;
}
void LauncherView::hideIcons()
{
icons->hide();
}
void LauncherView::setToolsEnabled(bool y)
{
if ( !y != !tools ) {
if ( y ) {
tools = new QHBox(this);
// Type filter
typemb = new QComboBox(tools);
QSizePolicy p = typemb->sizePolicy();
p.setHorData(QSizePolicy::Expanding);
typemb->setSizePolicy(p);
// Category filter
updateTools();
tools->show();
} else {
delete tools;
tools = 0;
}
}
}
void LauncherView::updateTools()
{
disconnect( typemb, SIGNAL(activated(int)),
this, SLOT(showType(int)) );
if ( catmb ) {
disconnect( catmb, SIGNAL(signalSelected(int)),this,SLOT(showCategory(int)));
}
// ### I want to remove this
icons->updateCategoriesAndMimeTypes();
QString prev;
// Type filter
QStringList types;
typelist = icons->mimeTypes();
for (QStringList::ConstIterator it = typelist.begin(); it!=typelist.end(); ++it) {
QString t = *it;
if ( t.left(12) == "application/" ) {
MimeType mt(t);
const AppLnk* app = mt.application();
if ( app )
t = app->name();
else
t = t.mid(12);
} else {
t[0] = t[0].upper();
}
types += t;
}
types << tr("All types");
prev = typemb->currentText();
typemb->clear();
typemb->insertStringList(types);
for (int i=0; i<typemb->count(); i++) {
if ( typemb->text(i) == prev ) {
typemb->setCurrentItem(i);
break;
}
}
if ( prev.isNull() ) {
typemb->setCurrentItem(typemb->count()-1);
}
int pcat = catmb ? catmb->currentCategory() : -2;
if ( !catmb ) {
catmb = new CategorySelect(tools);
} else if (pcat!=-2) {
}
Categories cats( 0 );
cats.load( categoryFileName() );
QArray<int> vl( 0 );
catmb->setCategories( vl, "Document View", // No tr
tr("Document View") );
catmb->setRemoveCategoryEdit( TRUE );
catmb->setAllCategories( TRUE );
catmb->setCurrentCategory(pcat);
// if type has changed we need to redisplay
if ( typemb->currentText() != prev )
showType( typemb->currentItem() );
connect(typemb, SIGNAL(activated(int)), this, SLOT(showType(int)));
connect(catmb, SIGNAL(signalSelected(int)), this, SLOT(showCategory(int)));
}
void LauncherView::sortBy(int s)
{
icons->setSortMethod((LauncherIconView::SortMethod)s);
}
void LauncherView::showType(int t)
{
if ( t >= (int)typelist.count() ) {
icons->setTypeFilter("",TRUE);
} else {
QString ty = typelist[t];
if ( !ty.contains('/') )
ty += "/*";
icons->setTypeFilter(ty,TRUE);
}
}
void LauncherView::showCategory( int c )
{
icons->setCategoryFilter( c, TRUE );
}
void LauncherView::setViewMode( ViewMode m )
{
odebug << "LauncherView::setViewMode( ViewMode m )" << oendl;
if ( vmode != m ) {
bool bigIcons = m == Icon;
icons->viewport()->setUpdatesEnabled( FALSE );
icons->setBigIcons( bigIcons );
switch ( m ) {
case List:
icons->setItemTextPos( QIconView::Right );
break;
case Icon:
icons->setItemTextPos( QIconView::Bottom );
break;
}
icons->hideOrShowItems( FALSE );
icons->viewport()->setUpdatesEnabled( TRUE );
vmode = m;
}
}
//
// User images may require scaling.
//
QImage LauncherView::loadBackgroundImage(QString &bgName)
{
QImageIO imgio;
QSize ds = qApp->desktop()->size(); // should be launcher, not desktop
bool further_scaling = TRUE;
imgio.setFileName( bgName );
imgio.setParameters("GetHeaderInformation");
if (imgio.read() == FALSE) {
return imgio.image();
}
if (imgio.image().width() < ds.width() &&
imgio.image().height() < ds.height()) {
further_scaling = FALSE;
}
if (!imgio.image().bits()) {
//
// Scale and load. Note we don't scale up.
//
QString param( "Scale( %1, %2, ScaleMin )" ); // No tr
imgio.setParameters(further_scaling ?
param.arg(ds.width()).arg(ds.height()).latin1() :
"");
imgio.read();
} else {
if (further_scaling) {
int t1 = imgio.image().width() * ds.height();
int t2 = imgio.image().height() * ds.width();
int dsth = ds.height();
int dstw = ds.width();
if (t1 > t2) {
dsth = t2 / imgio.image().width();
} else {
dstw = t1 / imgio.image().height();
}
//
// Loader didn't scale for us. Do it manually.
//
return imgio.image().smoothScale(dstw, dsth);
}
}
return imgio.image();
}
void LauncherView::setBackgroundType( BackgroundType t, const QString &val )
{
if ( !bgCache ) {
bgCache = new QMap<QString,BgPixmap*>;
qAddPostRoutine( cleanup_cache );
}
if ( bgCache->contains( bgName ) )
(*bgCache)[bgName]->ref--;
bgName = "";
QPixmap bg;
switch ( t ) {
case Ruled: {
bgName = QString("Ruled_%1").arg(colorGroup().background().name()); // No tr
if ( bgCache->contains( bgName ) ) {
(*bgCache)[bgName]->ref++;
bg = (*bgCache)[bgName]->pm;
} else {
bg.resize( 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 );
}
painter.end();
bgCache->insert( bgName, new BgPixmap(bg) );
}
break;
}
case Image:
if (!val.isEmpty()) {
bgName = val;
if ( bgCache->contains( bgName ) ) {
(*bgCache)[bgName]->ref++;
bg = (*bgCache)[bgName]->pm;
} else {
QString imgFile = bgName;
bool tile = FALSE;
if ( imgFile[0]!='/' || !QFile::exists(imgFile) ) {
imgFile = Resource::findPixmap( imgFile );
tile = TRUE;
}
QImage img = loadBackgroundImage(imgFile);
if ( img.depth() == 1 )
img = img.convertDepth(8);
img.setAlphaBuffer(FALSE);
bg.convertFromImage(img);
bgCache->insert( bgName, new BgPixmap(bg) );
}
}
break;
case SolidColor:
default:
break;
}
const QObjectList *list = queryList( "QWidget", 0, FALSE );
QObject *obj;
for ( QObjectListIt it( *list ); (obj=it.current()); ++it ) {
if ( obj->isWidgetType() ) {
QWidget *w = (QWidget*)obj;
w->setBackgroundPixmap( bg );
if ( bgName.isEmpty() ) {
// Solid Color
if ( val.isEmpty() )
w->setBackgroundColor( colorGroup().base() );
else
w->setBackgroundColor( val );
} else {
// Ruled or Image pixmap
w->setBackgroundOrigin( ParentOrigin );
}
}
}
delete list;
bgType = t;
icons->viewport()->update();
QTimer::singleShot( 1000, this, SLOT(flushBgCache()) );
}
void LauncherView::setColNumber( int num )
{
icons->setColNumber( num );
}
void LauncherIconView::setColNumber( int num )
{
numColumns = num;
calculateGrid( Bottom );
}
void LauncherView::setTextColor( const QColor &tc )
{
textCol = tc;
QColorGroup cg = icons->colorGroup();
cg.setColor( QColorGroup::Text, tc );
icons->setPalette( QPalette(cg,cg,cg) );
icons->viewport()->update();
}
void LauncherView::setViewFont( const QFont &f )
{
icons->setFont( f );
icons->hideOrShowItems( FALSE );
}
void LauncherView::clearViewFont()
{
icons->unsetFont();
icons->hideOrShowItems( FALSE );
}
void LauncherView::resizeEvent(QResizeEvent *e)
{
// qDebug("LauncherView resize event");
QVBox::resizeEvent( e );
// commented out for launcherview and qt/e 2.3.8 problems, probably needs real fixing somewhere...
// if ( e->size().width() != e->oldSize().width() )
sort();
}
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 == ShiftButton )
emit rightPressed( appLnk );
item->setSelected(FALSE);
}
}
void LauncherView::removeAllItems()
{
odebug << "LauncherView::removeAllItems()" << oendl;
if (LauncherIconView::sm_EyeCache) LauncherIconView::sm_EyeCache->clear();
icons->clear();
}
bool LauncherView::removeLink(const QString& linkfile)
{
return icons->removeLink(linkfile);
}
void LauncherView::addItem(AppLnk* app, bool resort)
{
icons->addItem(app,resort);
}
void LauncherView::changeItem(const AppLnk&old,AppLnk*nlink)
{
icons->changeItem(old,nlink);
}
void LauncherView::setSortEnabled( bool v )
{
icons->setSorting( v );
if ( v )
sort();
}
void LauncherView::setUpdatesEnabled( bool u )
{
icons->setUpdatesEnabled( u );
}
void LauncherView::sort()
{
icons->sort();
}
void LauncherView::paletteChange( const QPalette &p )
{
icons->unsetPalette();
QVBox::paletteChange( p );
if ( bgType == Ruled )
setBackgroundType( Ruled, QString::null );
QColorGroup cg = icons->colorGroup();
cg.setColor( QColorGroup::Text, textCol );
icons->setPalette( QPalette(cg,cg,cg) );
}
void LauncherView::fontChanged(const QFont&)
{
odebug << "LauncherView::fontChanged()" << oendl;
icons->hideOrShowItems( FALSE );
}
void LauncherView::relayout(void)
{
icons->hideOrShowItems(FALSE);
}
void LauncherView::flushBgCache()
{
if ( !bgCache )
return;
// remove unreferenced backgrounds.
QMap<QString,BgPixmap*>::Iterator it = bgCache->begin();
while ( it != bgCache->end() ) {
QMap<QString,BgPixmap*>::Iterator curr = it;
++it;
if ( (*curr)->ref == 0 ) {
delete (*curr);
bgCache->remove( curr );
}
}
}
/*
* Launcherthumbnail handling for image files
*/
/* special image handling - based on opie eye */
QDataStream &operator>>( QDataStream& s, PixmapInfo& inf ) {
s >> inf.file >> inf.pixmap >> inf.width >> inf.height;
return s;
}
QDataStream &operator<<( QDataStream& s, const PixmapInfo& inf) {
return s << inf.file << inf.width << inf.height;
}
LauncherThumbReceiver::LauncherThumbReceiver()
:QObject()
{
QCopChannel * chan = new QCopChannel( "QPE/opie-eye",this );
connect(chan, SIGNAL(received(const QCString&,const QByteArray&)),
this, SLOT(recieve(const QCString&,const QByteArray&)) );
{
QCopEnvelope( "QPE/Application/opie-eye_slave", "refUp()" );
}
}
LauncherThumbReceiver::~LauncherThumbReceiver()
{
{
QCopEnvelope( "QPE/Application/opie-eye_slave", "refDown()" );
}
}
void LauncherThumbReceiver::recieve( const QCString&str, const QByteArray&at )
{
PixmapInfos pixinfos;
QDataStream stream( at, IO_ReadOnly );
/* we are just interested in thumbmails */
if ( str == "pixmapsHandled(PixmapList)" )
stream >> pixinfos;
for ( PixmapInfos::Iterator it = pixinfos.begin(); it != pixinfos.end(); ++it ) {
emit sig_Thumbnail((*it).pixmap,(*it).file,(*it).width);
}
}
void LauncherThumbReceiver::requestThumb(const QString&file,int width,int height)
{
PixmapInfo rItem;
rItem.file = file;
rItem.width = width;
rItem.height = height;
m_inThumbNail.append(rItem);
QTimer::singleShot(2, this, SLOT(sendRequest()));
}
void LauncherThumbReceiver::sendRequest()
{
if (m_inThumbNail.count()>0) {
QCopEnvelope env("QPE/opie-eye_slave", "pixmapInfos(PixmapInfos)" );
env << m_inThumbNail;
m_inThumbNail.clear();
}
}
diff --git a/core/launcher/launcherview.h b/core/launcher/launcherview.h
index 97b1dea..6a2d197 100644
--- a/core/launcher/launcherview.h
+++ b/core/launcher/launcherview.h
@@ -1,254 +1,255 @@
/**********************************************************************
** 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 LAUNCHERVIEW_H
#define LAUNCHERVIEW_H
#include <qtopia/storage.h>
#include <qtopia/applnk.h>
#include <qvbox.h>
#include <qiconview.h>
#include <qtimer.h>
#include <qmap.h>
class CategorySelect;
class LauncherIconView;
class LauncherItem;
class QIconViewItem;
class QLabel;
class QWidgetStack;
class MenuButton;
class QComboBox;
enum BusyIndicatorType {
BIT_Normal = 0,
BIT_Animated
};
class LauncherView : public QVBox
{
Q_OBJECT
public:
LauncherView( QWidget* parent = 0, const char* name = 0, WFlags fl = 0 );
~LauncherView();
void hideIcons();
bool removeLink(const QString& linkfile);
void addItem(AppLnk* app, bool resort=TRUE);
void changeItem(const AppLnk&old,AppLnk*nlink);
void removeAllItems();
void setSortEnabled(bool);
void setUpdatesEnabled(bool);
void sort();
void setToolsEnabled(bool);
void updateTools();
void setBusy(bool);
void setBusyIndicatorType( const QString& );
enum ViewMode { Icon, List };
void setViewMode( ViewMode m );
ViewMode viewMode() const { return vmode; }
enum BackgroundType { Ruled, SolidColor, Image };
void setBackgroundType( BackgroundType t, const QString & );
BackgroundType backgroundType() const { return bgType; }
void setTextColor( const QColor & );
QColor textColor() const { return textCol; }
void setViewFont( const QFont & );
void clearViewFont();
void setColNumber( int );
-
void relayout(void);
+ LauncherIconView* iconView() { return icons; };
signals:
void clicked( const AppLnk * );
void rightPressed( AppLnk * );
protected slots:
void selectionChanged();
void returnPressed( QIconViewItem *item );
void itemClicked( int, QIconViewItem * );
void itemPressed( int, QIconViewItem * );
void sortBy(int);
void showType(int);
void showCategory( int );
void resizeEvent(QResizeEvent *);
void flushBgCache();
protected:
void paletteChange( const QPalette & );
void fontChanged(const QFont &);
private:
static bool bsy;
QWidget* tools;
LauncherIconView* icons;
QComboBox *typemb;
QStringList typelist;
CategorySelect *catmb;
ViewMode vmode;
BackgroundType bgType;
QString bgName;
QColor textCol;
QImage loadBackgroundImage(QString &fname);
};
/* from opie-eye */
struct PixmapInfo {
PixmapInfo() : width( -1 ), height( -1 ) {}
bool operator==( const PixmapInfo& r ) {
if ( width != r.width ) return false;
if ( height != r.height ) return false;
if ( file != r.file ) return false;
return true;
}
int width, height;
QString file;
QPixmap pixmap;
};
class LauncherThumbReceiver:public QObject
{
Q_OBJECT
typedef QValueList<PixmapInfo> PixmapInfos;
public:
LauncherThumbReceiver();
~LauncherThumbReceiver();
void requestThumb(const QString&file,int width,int height);
public slots:
void recieve( const QCString&, const QByteArray& );
protected slots:
virtual void sendRequest();
signals:
void sig_Thumbnail(const QPixmap&,const QString&,int);
protected:
PixmapInfos m_inThumbNail;
};
class LauncherIconView : public QIconView {
Q_OBJECT
public:
LauncherIconView( QWidget* parent, const char* name=0 );
~LauncherIconView();
QIconViewItem* busyItem() const;
#ifdef USE_ANIMATED_BUSY_ICON_OVERLAY
QPixmap busyPixmap() const { return busyPix; }
#endif
void setBigIcons( bool bi );
void updateCategoriesAndMimeTypes();
void setBusyIndicatorType ( BusyIndicatorType t );
+ void setStaticBackgroundPicture( bool enable );
void doAutoScroll()
{
// We don't want rubberbanding (yet)
}
void setBusy(bool on);
bool inKeyEvent() const { return ike; }
void addItem(AppLnk* app, bool resort=TRUE);
bool removeLink(const QString& linkfile,bool removeCache = true);
void changeItem(const AppLnk&old,AppLnk*nlink);
QStringList mimeTypes() const;
QStringList categories() const;
void clear();
void addCatsAndMimes(AppLnk* app);
void setBackgroundOrigin( QWidget::BackgroundOrigin ) {}
void setBackgroundPixmap( const QPixmap &pm ) {
bgPixmap = pm;
}
void setBackgroundColor( const QColor &c ) {
bgColor = c;
}
void setColNumber( int );
void drawBackground( QPainter *p, const QRect &r );
void setItemTextPos( ItemTextPos pos );
void hideOrShowItems(bool resort);
void setTypeFilter(const QString& typefilter, bool resort);
void setCategoryFilter( int catfilter, bool resort );
enum SortMethod { Name, Date, Type };
void setSortMethod( SortMethod m );
int compare(const AppLnk* a, const AppLnk* b);
void requestEyePix(const LauncherItem*which);
static QMap<QString,QPixmap>* sm_EyeCache;
protected:
virtual void timerEvent( QTimerEvent *te );
void styleChange( QStyle &old );
void calculateGrid( ItemTextPos pos );
void focusInEvent( QFocusEvent * ) {}
void focusOutEvent( QFocusEvent * ) {}
LauncherItem*findDocItem(const QString&);
void addCheckItem(AppLnk* app);
void checkCallback();
virtual void keyPressEvent(QKeyEvent* e);
protected slots:
void setEyePixmap(const QPixmap&,const QString&,int width);
void stopEyeTimer();
private:
QList<AppLnk> hidden;
QDict<void> mimes;
QDict<void> cats;
SortMethod sortmeth;
QRegExp tf;
int cf;
LauncherItem* bsy;
int busyTimer;
bool ike;
bool bigIcns;
QPixmap bgPixmap;
QColor bgColor;
LauncherThumbReceiver*m_EyeCallBack;
#ifdef USE_ANIMATED_BUSY_ICON_OVERLAY
QPixmap busyPix;
#endif
BusyIndicatorType busyType;
QTimer m_eyeTimer;
int numColumns;
bool staticBackground;
};
#endif // LAUNCHERVIEW_H
diff --git a/core/settings/launcher/tabssettings.cpp b/core/settings/launcher/tabssettings.cpp
index 42f0568..fca6b20 100644
--- a/core/settings/launcher/tabssettings.cpp
+++ b/core/settings/launcher/tabssettings.cpp
@@ -1,330 +1,339 @@
/*
               =. This file is part of the OPIE Project
             .=l. Copyright (c) 2002 Robert Griebl <sandman@handhelds.org>
           .>+-=
 _;:,     .>    :=|. This file is free software; you can
.> <`_,   >  .   <= redistribute it and/or modify it under
:`=1 )Y*s>-.--   : the terms of the GNU General Public
.="- .-=="i,     .._ License as published by the Free Software
 - .   .-<_>     .<> Foundation; either version 2 of the License,
     ._= =}       : or (at your option) any later version.
    .%`+i>       _;_.
    .i_,=:_.      -<s. This file is distributed in the hope that
     +  .  -:.       = it will be useful, but WITHOUT ANY WARRANTY;
    : ..    .:,     . . . without even the implied warranty of
    =_        +     =;=|` MERCHANTABILITY or FITNESS FOR A
  _.=:.       :    :=>`: PARTICULAR PURPOSE. See the GNU General
..}^=.=       =       ; Public License for more details.
++=   -.     .`     .:
 :     =  ...= . :.=- You should have received a copy of the GNU
 -.   .:....=;==+<; General Public License along with this file;
  -_. . .   )=.  = see the file COPYING. If not, write to the
    --        :-=` Free Software Foundation, Inc.,
59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
*/
#include "tabssettings.h"
#include <qpe/resource.h>
#include <qpe/applnk.h>
#include <qpe/mimetype.h>
#include <qpe/qcopenvelope_qws.h>
#include <qpe/config.h>
#include <qpe/qpeapplication.h>
#include <qlistbox.h>
#include <qpushbutton.h>
#include <qlayout.h>
#include <qlabel.h>
#include <qwhatsthis.h>
#include <qcheckbox.h>
#include "tabdialog.h"
#include <stdlib.h>
#include <qmessagebox.h>
#define GLOBALID ".global."
TabsSettings::TabsSettings ( QWidget *parent, const char *name )
: QWidget ( parent, name )
{
QGridLayout *lay = new QGridLayout ( this, 0, 0, 4, 4 );
QLabel *l = new QLabel ( tr( "Launcher Tabs:" ), this );
lay-> addMultiCellWidget ( l, 0, 0, 0, 1 );
m_list = new QListBox ( this );
lay-> addMultiCellWidget ( m_list, 1, 4, 0, 0 );
QWhatsThis::add ( m_list, tr( "foobar" ));
QPushButton *p1, *p2, *p3;
p1 = new QPushButton ( tr( "New" ), this );
lay-> addWidget ( p1, 1, 1 );
connect ( p1, SIGNAL( clicked()), this, SLOT( newClicked()));
p2 = new QPushButton ( tr( "Edit" ), this );
lay-> addWidget ( p2, 2, 1 );
connect ( p2, SIGNAL( clicked()), this, SLOT( editClicked()));
p3 = new QPushButton ( tr( "Delete" ), this );
lay-> addWidget ( p3, 3, 1 );
connect ( p3, SIGNAL( clicked()), this, SLOT( deleteClicked()));
lay-> setRowStretch ( 4, 10 );
m_bigbusy = new QCheckBox( tr( "Enable big busy indicator" ), this );
lay-> addMultiCellWidget ( m_bigbusy, 5, 5, 0, 1 );
m_busyani = new QCheckBox ( tr( "Enable animated busy indicator" ), this );
lay-> addMultiCellWidget ( m_busyani, 6, 6, 0, 1 );
+
+ m_staticbackground = new QCheckBox( tr( "Enable static background pixmap" ), this );
+ lay->addMultiCellWidget( m_staticbackground, 7, 7, 0, 1 );
p1-> setEnabled ( false );
p3-> setEnabled ( false );
init ( );
QWhatsThis::add ( m_list, tr( "Select the Launcher Tab you want to edit or delete." ));
QWhatsThis::add ( p1, tr( "Adds a new Tab to the Launcher." ) + QString ( "<center><br><i>not yet implemented</i><br>Please use the tabmanager</center>." ));
QWhatsThis::add ( p2, tr( "Opens a new dialog to customize the select Tab." ));
QWhatsThis::add ( p3, tr( "Deletes a Tab from the Launcher." ) + QString ( "<center><br><i>not yet implemented</i><br>Please use the tabmanager</center>." ));
QWhatsThis::add ( m_bigbusy, tr( "Activate this, if you want a big busy indicator in the middle of the screen instead of the one in taskbar." ));
QWhatsThis::add ( m_busyani, tr( "Activate this, if you want an animatedbusy indicator for starting applications in the Launcher." ));
+ QWhatsThis::add ( m_staticbackground, tr( "Activate this, if you want the background pixmap not to scroll with the icons." ));
}
void TabsSettings::init ( )
{
AppLnkSet rootFolder( MimeType::appsFolderName ( ));
QStringList types = rootFolder. types ( );
m_list-> insertItem ( tr( "All Tabs" ));
m_ids << GLOBALID;
for ( QStringList::Iterator it = types. begin ( ); it != types. end ( ); ++it ) {
m_list-> insertItem ( rootFolder. typePixmap ( *it ), rootFolder. typeName ( *it ));
m_ids << *it;
}
QImage img ( Resource::loadImage ( "DocsIcon" ));
QPixmap pix;
pix = img. smoothScale ( AppLnk::smallIconSize ( ), AppLnk::smallIconSize ( ));
m_list-> insertItem ( pix, tr( "Documents" ));
m_ids += "Documents"; // No tr
Config cfg ( "Launcher" );
readTabSettings ( cfg );
cfg. setGroup ( "GUI" );
m_busyani-> setChecked ( cfg. readEntry ( "BusyType" ). lower ( ) == "animated" );
m_bigbusy->setChecked( cfg. readBoolEntry ( "BigBusy" ) );
+ m_staticbackground->setChecked( cfg.readBoolEntry( "StaticBackground", true ) );
}
void TabsSettings::readTabSettings ( Config &cfg )
{
QString grp ( "Tab %1" ); // No tr
m_tabs. clear ( );
TabConfig global_def;
global_def. m_view = TabConfig::Icon;
global_def. m_bg_type = TabConfig::Ruled;
global_def. m_bg_image = "launcher/opie-background";
global_def. m_bg_color = colorGroup ( ). color ( QColorGroup::Base ). name ( );
global_def. m_iconcolumns = 0; // automatic
global_def. m_text_color = colorGroup ( ). color ( QColorGroup::Text ). name ( );
global_def. m_font_use = false;
global_def. m_font_family = font ( ). family ( );
global_def. m_font_size = font ( ). pointSize ( );
global_def. m_font_weight = 50;
global_def. m_font_italic = false;
global_def. m_changed = false;
Config cfg2 = Config( "Launchersettings" );
for ( QStringList::Iterator it = m_ids. begin ( ); it != m_ids. end ( ); ++it ) {
TabConfig tc = ( it != m_ids. begin ( )) ? m_tabs [GLOBALID] : global_def;
cfg. setGroup ( grp. arg ( *it ));
cfg2. setGroup( grp. arg ( *it ));
QString view = cfg. readEntry ( "View" );
if ( view == "Icon" ) // No tr
tc. m_view = TabConfig::Icon;
if ( view == "List" ) // No tr
tc. m_view = TabConfig::List;
QString bgType = cfg. readEntry ( "BackgroundType" );
if ( bgType == "Image" )
tc. m_bg_type = TabConfig::Image;
else if ( bgType == "SolidColor" )
tc. m_bg_type = TabConfig::SolidColor;
else if ( bgType == "Image" ) // No tr
tc. m_bg_type = TabConfig::Image;
tc. m_bg_image = cfg. readEntry ( "BackgroundImage", tc. m_bg_image );
tc. m_last_directory = cfg2.readEntry( "DefaultDir", "" );
tc. m_bg_color = cfg. readEntry ( "BackgroundColor", tc. m_bg_color );
tc. m_iconcolumns = cfg. readNumEntry ( "Columns", tc. m_iconcolumns );
qDebug( "m_iconcolumns for %s = %d", (const char*) *it, tc.m_iconcolumns );
tc. m_text_color = cfg. readEntry ( "TextColor", tc. m_text_color );
QStringList f = cfg. readListEntry ( "Font", ',' );
if ( f. count ( ) == 4 ) {
tc. m_font_use = true;
tc. m_font_family = f [0];
tc. m_font_size = f [1]. toInt ( );
tc. m_font_weight = f [2]. toInt ( );
tc. m_font_italic = ( f [3]. toInt ( ));
}
m_tabs [*it] = tc;
}
// if all tabs have the same config, then initialize the GLOBALID tab to these values
TabConfig *first = 0;
bool same = true;
for ( QStringList::Iterator it = m_ids. begin ( ); it != m_ids. end ( ); ++it ) {
if ( *it == GLOBALID )
continue;
else if ( !first )
first = &m_tabs [*it];
else
same &= ( *first == m_tabs [*it] );
}
if ( same ) {
m_tabs [GLOBALID] = *first;
m_tabs [GLOBALID]. m_changed = true;
}
}
void TabsSettings::accept ( )
{
Config cfg ( "Launcher" );
Config cfg2 ( "Launchersettings" );
// Launcher Tab
QString grp ( "Tab %1" ); // No tr
for ( QStringList::Iterator it = m_ids. begin ( ); it != m_ids. end ( ); ++it ) {
TabConfig &tc = m_tabs [*it];
if ( !tc. m_changed )
continue;
cfg. setGroup ( grp. arg ( *it ));
cfg2. setGroup ( grp. arg ( *it ));
switch ( tc. m_view ) {
case TabConfig::Icon:
cfg.writeEntry ( "View", "Icon" );
break;
case TabConfig::List:
cfg.writeEntry ( "View", "List" );
break;
}
QCopEnvelope e ( "QPE/Launcher", "setTabView(QString,int)" );
e << *it << tc. m_view;
cfg. writeEntry ( "BackgroundImage", tc. m_bg_image );
cfg. writeEntry ( "BackgroundColor", tc. m_bg_color );
cfg. writeEntry ( "Columns", tc. m_iconcolumns );
cfg. writeEntry ( "TextColor", tc. m_text_color );
cfg2. writeEntry ( "DefaultDir", tc.m_last_directory );
if ( tc. m_font_use ) {
QString f = tc. m_font_family + "," + QString::number ( tc. m_font_size ) + "," + QString::number ( tc. m_font_weight ) + "," + ( tc. m_font_italic ? "1" : "0" );
cfg. writeEntry ( "Font", f );
}
else
cfg. removeEntry ( "Font" );
QCopEnvelope be ( "QPE/Launcher", "setTabBackground(QString,int,QString)" );
switch ( tc. m_bg_type ) {
case TabConfig::Ruled:
cfg.writeEntry( "BackgroundType", "Ruled" );
be << *it << tc. m_bg_type << QString("");
break;
case TabConfig::SolidColor:
cfg.writeEntry( "BackgroundType", "SolidColor" );
be << *it << tc. m_bg_type << tc. m_bg_color;
break;
case TabConfig::Image:
cfg.writeEntry( "BackgroundType", "Image" );
be << *it << tc. m_bg_type << tc. m_bg_image;
break;
}
QCopEnvelope te( "QPE/Launcher", "setTextColor(QString,QString)" );
te << *it << tc. m_text_color;
QCopEnvelope ic( "QPE/Launcher", "setIconColumns(QString,int)" );
ic << *it << tc. m_iconcolumns;
QCopEnvelope fe ( "QPE/Launcher", "setFont(QString,QString,int,int,int)" );
fe << *it;
fe << ( tc. m_font_use ? tc. m_font_family : QString::null );
fe << tc. m_font_size;
fe << tc. m_font_weight;
fe << ( tc. m_font_italic ? 1 : 0 );
tc. m_changed = false;
}
cfg. setGroup ( "GUI" );
QString busytype = QString ( m_busyani-> isChecked ( ) ? "Animated" : "" );
cfg. writeEntry ( "BusyType", busytype );
-
- cfg. writeEntry ( "BigBusy", m_bigbusy->isChecked( ) );
+ cfg. writeEntry ( "BigBusy", m_bigbusy->isChecked( ) );
+ cfg. writeEntry ( "StaticBackground", m_staticbackground->isChecked( ) );
{
QCopEnvelope e ( "QPE/Launcher", "setBusyIndicatorType(QString)" );
e << busytype;
}
+ {
+ QCopEnvelope e ( "QPE/Launcher", "setStaticBackground(bool)" );
+ e << m_staticbackground->isChecked();
+ }
}
void TabsSettings::newClicked ( )
{
QMessageBox::information ( this, tr( "Error" ), tr( "Not implemented yet" ));
}
void TabsSettings::deleteClicked ( )
{
int ind = m_list-> currentItem ( );
if ( ind < 0 )
return;
QMessageBox::information ( this, tr( "Error" ), tr( "Not implemented yet" ));
}
void TabsSettings::editClicked ( )
{
int ind = m_list-> currentItem ( );
if ( ind < 0 )
return;
TabConfig tc = m_tabs [m_ids [ind]];
TabDialog *d = new TabDialog ( m_list-> pixmap ( ind ), m_list-> text ( ind ), tc, this, "TabDialog", true );
if ( QPEApplication::execDialog( d ) == QDialog::Accepted ) {
tc. m_changed = true;
m_tabs [m_ids [ind]] = tc;
if ( m_ids [ind] == GLOBALID ) {
for ( QStringList::Iterator it = m_ids. begin ( ); it != m_ids. end ( ); ++it ) {
if ( *it != GLOBALID )
m_tabs [*it] = tc;
}
}
}
delete d;
}
diff --git a/core/settings/launcher/tabssettings.h b/core/settings/launcher/tabssettings.h
index 600c65c..bbe1e72 100644
--- a/core/settings/launcher/tabssettings.h
+++ b/core/settings/launcher/tabssettings.h
@@ -1,68 +1,68 @@
/*
               =. This file is part of the OPIE Project
             .=l. Copyright (c) 2002 Robert Griebl <sandman@handhelds.org>
           .>+-=
 _;:,     .>    :=|. This file is free software; you can
.> <`_,   >  .   <= redistribute it and/or modify it under
:`=1 )Y*s>-.--   : the terms of the GNU General Public
.="- .-=="i,     .._ License as published by the Free Software
 - .   .-<_>     .<> Foundation; either version 2 of the License,
     ._= =}       : or (at your option) any later version.
    .%`+i>       _;_.
    .i_,=:_.      -<s. This file is distributed in the hope that
     +  .  -:.       = it will be useful, but WITHOUT ANY WARRANTY;
    : ..    .:,     . . . without even the implied warranty of
    =_        +     =;=|` MERCHANTABILITY or FITNESS FOR A
  _.=:.       :    :=>`: PARTICULAR PURPOSE. See the GNU General
..}^=.=       =       ; Public License for more details.
++=   -.     .`     .:
 :     =  ...= . :.=- You should have received a copy of the GNU
 -.   .:....=;==+<; General Public License along with this file;
  -_. . .   )=.  = see the file COPYING. If not, write to the
    --        :-=` Free Software Foundation, Inc.,
59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
*/
#ifndef __TABS_SETTINGS_H__
#define __TABS_SETTINGS_H__
#include <qwidget.h>
#include <qmap.h>
#include "tabconfig.h"
class QListBox;
class QCheckBox;
class Config;
class TabsSettings : public QWidget {
Q_OBJECT
public:
TabsSettings ( QWidget *parent = 0, const char *name = 0 );
void accept ( );
protected slots:
void newClicked ( );
void deleteClicked ( );
void editClicked ( );
protected:
void init ( );
void readTabSettings ( Config & );
private:
QListBox *m_list;
// QString currentTab;
QStringList m_ids;
QMap <QString, TabConfig> m_tabs;
- QCheckBox *m_busyani, *m_bigbusy;
+ QCheckBox *m_busyani, *m_bigbusy, *m_staticbackground;
};
#endif