summaryrefslogtreecommitdiff
authorsandman <sandman>2002-12-23 00:07:32 (UTC)
committer sandman <sandman>2002-12-23 00:07:32 (UTC)
commit6f82a7bad0746d37ff1545717be3fe67e2eed17c (patch) (side-by-side diff)
treeeaf5e6b6d7e7fcc648d25ae7021d1785b80122f2
parentc513f413c7d901cc9945714c8e7eb47292f63306 (diff)
downloadopie-6f82a7bad0746d37ff1545717be3fe67e2eed17c.zip
opie-6f82a7bad0746d37ff1545717be3fe67e2eed17c.tar.gz
opie-6f82a7bad0746d37ff1545717be3fe67e2eed17c.tar.bz2
- ported the device button handling to the new ODevice based framework
- removed the key re-grabbing in runningsappbar (not necessary anymore) - added a few new QCops to make all "special" launcher functions available via qcop - added the devicebuttons to the opie-taskbar ipk
Diffstat (more/less context) (show whitespace changes)
-rw-r--r--core/launcher/desktop.cpp352
-rw-r--r--core/launcher/desktop.h39
-rw-r--r--core/launcher/launcher.cpp7
-rw-r--r--core/launcher/main.cpp5
-rw-r--r--core/launcher/opie-taskbar.control2
-rw-r--r--core/launcher/runningappbar.cpp9
-rw-r--r--core/launcher/startmenu.cpp3
-rw-r--r--core/launcher/taskbar.cpp12
8 files changed, 186 insertions, 243 deletions
diff --git a/core/launcher/desktop.cpp b/core/launcher/desktop.cpp
index 6c67056..fa9736f 100644
--- a/core/launcher/desktop.cpp
+++ b/core/launcher/desktop.cpp
@@ -1,905 +1,841 @@
/**********************************************************************
** Copyright (C) 2000 Trolltech AS. All rights reserved.
**
** This file is part of Qtopia Environment.
**
** This file may be distributed and/or modified under the terms of the
** GNU General Public License version 2 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
** See http://www.trolltech.com/gpl/ for GPL licensing information.
**
** Contact info@trolltech.com if any conditions of this licensing are
** not clear to you.
**
**********************************************************************/
#include "desktop.h"
#include "info.h"
#include "launcher.h"
#include "qcopbridge.h"
#include "shutdownimpl.h"
#include "startmenu.h"
#include "taskbar.h"
#include "transferserver.h"
#include "irserver.h"
#include "packageslave.h"
#include "screensaver.h"
#include <qpe/applnk.h>
#include <qpe/mimetype.h>
#include <qpe/password.h>
#include <qpe/config.h>
#include <qpe/power.h>
#include <qpe/timeconversion.h>
#include <qpe/qcopenvelope_qws.h>
#include <qpe/network.h>
#include <qpe/global.h>
#if defined( QT_QWS_SHARP ) || defined( QT_QWS_IPAQ )
#include <qpe/custom.h>
#endif
#include <opie/odevice.h>
#include <qgfx_qws.h>
#include <qmainwindow.h>
#include <qmessagebox.h>
#include <qtimer.h>
#include <qwindowsystem_qws.h>
#include <qvaluelist.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
+
using namespace Opie;
class QCopKeyRegister
{
public:
QCopKeyRegister() : keyCode( 0 )
{ }
- QCopKeyRegister( int k, const QString &c, const QString &m )
+ QCopKeyRegister( int k, const QCString &c, const QCString &m )
: keyCode( k ), channel( c ), message( m )
{ }
int getKeyCode() const
{
return keyCode;
}
- QString getChannel() const
+ QCString getChannel() const
{
return channel;
}
- QString getMessage() const
+ QCString getMessage() const
{
return message;
}
private:
int keyCode;
- QString channel, message;
+ QCString channel, message;
};
typedef QValueList<QCopKeyRegister> KeyRegisterList;
KeyRegisterList keyRegisterList;
static Desktop* qpedesktop = 0;
static int loggedin = 0;
static void login( bool at_poweron )
{
if ( !loggedin ) {
Global::terminateBuiltin( "calibrate" );
Password::authenticate( at_poweron );
loggedin = 1;
QCopEnvelope e( "QPE/Desktop", "unlocked()" );
}
}
bool Desktop::screenLocked()
{
return loggedin == 0;
}
/*
Priority is number of alerts that are needed to pop up
alert.
*/
class DesktopPowerAlerter : public QMessageBox
{
public:
DesktopPowerAlerter( QWidget *parent, const char *name = 0 )
: QMessageBox( tr( "Battery Status" ), "Low Battery",
QMessageBox::Critical,
QMessageBox::Ok | QMessageBox::Default,
QMessageBox::NoButton, QMessageBox::NoButton,
parent, name, FALSE )
{
currentPriority = INT_MAX;
alertCount = 0;
}
void alert( const QString &text, int priority );
void hideEvent( QHideEvent * );
private:
int currentPriority;
int alertCount;
};
void DesktopPowerAlerter::alert( const QString &text, int priority )
{
alertCount++;
if ( alertCount < priority )
return ;
if ( priority > currentPriority )
return ;
currentPriority = priority;
setText( text );
show();
}
void DesktopPowerAlerter::hideEvent( QHideEvent *e )
{
QMessageBox::hideEvent( e );
alertCount = 0;
currentPriority = INT_MAX;
}
void DesktopApplication::switchLCD ( bool on )
{
if ( qApp ) {
DesktopApplication *dapp = (DesktopApplication *) qApp;
if ( dapp-> m_screensaver ) {
if ( on ) {
dapp-> m_screensaver-> setDisplayState ( true );
dapp-> m_screensaver-> setBacklight ( -3 );
}
else {
dapp-> m_screensaver-> setDisplayState ( false );
}
}
}
}
DesktopApplication::DesktopApplication( int& argc, char **argv, Type appType )
: QPEApplication( argc, argv, appType )
{
Config cfg( "apm" );
cfg.setGroup( "Warnings" );
//cfg.readNumEntry( "checkinterval", 10000 )
m_powerVeryLow = cfg.readNumEntry( "powerverylow", 10 );
m_powerCritical = cfg.readNumEntry( "powercritical", 5 );
m_ps = new PowerStatus;
m_ps_last = new PowerStatus;
pa = new DesktopPowerAlerter( 0 );
m_timer = new QTimer( this );
connect( m_timer, SIGNAL( timeout() ), this, SLOT( apmTimeout() ) );
m_timer->start( 5000 );
- channel = new QCopChannel( "QPE/Desktop", this );
- connect( channel, SIGNAL( received( const QCString&, const QByteArray& ) ),
- this, SLOT( desktopMessage( const QCString&, const QByteArray& ) ) );
+ m_last_button = 0;
+ m_button_timer = new QTimer ( );
+ connect ( m_button_timer, SIGNAL( timeout ( )), this, SLOT( sendHeldAction ( )));
channel = new QCopChannel( "QPE/System", this );
connect( channel, SIGNAL( received( const QCString&, const QByteArray& ) ),
this, SLOT( systemMessage( const QCString&, const QByteArray& ) ) );
+ channel = new QCopChannel( "QPE/Launcher", this );
+ connect( channel, SIGNAL( received( const QCString&, const QByteArray& ) ),
+ this, SLOT( launcherMessage( const QCString&, const QByteArray& ) ) );
+
m_screensaver = new OpieScreenSaver ( );
m_screensaver-> setInterval ( -1 );
QWSServer::setScreenSaver( m_screensaver );
+ rereadVolumes();
+ connect( qApp, SIGNAL( volumeChanged( bool ) ), this, SLOT( rereadVolumes() ) );
+
apmTimeout ( );
+
+ grabKeyboard ( );
}
DesktopApplication::~DesktopApplication()
{
+ ungrabKeyboard ( );
+
delete m_ps;
delete m_ps_last;
delete pa;
}
void DesktopApplication::apmTimeout()
{
qpedesktop->checkMemory(); // in case no events are being generated
*m_ps_last = *m_ps;
*m_ps = PowerStatusManager::readStatus();
if ( m_ps-> acStatus ( ) != m_ps_last-> acStatus ( ))
m_screensaver-> powerStatusChanged ( *m_ps );
if ( m_ps-> acStatus ( ) != PowerStatus::Online ) {
int bat = m_ps-> batteryPercentRemaining ( );
if ( bat < m_ps_last-> batteryPercentRemaining ( )) {
if ( bat <= m_powerCritical )
pa->alert( tr( "Battery level is critical!\nKeep power off until power restored!" ), 1 );
else if ( bat <= m_powerVeryLow )
pa->alert( tr( "Battery is running very low." ), 2 );
}
if ( m_ps-> backupBatteryStatus ( ) == PowerStatus::VeryLow )
pa->alert( tr( "The Back-up battery is very low.\nPlease charge the back-up battery." ), 2 );
}
}
-void DesktopApplication::desktopMessage( const QCString &msg, const QByteArray &data )
-{
- QDataStream stream( data, IO_ReadOnly );
- if ( msg == "keyRegister(int key, QString channel, QString message)" ) {
- int k;
- QString c, m;
- stream >> k;
- stream >> c;
- stream >> m;
-
- qWarning( "KeyRegisterReceived: %i, %s, %s", k, ( const char* ) c, ( const char * ) m );
- keyRegisterList.append( QCopKeyRegister( k, c, m ) );
- }
-}
-
void DesktopApplication::systemMessage( const QCString & msg, const QByteArray & data )
{
QDataStream stream ( data, IO_ReadOnly );
if ( msg == "setScreenSaverInterval(int)" ) {
int time;
stream >> time;
m_screensaver-> setInterval( time );
}
else if ( msg == "setScreenSaverIntervals(int,int,int)" ) {
int t1, t2, t3;
stream >> t1 >> t2 >> t3;
m_screensaver-> setIntervals( t1, t2, t3 );
}
else if ( msg == "setBacklight(int)" ) {
int bright;
stream >> bright;
m_screensaver-> setBacklight( bright );
}
else if ( msg == "setScreenSaverMode(int)" ) {
int mode;
stream >> mode;
m_screensaver-> setMode ( mode );
}
else if ( msg == "reloadPowerWarnSettings()" ) {
reloadPowerWarnSettings();
}
else if ( msg == "setDisplayState(int)" ) {
int state;
stream >> state;
m_screensaver-> setDisplayState ( state != 0 );
}
else if ( msg == "suspend()" ) {
emit power();
}
+ else if ( msg == "sendBusinessCard()" ) {
+ QString card = ::getenv ( "HOME" );
+ card += "/Applications/addressbook/businesscard.vcf";
+
+ if ( QFile::exists( card ) ) {
+ QCopEnvelope e ( "QPE/Obex", "send(QString,QString,QString)" );
+ QString mimetype = "text/x-vCard";
+ e << tr( "business card" ) << card << mimetype;
+ }
+ }
}
-void DesktopApplication::reloadPowerWarnSettings() {
+void DesktopApplication::reloadPowerWarnSettings()
+{
Config cfg( "apm" );
cfg.setGroup( "Warnings" );
// m_timer->changeInterval( cfg.readNumEntry( "checkinterval", 10000 ) );
m_powerVeryLow = cfg.readNumEntry( "powerverylow", 10 );
m_powerCritical = cfg.readNumEntry( "powervcritical", 5 );
}
enum MemState { Unknown, VeryLow, Low, Normal } memstate = Unknown;
-#ifdef Q_WS_QWS
-bool DesktopApplication::qwsEventFilter( QWSEvent *e )
+
+void DesktopApplication::launcherMessage( const QCString & msg, const QByteArray & data )
{
- qpedesktop->checkMemory();
+ QDataStream stream ( data, IO_ReadOnly );
- if ( e->type == QWSEvent::Key ) {
- QWSKeyEvent * ke = ( QWSKeyEvent * ) e;
- if ( !loggedin && ke->simpleData.keycode != Key_F34 )
- return TRUE;
- bool press = ke->simpleData.is_press;
- bool autoRepeat = ke->simpleData.is_auto_repeat;
+ if ( msg == "deviceButton(int,int,int)" ) {
+ int keycode, press, autoRepeat;
+ stream >> keycode >> press >> autoRepeat;
- /*
- app that registers key/message to be sent back to the app, when it doesn't have focus,
- when user presses key, unless keyboard has been requested from app.
- will not send multiple repeats if user holds key
- i.e. one shot
- */
- if ( !keyRegisterList.isEmpty() && ke->simpleData.keycode !=0 && press) {
-// qDebug("<<<<<<<<<<<<<keycode %d", ke->simpleData.keycode);
- KeyRegisterList::Iterator it;
- for ( it = keyRegisterList.begin(); it != keyRegisterList.end(); ++it ) {
- if ( ( *it ).getKeyCode() == ke->simpleData.keycode && !autoRepeat && !keyboardGrabbed() ) {
- if ( press )
- qDebug( "press" );
- else
- qDebug( "release" );
- QCopEnvelope( ( *it ).getChannel().utf8(), ( *it ).getMessage().utf8() );
+ const ODeviceButton *db = ODevice::inst ( )-> buttonForKeycode ( keycode );
+
+ if ( db )
+ checkButtonAction ( db, keycode, press, autoRepeat );
}
+ else if ( msg == "keyRegister(int,QCString,QCString)" ) {
+ int k;
+ QCString c, m;
+ stream >> k >> c >> m;
+
+ keyRegisterList.append ( QCopKeyRegister ( k, c, m ));
}
}
- if ( !keyboardGrabbed() ) {
- if ( ke->simpleData.keycode == Key_F9 ) {
- if ( press )
- emit datebook();
- return TRUE;
+void DesktopApplication::sendHeldAction ( )
+{
+ if ( m_last_button ) {
+ m_last_button-> heldAction ( ). send ( );
+ m_last_button = 0;
}
- if ( ke->simpleData.keycode == Key_F10 ) {
- if ( !press && cardSendTimer ) {
- emit contacts();
- delete cardSendTimer;
}
- else if ( press ) {
- cardSendTimer = new QTimer();
- cardSendTimer->start( 2000, TRUE );
- connect( cardSendTimer, SIGNAL( timeout() ), this, SLOT( sendCard() ) );
+
+
+
+void DesktopApplication::checkButtonAction ( const ODeviceButton *db, int keycode, bool press, bool autoRepeat )
+{
+ if ( db ) {
+ if ( !press && !autoRepeat && m_button_timer-> isActive ( )) {
+ m_button_timer-> stop ( );
+ if ( !db-> pressedAction ( ). channel ( ). isEmpty ( )) {
+ db-> pressedAction ( ). send ( );
}
- return TRUE;
}
+ else if ( press && !autoRepeat ) {
+ m_button_timer-> stop ( );
- if ( ke->simpleData.keycode == Key_F11 ) {
- if ( press ) emit menu();
- return TRUE;
+ if ( !db-> heldAction ( ). channel ( ). isEmpty ( )) {
+ m_last_button = db;
+ m_button_timer-> start ( ODevice::inst ( )-> buttonHoldTime ( ), true );
+ }
+ }
+ }
}
- if ( ke->simpleData.keycode == Key_F12 ) {
- while ( activePopupWidget() )
- activePopupWidget() ->close();
- if ( press )
- emit launch();
- return TRUE;
+bool DesktopApplication::eventFilter ( QObject *o, QEvent *e )
+{
+ if ( e-> type ( ) == QEvent::KeyPress || e-> type ( ) == QEvent::KeyRelease ) {
+ QKeyEvent *ke = (QKeyEvent *) e;
+
+ const ODeviceButton *db = ODevice::inst ( )-> buttonForKeycode ( ke-> key ( ));
+
+ if ( db ) {
+ checkButtonAction ( db, ke-> key ( ), e-> type ( ) == QEvent::KeyPress, ke-> isAutoRepeat ( ));
+ return true;
+ }
+ }
+ return QPEApplication::eventFilter ( o, e );
+}
+
+#ifdef Q_WS_QWS
+
+bool DesktopApplication::qwsEventFilter( QWSEvent *e )
+{
+ qpedesktop->checkMemory();
+
+ if ( e->type == QWSEvent::Key ) {
+ QWSKeyEvent * ke = (QWSKeyEvent *) e;
+ ushort keycode = ke-> simpleData. keycode;
+
+ if ( !loggedin && keycode != Key_F34 )
+ return true;
+
+ bool press = ke-> simpleData. is_press;
+ bool autoRepeat = ke-> simpleData. is_auto_repeat;
+
+ if ( !keyboardGrabbed ( )) {
+ // app that registers key/message to be sent back to the app, when it doesn't have focus,
+ // when user presses key, unless keyboard has been requested from app.
+ // will not send multiple repeats if user holds key
+ // i.e. one shot
+
+ if ( keycode != 0 && press && !autoRepeat ) {
+ for ( KeyRegisterList::Iterator it = keyRegisterList.begin(); it != keyRegisterList.end(); ++it ) {
+ if (( *it ). getKeyCode ( ) == keycode ) {
+ QCopEnvelope (( *it ). getChannel ( ), ( *it ). getMessage ( ));
+ return true;
+ }
}
- if ( ke->simpleData.keycode == Key_F13 ) {
- if ( press )
- emit email();
- return TRUE;
}
}
- if ( ke->simpleData.keycode == Key_F34 ) {
+ if ( keycode == HardKey_Suspend ) {
if ( press )
emit power();
- return TRUE;
+ return true;
}
- // This was used for the iPAQ PowerButton
- // See main.cpp for new KeyboardFilter
- //
- // if ( ke->simpleData.keycode == Key_SysReq ) {
- // if ( press ) emit power();
- // return TRUE;
- // }
- if ( ke->simpleData.keycode == Key_F35 ) {
+ else if ( keycode == HardKey_Backlight ) {
if ( press )
emit backlight();
- return TRUE;
+ return true;
}
- if ( ke->simpleData.keycode == Key_F32 ) {
+ else if ( keycode == Key_F32 ) {
if ( press )
QCopEnvelope e( "QPE/Desktop", "startSync()" );
- return TRUE;
+ return true;
}
- if ( ke->simpleData.keycode == Key_F31 && !ke->simpleData.modifiers ) {
+ else if ( keycode == Key_F31 && !ke-> simpleData. modifiers ) { // Symbol Key -> show Unicode IM
if ( press )
emit symbol();
- return TRUE;
+ return true;
}
- if ( ke->simpleData.keycode == Key_NumLock ) {
+ else if ( keycode == Key_NumLock ) {
if ( press )
emit numLockStateToggle();
}
- if ( ke->simpleData.keycode == Key_CapsLock ) {
+ else if ( keycode == Key_CapsLock ) {
if ( press )
emit capsLockStateToggle();
}
- if ( ( press && !autoRepeat ) || ( !press && autoRepeat ) )
- qpedesktop->keyClick();
+ if (( press && !autoRepeat ) || ( !press && autoRepeat )) {
+ if ( m_keyclick_sound )
+ ODevice::inst ( )-> keySound ( );
}
- else {
- if ( e->type == QWSEvent::Mouse ) {
+ }
+ else if ( e-> type == QWSEvent::Mouse ) {
QWSMouseEvent * me = ( QWSMouseEvent * ) e;
- static bool up = TRUE;
+ static bool up = true;
+
if ( me->simpleData.state & LeftButton ) {
if ( up ) {
- up = FALSE;
- qpedesktop->screenClick();
+ up = false;
+ if ( m_screentap_sound )
+ ODevice::inst ( ) -> touchSound ( );
}
}
else {
- up = TRUE;
- }
+ up = true;
}
}
return QPEApplication::qwsEventFilter( e );
}
#endif
-void DesktopApplication::sendCard()
-{
- delete cardSendTimer;
- cardSendTimer = 0;
- QString card = getenv( "HOME" );
- card += "/Applications/addressbook/businesscard.vcf";
-
- if ( QFile::exists( card ) ) {
- QCopEnvelope e( "QPE/Obex", "send(QString,QString,QString)" );
- QString mimetype = "text/x-vCard";
- e << tr( "business card" ) << card << mimetype;
- }
-}
#if defined(QPE_HAVE_MEMALERTER)
QPE_MEMALERTER_IMPL
#endif
//===========================================================================
Desktop::Desktop() :
QWidget( 0, 0, WStyle_Tool | WStyle_Customize ),
qcopBridge( 0 ),
transferServer( 0 ),
packageSlave( 0 )
{
qpedesktop = this;
// bg = new Info( this );
tb = new TaskBar;
launcher = new Launcher( 0, 0, WStyle_Customize | QWidget::WGroupLeader );
connect( launcher, SIGNAL( busy() ), tb, SLOT( startWait() ) );
connect( launcher, SIGNAL( notBusy( const QString& ) ), tb, SLOT( stopWait( const QString& ) ) );
int displayw = qApp->desktop() ->width();
int displayh = qApp->desktop() ->height();
QSize sz = tb->sizeHint();
setGeometry( 0, displayh - sz.height(), displayw, sz.height() );
tb->setGeometry( 0, displayh - sz.height(), displayw, sz.height() );
tb->show();
launcher->showMaximized();
launcher->show();
launcher->raise();
#if defined(QPE_HAVE_MEMALERTER)
initMemalerter();
#endif
// start services
startTransferServer();
( void ) new IrServer( this );
- rereadVolumes();
packageSlave = new PackageSlave( this );
- connect( qApp, SIGNAL( volumeChanged( bool ) ), this, SLOT( rereadVolumes() ) );
qApp->installEventFilter( this );
qApp-> setMainWidget ( launcher );
}
void Desktop::show()
{
login( TRUE );
QWidget::show();
}
Desktop::~Desktop()
{
delete launcher;
delete tb;
delete qcopBridge;
delete transferServer;
}
bool Desktop::recoverMemory()
{
return tb->recoverMemory();
}
void Desktop::checkMemory()
{
#if defined(QPE_HAVE_MEMALERTER)
static bool ignoreNormal = FALSE;
static bool existingMessage = FALSE;
if ( existingMessage )
return ; // don't show a second message while still on first
existingMessage = TRUE;
switch ( memstate ) {
case Unknown:
break;
case Low:
memstate = Unknown;
if ( recoverMemory() )
ignoreNormal = TRUE;
else
QMessageBox::warning( 0 , "Memory Status",
"The memory smacks of shortage. \n"
"Please save data. " );
break;
case Normal:
memstate = Unknown;
if ( ignoreNormal )
ignoreNormal = FALSE;
// else
// QMessageBox::information ( 0 , "Memory Status",
// "There is enough memory again." );
break;
case VeryLow:
memstate = Unknown;
QMessageBox::critical( 0 , "Memory Status",
"The memory is very low. \n"
"Please end this application \n"
"immediately." );
recoverMemory();
}
existingMessage = FALSE;
#endif
}
static bool isVisibleWindow( int wid )
{
#ifdef 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;
}
static bool hasVisibleWindow( const QString& clientname )
{
#ifdef QWS
const QList<QWSWindow> &list = qwsServer->clientWindows();
QWSWindow* w;
for ( QListIterator<QWSWindow> it( list ); ( w = it.current() ); ++it ) {
if ( w->client() ->identity() == clientname && !w->isFullyObscured() )
return TRUE;
}
#endif
return FALSE;
}
-void Desktop::raiseLauncher()
-{
- Config cfg( "qpe" ); //F12 'Home'
- cfg.setGroup( "AppsKey" );
- QString tempItem;
- tempItem = cfg.readEntry( "Middle", "Home" );
- if ( tempItem == "Home" || tempItem.isEmpty() ) {
- home ( );
- }
- else {
- QCopEnvelope e( "QPE/System", "execute(QString)" );
- e << tempItem;
- }
-}
-
-void Desktop::home ( )
-{
- if ( isVisibleWindow( launcher->winId() ) )
- launcher->nextView();
- else
- launcher->raise();
-}
void Desktop::executeOrModify( const QString& appLnkFile )
{
AppLnk lnk( MimeType::appsFolderName() + "/" + appLnkFile );
if ( lnk.isValid() ) {
QCString app = lnk.exec().utf8();
Global::terminateBuiltin( "calibrate" );
if ( QCopChannel::isRegistered( "QPE/Application/" + app ) ) {
// MRUList::addTask( &lnk );
if ( hasVisibleWindow( app ) )
QCopChannel::send( "QPE/Application/" + app, "nextView()" );
else
QCopChannel::send( "QPE/Application/" + app, "raise()" );
}
else {
lnk.execute();
}
}
}
-void Desktop::raiseDatebook()
-{
- Config cfg( "qpe" ); //F9 'Activity'
- cfg.setGroup( "AppsKey" );
- QString tempItem;
- tempItem = cfg.readEntry( "LeftEnd" , "Calendar" );
- if ( tempItem == "Calendar" || tempItem.isEmpty() ) {
- tempItem = "datebook";
- }
- QCopEnvelope e( "QPE/System", "execute(QString)" );
- e << tempItem;
-}
-
-void Desktop::raiseContacts()
-{
- Config cfg( "qpe" ); //F10, 'Contacts'
- cfg.setGroup( "AppsKey" );
- QString tempItem;
- tempItem = cfg.readEntry( "Left2nd", "Address Book" );
- if ( tempItem == "Address Book" || tempItem.isEmpty() ) {
- tempItem = "addressbook";
- }
- QCopEnvelope e( "QPE/System", "execute(QString)" );
- e << tempItem;
-}
-
-void Desktop::raiseMenu()
-{
- Config cfg( "qpe" ); //F11, 'Menu
- cfg.setGroup( "AppsKey" );
- QString tempItem;
- tempItem = cfg.readEntry( "Right2nd" , "Popup Menu" );
- if ( tempItem == "Popup Menu" || tempItem.isEmpty() ) {
- Global::terminateBuiltin( "calibrate" );
- tb->startMenu() ->launch();
- }
- else {
- QCopEnvelope e( "QPE/System", "execute(QString)" );
- e << tempItem;
- }
-}
-
-void Desktop::raiseEmail()
-{
- Config cfg( "qpe" ); //F13, 'Mail' // only in zaurus, on ipaq mail key is F11
- cfg.setGroup( "AppsKey" );
- QString tempItem;
- tempItem = cfg.readEntry( "RightEnd", "Mail" );
- if ( tempItem == "Mail" || tempItem == "qtmail" || tempItem.isEmpty() ) {
- tempItem = "mail";
- }
- QCopEnvelope e( "QPE/System", "execute(QString)" );
- e << tempItem;
-}
-
// autoStarts apps on resume and start
void Desktop::execAutoStart()
{
QString appName;
int delay;
QDateTime now = QDateTime::currentDateTime();
Config cfg( "autostart" );
cfg.setGroup( "AutoStart" );
appName = cfg.readEntry( "Apps", "" );
delay = ( cfg.readEntry( "Delay", "0" ) ).toInt();
// If the time between suspend and resume was longer then the
// value saved as delay, start the app
if ( suspendTime.secsTo( now ) >= ( delay * 60 ) && !appName.isEmpty() ) {
QCopEnvelope e( "QPE/System", "execute(QString)" );
e << QString( appName );
}
}
#if defined(QPE_HAVE_TOGGLELIGHT)
#include <qpe/config.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <linux/ioctl.h>
#include <time.h>
#endif
void Desktop::togglePower()
{
static bool excllock = false;
qDebug ( "togglePower (locked == %d)", excllock ? 1 : 0 );
if ( excllock )
return;
excllock = true;
bool wasloggedin = loggedin;
loggedin = 0;
suspendTime = QDateTime::currentDateTime();
#ifdef QWS
+
if ( Password::needToAuthenticate ( true ) && qt_screen ) {
// Should use a big black window instead.
// But this would not show up fast enough
QGfx *g = qt_screen-> screenGfx ( );
g-> fillRect ( 0, 0, qt_screen-> width ( ), qt_screen-> height ( ));
delete g;
}
#endif
ODevice::inst ( )-> suspend ( );
DesktopApplication::switchLCD ( true ); // force LCD on without slow qcop call
QWSServer::screenSaverActivate ( false );
{
QCopEnvelope( "QPE/Card", "mtabChanged()" ); // might have changed while asleep
}
if ( wasloggedin )
login ( true );
execAutoStart();
//qcopBridge->closeOpenConnections();
excllock = false;
}
void Desktop::toggleLight()
{
QCopEnvelope e( "QPE/System", "setBacklight(int)" );
e << -2; // toggle
}
void Desktop::toggleSymbolInput()
{
tb->toggleSymbolInput();
}
void Desktop::toggleNumLockState()
{
tb->toggleNumLockState();
}
void Desktop::toggleCapsLockState()
{
tb->toggleCapsLockState();
}
void Desktop::styleChange( QStyle &s )
{
QWidget::styleChange( s );
int displayw = qApp->desktop() ->width();
int displayh = qApp->desktop() ->height();
QSize sz = tb->sizeHint();
tb->setGeometry( 0, displayh - sz.height(), displayw, sz.height() );
}
void DesktopApplication::shutdown()
{
if ( type() != GuiServer )
return ;
ShutdownImpl *sd = new ShutdownImpl( 0, 0, WDestructiveClose );
connect( sd, SIGNAL( shutdown( ShutdownImpl::Type ) ),
this, SLOT( shutdown( ShutdownImpl::Type ) ) );
sd->showMaximized();
}
void DesktopApplication::shutdown( ShutdownImpl::Type t )
{
switch ( t ) {
case ShutdownImpl::ShutdownSystem:
execlp( "shutdown", "shutdown", "-h", "now", ( void* ) 0 );
break;
case ShutdownImpl::RebootSystem:
execlp( "shutdown", "shutdown", "-r", "now", ( void* ) 0 );
break;
case ShutdownImpl::RestartDesktop:
restart();
break;
case ShutdownImpl::TerminateDesktop:
prepareForTermination( FALSE );
// This is a workaround for a Qt bug
// clipboard applet has to stop its poll timer, or Qt/E
// will hang on quit() right before it emits aboutToQuit()
emit aboutToQuit ( );
quit();
break;
}
}
void DesktopApplication::restart()
{
prepareForTermination( TRUE );
#ifdef Q_WS_QWS
for ( int fd = 3; fd < 100; fd++ )
close( fd );
#if defined(QT_DEMO_SINGLE_FLOPPY)
execl( "/sbin/init", "qpe", 0 );
#elif defined(QT_QWS_CASSIOPEIA)
execl( "/bin/sh", "sh", 0 );
#else
execl( ( qpeDir() + "/bin/qpe" ).latin1(), "qpe", 0 );
#endif
exit( 1 );
#endif
}
void Desktop::startTransferServer()
{
// start qcop bridge server
qcopBridge = new QCopBridge( 4243 );
if ( !qcopBridge->ok() ) {
delete qcopBridge;
qcopBridge = 0;
}
// start transfer server
transferServer = new TransferServer( 4242 );
if ( !transferServer->ok() ) {
delete transferServer;
transferServer = 0;
}
if ( !transferServer || !qcopBridge )
startTimer( 2000 );
}
void Desktop::timerEvent( QTimerEvent *e )
{
killTimer( e->timerId() );
startTransferServer();
}
void Desktop::terminateServers()
{
delete transferServer;
delete qcopBridge;
transferServer = 0;
qcopBridge = 0;
}
-void Desktop::rereadVolumes()
+void DesktopApplication::rereadVolumes()
{
Config cfg( "qpe" );
cfg.setGroup( "Volume" );
- touchclick = cfg.readBoolEntry( "TouchSound" );
- keyclick = cfg.readBoolEntry( "KeySound" );
- alarmsound = cfg.readBoolEntry( "AlarmSound" );
-}
-void Desktop::keyClick()
-{
- if ( keyclick )
- ODevice::inst ( ) -> keySound ( );
+ m_screentap_sound = cfg. readBoolEntry ( "TouchSound" );
+ m_keyclick_sound = cfg. readBoolEntry ( "KeySound" );
+ m_alarm_sound = cfg. readBoolEntry ( "AlarmSound" );
}
-void Desktop::screenClick()
+void DesktopApplication::soundAlarm()
{
- if ( touchclick )
- ODevice::inst ( ) -> touchSound ( );
+ if ( me ( )-> m_alarm_sound )
+ ODevice::inst ( )-> alarmSound ( );
}
-void Desktop::soundAlarm()
+DesktopApplication *DesktopApplication::me ( )
{
- if ( qpedesktop-> alarmsound )
- ODevice::inst ( ) -> alarmSound ( );
+ return (DesktopApplication *) qApp;
}
diff --git a/core/launcher/desktop.h b/core/launcher/desktop.h
index 1f8daa0..6cb7ab2 100644
--- a/core/launcher/desktop.h
+++ b/core/launcher/desktop.h
@@ -1,152 +1,155 @@
/**********************************************************************
** Copyright (C) 2000 Trolltech AS. All rights reserved.
**
** This file is part of Qtopia Environment.
**
** This file may be distributed and/or modified under the terms of the
** GNU General Public License version 2 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
** See http://www.trolltech.com/gpl/ for GPL licensing information.
**
** Contact info@trolltech.com if any conditions of this licensing are
** not clear to you.
**
**********************************************************************/
#ifndef __DESKTOP_H__
#define __DESKTOP_H__
#include "shutdownimpl.h"
#include <qpe/qpeapplication.h>
+#include <opie/odevicebutton.h>
#include <qwidget.h>
#include <qdatetime.h>
class Background;
class Launcher;
class TaskBar;
class PowerStatus;
class QCopBridge;
class TransferServer;
class DesktopPowerAlerter;
class PackageSlave;
class OpieScreenSaver;
class DesktopApplication : public QPEApplication
{
Q_OBJECT
public:
DesktopApplication( int& argc, char **argv, Type t );
~DesktopApplication();
static void switchLCD ( bool on ); // only for togglePower in Desktop
+ static void soundAlarm(); // only because QCop soundAlarm() is defined in QPE/TaskBar
+
signals:
void menu();
void home();
- void datebook();
- void contacts();
void launch();
- void email();
void backlight();
void power();
void symbol();
void numLockStateToggle();
void capsLockStateToggle();
void prepareForRestart();
protected:
#ifdef Q_WS_QWS
bool qwsEventFilter( QWSEvent * );
#endif
void shutdown();
void restart();
public slots:
- virtual void desktopMessage ( const QCString &msg, const QByteArray &data );
virtual void systemMessage ( const QCString &msg, const QByteArray &data );
+ virtual void launcherMessage ( const QCString &msg, const QByteArray &data );
+ void rereadVolumes();
protected slots:
void shutdown( ShutdownImpl::Type );
void apmTimeout();
- void sendCard();
+ void sendHeldAction ( );
+
+protected:
+ virtual bool eventFilter ( QObject *o, QEvent *e );
+ void checkButtonAction ( const Opie::ODeviceButton *db, int keycode, bool press, bool autoRepeat );
+
+private:
+ static DesktopApplication *me ( );
+
private:
void reloadPowerWarnSettings();
DesktopPowerAlerter *pa;
PowerStatus *m_ps, *m_ps_last;
QTimer *cardSendTimer;
QCopChannel *channel;
OpieScreenSaver *m_screensaver;
QTimer * m_timer;
int m_powerVeryLow;
int m_powerCritical;
int m_currentPowerLevel;
+
+ const Opie::ODeviceButton *m_last_button;
+ QTimer *m_button_timer;
+
+ bool m_keyclick_sound : 1;
+ bool m_screentap_sound : 1;
+ bool m_alarm_sound : 1;
};
class Desktop : public QWidget
{
Q_OBJECT
public:
Desktop();
~Desktop();
static bool screenLocked();
void show();
void checkMemory();
- void keyClick();
- void screenClick();
- static void soundAlarm();
-
public slots:
- void raiseDatebook();
- void raiseContacts();
- void raiseMenu();
- void raiseLauncher();
- void raiseEmail();
void execAutoStart();
void togglePower();
void toggleLight();
void toggleNumLockState();
void toggleCapsLockState();
void toggleSymbolInput();
void terminateServers();
- void rereadVolumes();
-
- void home ( );
protected:
void executeOrModify( const QString& appLnkFile );
void styleChange( QStyle & );
void timerEvent( QTimerEvent *e );
QWidget *bg;
Launcher *launcher;
TaskBar *tb;
private:
void startTransferServer();
bool recoverMemory();
QCopBridge *qcopBridge;
TransferServer *transferServer;
PackageSlave *packageSlave;
QDateTime suspendTime;
- bool keyclick, touchclick, alarmsound;
};
#endif // __DESKTOP_H__
diff --git a/core/launcher/launcher.cpp b/core/launcher/launcher.cpp
index 767efb2..6764338 100644
--- a/core/launcher/launcher.cpp
+++ b/core/launcher/launcher.cpp
@@ -1,1253 +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.
**
**********************************************************************/
// WARNING: Do *NOT* define this yourself. The SL5xxx from SHARP does NOT
// have this class.
#define QTOPIA_INTERNAL_FSLP
#include <qpe/qcopenvelope_qws.h>
#include <qpe/resource.h>
#include <qpe/applnk.h>
#include <qpe/config.h>
#include <qpe/global.h>
#include <qpe/qpeapplication.h>
#include <qpe/mimetype.h>
#include <qpe/storage.h>
#include <qpe/palmtoprecord.h>
#include <qpe/version.h>
#include <qdir.h>
#ifdef QWS
#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 <qlayout.h>
#include <qregexp.h>
#include <qmessagebox.h>
#include <qframe.h>
#include <qpainter.h>
#include <qlabel.h>
#include <qtextstream.h>
#include <qpopupmenu.h>
#include "launcherview.h"
#include "launcher.h"
#include "syncdialog.h"
#include "desktop.h"
#include <qpe/lnkproperties.h>
//#include "mrulist.h"
#include "qrsync.h"
#include <stdlib.h>
#include <unistd.h>
#if defined(_OS_LINUX_) || defined(Q_OS_LINUX)
#include <stdio.h>
#include <sys/vfs.h>
#include <mntent.h>
#endif
#include <qpe/storage.h>
#include "mediummountgui.h"
namespace {
QStringList configToMime( Config *cfg ){
QStringList mimes;
bool tmpMime = true;
cfg->setGroup("mimetypes" );
tmpMime = cfg->readBoolEntry("all" ,true);
if( tmpMime ){
mimes << QString::null;
return mimes;
}else{
tmpMime = cfg->readBoolEntry("audio", true );
if(tmpMime )
mimes.append("audio/*" );
tmpMime = cfg->readBoolEntry("image", true );
if(tmpMime )
mimes.append("image/*" );
tmpMime = cfg->readBoolEntry("text", true );
if(tmpMime )
mimes.append("text/*");
tmpMime = cfg->readBoolEntry("video", true );
if(tmpMime )
mimes.append("video/*" );
}
return mimes;
}
}
//#define SHOW_ALL
class CategoryTab : public QTab
{
public:
CategoryTab( const QIconSet &icon, const QString &text=QString::null )
: QTab( icon, text )
{
}
QColor bgColor;
QColor fgColor;
};
//===========================================================================
CategoryTabWidget::CategoryTabWidget( QWidget* parent ) :
QVBox( parent )
{
categoryBar = 0;
stack = 0;
}
void CategoryTabWidget::prevTab()
{
if ( categoryBar ) {
int n = categoryBar->count();
int tab = categoryBar->currentTab();
if ( tab >= 0 )
categoryBar->setCurrentTab( (tab - 1 + n)%n );
}
}
void CategoryTabWidget::nextTab()
{
if ( categoryBar ) {
int n = categoryBar->count();
int tab = categoryBar->currentTab();
categoryBar->setCurrentTab( (tab + 1)%n );
}
}
void CategoryTabWidget::addItem( const QString& linkfile )
{
int i=0;
AppLnk *app = new AppLnk(linkfile);
if ( !app->isValid() ) {
delete app;
app=0;
}
if ( !app || !app->file().isEmpty() ) {
// A document
delete app;
app = new DocLnk(linkfile);
if ( app->fileKnown() ) {
((LauncherView*)(stack->widget(ids.count()-1)))->addItem(app);
} else {
((LauncherView*)(stack->widget(ids.count()-1)))->sort();
delete app;
}
return;
}
// An application
for ( QStringList::Iterator it=ids.begin(); it!=ids.end(); ++it) {
if ( !(*it).isEmpty() ) {
QRegExp tf(*it,FALSE,TRUE);
if ( tf.match(app->type()) >= 0 ) {
((LauncherView*)stack->widget(i))->addItem(app);
return;
}
i++;
}
}
QCopEnvelope e("QPE/TaskBar","reloadApps()");
}
void CategoryTabWidget::initializeCategories(AppLnkSet* rootFolder,
AppLnkSet* docFolder, const QList<FileSystem> &fs)
{
delete categoryBar;
categoryBar = new CategoryTabBar( this );
QPalette pal = categoryBar->palette();
pal.setColor( QColorGroup::Light, pal.color(QPalette::Active,QColorGroup::Shadow) );
pal.setColor( QColorGroup::Background, pal.active().background().light(110) );
categoryBar->setPalette( pal );
delete stack;
stack = new QWidgetStack(this);
tabs=0;
ids.clear();
Config cfg("Launcher");
QStringList types = rootFolder->types();
for ( QStringList::Iterator it=types.begin(); it!=types.end(); ++it) {
if ( !(*it).isEmpty() ) {
(void)newView(*it,rootFolder->typePixmap(*it),rootFolder->typeName(*it));
setTabAppearance( *it, cfg );
}
}
QListIterator<AppLnk> it( rootFolder->children() );
AppLnk* l;
while ( (l=it.current()) ) {
if ( l->type() == "Separator" ) { // No tr
rootFolder->remove(l);
delete l;
} else {
int i=0;
for ( QStringList::Iterator it=types.begin(); it!=types.end(); ++it) {
if ( *it == l->type() )
((LauncherView*)stack->widget(i))->addItem(l,FALSE);
i++;
}
}
++it;
}
rootFolder->detachChildren();
for (int i=0; i<tabs; i++)
((LauncherView*)stack->widget(i))->sort();
// all documents
QImage img( Resource::loadImage( "DocsIcon" ) );
QPixmap pm;
pm = img.smoothScale( AppLnk::smallIconSize(), AppLnk::smallIconSize() );
docview = newView( "Documents", // No tr
pm, tr("Documents"));
docview->populate( docFolder, QString::null );
docFolder->detachChildren();
docview->setFileSystems(fs);
docview->setToolsEnabled(TRUE);
setTabAppearance( "Documents", cfg ); // No tr
connect( categoryBar, SIGNAL(selected(int)), stack, SLOT(raiseWidget(int)) );
((LauncherView*)stack->widget(0))->setFocus();
cfg. setGroup ( "GUI" );
setBusyIndicatorType ( cfg. readEntry ( "BusyType", QString::null ));
categoryBar->show();
stack->show();
}
void CategoryTabWidget::setTabAppearance( const QString &id, Config &cfg )
{
QString grp( "Tab %1" ); // No tr
cfg.setGroup( grp.arg(id) );
LauncherView *v = view( id );
int idx = ids.findIndex( id );
CategoryTab *tab = (CategoryTab *)categoryBar->tab( idx );
// 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 );
}
QString textCol = cfg.readEntry( "TextColor" );
if ( textCol.isEmpty() )
v->setTextColor( QColor() );
else
v->setTextColor( QColor(textCol) );
QStringList font = cfg.readListEntry( "Font", ',' );
if ( font.count() == 4 )
v->setViewFont( QFont(font[0], font[1].toInt(), font[2].toInt(), font[3].toInt()!=0) );
// 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 CategoryTabWidget::updateDocs(AppLnkSet* docFolder, const QList<FileSystem> &fs)
{
docview->populate( docFolder, QString::null );
docFolder->detachChildren();
docview->setFileSystems(fs);
docview->updateTools();
}
void CategoryTabWidget::tabProperties()
{
LauncherView *view = (LauncherView*)stack->widget( categoryBar->currentTab() );
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;
}
QString CategoryTabWidget::getAllDocLinkInfo() const
{
return docview->getAllDocLinkInfo();
}
LauncherView* CategoryTabWidget::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*)));
ids.append(id);
categoryBar->addTab( new CategoryTab( pm, label ) );
stack->addWidget( view, tabs++ );
return view;
}
void CategoryTabWidget::updateLink(const QString& linkfile)
{
int i=0;
LauncherView* view;
while ((view = (LauncherView*)stack->widget(i++))) {
if ( view->removeLink(linkfile) )
break;
}
addItem(linkfile);
docview->updateTools();
}
void CategoryTabWidget::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 CategoryTabWidget::setBusy(bool on)
{
if ( on )
((LauncherView*)stack->visibleWidget())->setBusy(TRUE);
else
for (int i=0; i<tabs; i++)
((LauncherView*)stack->widget(i))->setBusy(FALSE);
}
LauncherView *CategoryTabWidget::view( const QString &id )
{
int idx = ids.findIndex( id );
return (LauncherView *)stack->widget(idx);
}
void CategoryTabWidget::setBusyIndicatorType ( const QString &type )
{
for ( QStringList::Iterator it = ids. begin ( ); it != ids. end ( ); ++it )
view ( *it )-> setBusyIndicatorType ( type );
}
//===========================================================================
CategoryTabBar::CategoryTabBar( QWidget *parent, const char *name )
: QTabBar( parent, name )
{
setFocusPolicy( NoFocus );
connect( this, SIGNAL( selected(int) ), this, SLOT( layoutTabs() ) );
}
CategoryTabBar::~CategoryTabBar()
{
}
void CategoryTabBar::layoutTabs()
{
if ( !count() )
return;
// int percentFalloffTable[] = { 100, 70, 40, 12, 6, 3, 1, 0 };
int available = width()-1;
QFontMetrics fm = fontMetrics();
int hiddenTabWidth = -7;
int middleTab = currentTab();
int hframe, vframe, overlap;
style().tabbarMetrics( this, hframe, vframe, overlap );
int x = 0;
QRect r;
QTab *t;
int required = 0;
int eventabwidth = (width()-1)/count();
enum Mode { HideBackText, Pack, Even } mode=Even;
for ( int i = 0; i < count(); i++ ) {
t = tab(i);
int iw = fm.width( t->text() ) + hframe - overlap;
if ( i != middleTab ) {
available -= hiddenTabWidth + hframe - overlap;
if ( t->iconSet() != 0 )
available -= t->iconSet()->pixmap( QIconSet::Small, QIconSet::Normal ).width();
}
if ( t->iconSet() != 0 )
iw += t->iconSet()->pixmap( QIconSet::Small, QIconSet::Normal ).width();
required += iw;
// As space gets tight, packed looks better than even. "10" must be at least 0.
if ( iw >= eventabwidth-10 )
mode = Pack;
}
if ( mode == Pack && required > width()-1 )
mode = HideBackText;
for ( int i = 0; i < count(); i++ ) {
t = tab(i);
if ( mode != HideBackText ) {
int w = fm.width( t->text() );
int ih = 0;
if ( t->iconSet() != 0 ) {
w += t->iconSet()->pixmap( QIconSet::Small, QIconSet::Normal ).width();
ih = t->iconSet()->pixmap( QIconSet::Small, QIconSet::Normal ).height();
}
int h = QMAX( fm.height(), ih );
h = QMAX( h, QApplication::globalStrut().height() );
h += vframe;
w += hframe;
QRect tr(x, 0,
mode == Even ? eventabwidth : w * (width()-1)/required, h);
t->setRect(tr);
x += tr.width() - overlap;
r = r.unite(tr);
} else if ( i != middleTab ) {
int w = hiddenTabWidth;
int ih = 0;
if ( t->iconSet() != 0 ) {
w += t->iconSet()->pixmap( QIconSet::Small, QIconSet::Normal ).width();
ih = t->iconSet()->pixmap( QIconSet::Small, QIconSet::Normal ).height();
}
int h = QMAX( fm.height(), ih );
h = QMAX( h, QApplication::globalStrut().height() );
h += vframe;
w += hframe;
t->setRect( QRect(x, 0, w, h) );
x += t->rect().width() - overlap;
r = r.unite( t->rect() );
} else {
int ih = 0;
if ( t->iconSet() != 0 ) {
ih = t->iconSet()->pixmap( QIconSet::Small, QIconSet::Normal ).height();
}
int h = QMAX( fm.height(), ih );
h = QMAX( h, QApplication::globalStrut().height() );
h += vframe;
t->setRect( QRect(x, 0, available, h) );
x += t->rect().width() - overlap;
r = r.unite( t->rect() );
}
}
QRect rr = tab(count()-1)->rect();
rr.setRight(width()-1);
tab(count()-1)->setRect( rr );
for ( t = tabList()->first(); t; t = tabList()->next() ) {
QRect tr = t->rect();
tr.setHeight( r.height() );
t->setRect( tr );
}
update();
}
void CategoryTabBar::paint( QPainter * p, QTab * t, bool selected ) const
{
CategoryTabBar *that = (CategoryTabBar *) this;
CategoryTab *ct = (CategoryTab *)t;
QPalette pal = palette();
bool setPal = FALSE;
if ( ct->bgColor.isValid() ) {
pal.setColor( QPalette::Active, QColorGroup::Background, ct->bgColor );
pal.setColor( QPalette::Active, QColorGroup::Button, ct->bgColor );
pal.setColor( QPalette::Inactive, QColorGroup::Background, ct->bgColor );
pal.setColor( QPalette::Inactive, QColorGroup::Button, ct->bgColor );
that->setUpdatesEnabled( FALSE );
that->setPalette( pal );
setPal = TRUE;
}
#if QT_VERSION >= 300
QStyle::SFlags flags = QStyle::Style_Default;
if ( selected )
flags |= QStyle::Style_Selected;
style().drawControl( QStyle::CE_TabBarTab, p, this, t->rect(),
colorGroup(), flags, QStyleOption(t) );
#else
style().drawTab( p, this, t, selected );
#endif
QRect r( t->rect() );
QFont f( font() );
if ( selected )
f.setBold( TRUE );
p->setFont( f );
if ( ct->fgColor.isValid() ) {
pal.setColor( QPalette::Active, QColorGroup::Foreground, ct->fgColor );
pal.setColor( QPalette::Inactive, QColorGroup::Foreground, ct->fgColor );
that->setUpdatesEnabled( FALSE );
that->setPalette( pal );
setPal = TRUE;
}
int iw = 0;
int ih = 0;
if ( t->iconSet() != 0 ) {
iw = t->iconSet()->pixmap( QIconSet::Small, QIconSet::Normal ).width() + 2;
ih = t->iconSet()->pixmap( QIconSet::Small, QIconSet::Normal ).height();
}
int w = iw + p->fontMetrics().width( t->text() ) + 4;
int h = QMAX(p->fontMetrics().height() + 4, ih );
paintLabel( p, QRect( r.left() + (r.width()-w)/2 - 3,
r.top() + (r.height()-h)/2, w, h ), t,
#if QT_VERSION >= 300
t->identifier() == keyboardFocusTab()
#else
t->identitifer() == keyboardFocusTab()
#endif
);
if ( setPal ) {
that->unsetPalette();
that->setUpdatesEnabled( TRUE );
}
}
void CategoryTabBar::paintLabel( QPainter* p, const QRect&,
QTab* t, bool has_focus ) const
{
QRect r = t->rect();
// if ( t->id != currentTab() )
//r.moveBy( 1, 1 );
//
if ( t->iconSet() ) {
// the tab has an iconset, draw it in the right mode
QIconSet::Mode mode = (t->isEnabled() && isEnabled()) ? QIconSet::Normal : QIconSet::Disabled;
if ( mode == QIconSet::Normal && has_focus )
mode = QIconSet::Active;
QPixmap pixmap = t->iconSet()->pixmap( QIconSet::Small, mode );
int pixw = pixmap.width();
int pixh = pixmap.height();
p->drawPixmap( r.left() + 6, r.center().y() - pixh / 2 + 1, pixmap );
r.setLeft( r.left() + pixw + 5 );
}
QRect tr = r;
if ( r.width() < 20 )
return;
if ( t->isEnabled() && isEnabled() ) {
#if defined(_WS_WIN32_)
if ( colorGroup().brush( QColorGroup::Button ) == colorGroup().brush( QColorGroup::Background ) )
p->setPen( colorGroup().buttonText() );
else
p->setPen( colorGroup().foreground() );
#else
p->setPen( colorGroup().foreground() );
#endif
p->drawText( tr, AlignCenter | AlignVCenter | ShowPrefix, t->text() );
} else {
p->setPen( palette().disabled().foreground() );
p->drawText( tr, AlignCenter | AlignVCenter | ShowPrefix, t->text() );
}
}
//---------------------------------------------------------------------------
Launcher::Launcher( QWidget* parent, const char* name, WFlags fl )
: QMainWindow( parent, name, fl )
{
setCaption( tr("Launcher") );
syncDialog = 0;
// we have a pretty good idea how big we'll be
setGeometry( 0, 0, qApp->desktop()->width(), qApp->desktop()->height() );
tabs = 0;
rootFolder = 0;
docsFolder = 0;
int stamp = uidgen.generate(); // this is our timestamp to see which devices we know
//uidgen.store( stamp );
m_timeStamp = QString::number( stamp );
tabs = new CategoryTabWidget( this );
tabs->setMaximumWidth( qApp->desktop()->width() );
setCentralWidget( tabs );
connect( tabs, SIGNAL(selected(const QString&)),
this, SLOT(viewSelected(const QString&)) );
connect( tabs, SIGNAL(clicked(const AppLnk*)),
this, SLOT(select(const AppLnk*)));
connect( tabs, SIGNAL(rightPressed(AppLnk*)),
this, SLOT(properties(AppLnk*)));
#if !defined(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 &)) );
QCopChannel *channel = new QCopChannel( "QPE/Launcher", this );
connect( channel, SIGNAL(received(const QCString&, const QByteArray&)),
this, SLOT(launcherMessage(const QCString&, const QByteArray&)) );
#endif
storage = new StorageInfo( this );
connect( storage, SIGNAL( disksChanged() ), SLOT( storageChanged() ) );
updateTabs();
preloadApps();
in_lnk_props = FALSE;
got_lnk_change = FALSE;
}
Launcher::~Launcher()
{
delete rootFolder;
delete docsFolder;
}
static bool isVisibleWindow(int wid)
{
#ifdef 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::showMaximized()
{
if ( isVisibleWindow( winId() ) )
doMaximize();
else
QTimer::singleShot( 20, this, SLOT(doMaximize()) );
}
void Launcher::doMaximize()
{
QMainWindow::showMaximized();
}
void Launcher::updateMimeTypes()
{
MimeType::clear();
updateMimeTypes(rootFolder);
}
void Launcher::updateMimeTypes(AppLnkSet* folder)
{
for ( QListIterator<AppLnk> it( folder->children() ); it.current(); ++it ) {
AppLnk *app = it.current();
if ( app->type() == "Folder" ) // No tr
updateMimeTypes((AppLnkSet *)app);
else {
MimeType::registerApp(*app);
}
}
}
/** This is a HACK....
* Reason: scanning huge mediums, microdirvers for examples
* consomes time. To avoid that we invented the MediumMountCheck
*
* a) the user globally disabled medium checking. We can ignore
* all removable medium
* b) the user enabled medium checking globally and we need to use this mimefilter
* c) the user enabled medium checking on a per medium bases
* c1) we already checked and its not ask again turns
* c2) we need to ask and then apply the mimefilter
*/
void Launcher::loadDocs() // ok here comes a hack belonging to Global::
{
delete docsFolder;
docsFolder = new DocLnkSet;
DocLnkSet *tmp = 0;
QString home = QString(getenv("HOME")) + "/Documents";
tmp = new DocLnkSet( home , QString::null);
docsFolder->appendFrom( *tmp );
delete tmp;
// RAM documents
StorageInfo storage;
const QList<FileSystem> &fileSystems = storage.fileSystems();
QListIterator<FileSystem> it ( fileSystems );
for ( ; it.current(); ++it ) {
if ( (*it)->disk() == "/dev/mtdblock6" || (*it)->disk() == "tmpfs" ) {
tmp = new DocLnkSet( (*it)->path(), QString::null );
docsFolder->appendFrom( *tmp );
delete tmp;
}
}
Config mediumCfg( "medium");
mediumCfg.setGroup("main");
// a) -zecke we don't want to check
if(!mediumCfg.readBoolEntry("use", true ) )
return;
// find out wich filesystems are new in this round
// We will do this by having a timestamp inside each mountpoint
// if the current timestamp doesn't match this is a new file system and
// come up with our MediumMountGui :) let the hacking begin
int stamp = uidgen.generate();
QString newStamp = QString::number( stamp ); // generates newtime Stamp
// b)
if( mediumCfg.readBoolEntry("global", true ) ){
QString mime = configToMime(&mediumCfg).join(";");
for( it.toFirst(); it.current(); ++it ){
if( (*it)->isRemovable() ){
tmp = new DocLnkSet( (*it)->path(), mime );
docsFolder->appendFrom( *tmp );
delete tmp;
}
} // done
return; // save the else
}
// c) zecke
for ( it.toFirst(); it.current(); ++it ) {
if ( (*it)->isRemovable() ) { // let's find out if we should search on it
Config cfg( (*it)->path() + "/.opiestorage.cf", Config::File);
cfg.setGroup("main");
QString stamp = cfg.readEntry("timestamp", QDateTime::currentDateTime().toString() );
/** This medium is uptodate
*/
if( stamp == m_timeStamp ){ // ok we know this card
cfg.writeEntry("timestamp", newStamp ); //just write a new timestamp
// we need to scan the list now. Hopefully the cache will be there
// read the mimetypes from the config and search for documents
QStringList mimetypes = configToMime( &cfg);
tmp = new DocLnkSet( (*it)->path(), mimetypes.join(";") );
docsFolder->appendFrom( *tmp );
delete tmp;
}else{ // come up with the gui cause this a new card
MediumMountGui medium(&cfg, (*it)->path() );
if( medium.check() ){ // we did not ask before or ask again is off
/** c2) */
if( medium.exec() ){ // he clicked yes so search it
// speicher
//cfg.read(); // cause of a race we need to reread - fixed
cfg.setGroup("main");
cfg.writeEntry("timestamp", newStamp );
cfg.write();
tmp = new DocLnkSet( (*it)->path(), medium.mimeTypes().join(";" ) );
docsFolder->appendFrom( *tmp );
delete tmp;
}// no else
/** c1) */
}else{ // we checked
// do something different see what we need to do
// let's see if we should check the device
cfg.setGroup("main" );
bool check = cfg.readBoolEntry("autocheck", true );
if( check ){ // find the documents
tmp = new DocLnkSet( (*it)->path(), configToMime(&cfg ).join(";") );
docsFolder->appendFrom( *tmp );
delete tmp;
}
}
}
}
}
m_timeStamp = newStamp;
}
void Launcher::updateTabs()
{
MimeType::updateApplications(); // ### reads all applnks twice
delete rootFolder;
rootFolder = new AppLnkSet( MimeType::appsFolderName() );
loadDocs();
tabs->initializeCategories(rootFolder, docsFolder, storage->fileSystems());
}
void Launcher::updateDocs()
{
loadDocs();
tabs->updateDocs(docsFolder,storage->fileSystems());
}
void Launcher::viewSelected(const QString& s)
{
setCaption( s + tr(" - Launcher") );
}
void Launcher::nextView()
{
tabs->nextTab();
}
void Launcher::select( const AppLnk *appLnk )
{
if ( appLnk->type() == "Folder" ) { // No tr
// Not supported: flat is simpler for the user
} else {
if ( appLnk->exec().isNull() ) {
QMessageBox::information(this,tr("No application"),
tr("<p>No application is defined for this document."
"<p>Type is %1.").arg(appLnk->type()));
return;
}
tabs->setBusy(TRUE);
emit executing( appLnk );
appLnk->execute();
}
}
void Launcher::externalSelected(const AppLnk *appLnk)
{
tabs->setBusy(TRUE);
emit executing( appLnk );
}
void Launcher::properties( AppLnk *appLnk )
{
if ( appLnk->type() == "Folder" ) { // No tr
// Not supported: flat is simpler for the user
} else {
in_lnk_props = TRUE;
got_lnk_change = FALSE;
LnkProperties prop(appLnk);
connect(&prop, SIGNAL(select(const AppLnk *)), this, SLOT(externalSelected(const AppLnk *)));
prop.showMaximized();
prop.exec();
in_lnk_props = FALSE;
if ( got_lnk_change ) {
updateLink(lnk_change);
}
}
}
void Launcher::updateLink(const QString& link)
{
if (link.isNull())
updateTabs();
else if (link.isEmpty())
updateDocs();
else
tabs->updateLink(link);
}
void Launcher::systemMessage( const QCString &msg, const QByteArray &data)
{
QDataStream stream( data, IO_ReadOnly );
if ( msg == "linkChanged(QString)" ) {
QString link;
stream >> link;
if ( in_lnk_props ) {
got_lnk_change = TRUE;
lnk_change = link;
} else {
updateLink(link);
}
} else if ( msg == "busy()" ) {
emit busy();
} else if ( msg == "notBusy(QString)" ) {
QString app;
stream >> app;
tabs->setBusy(FALSE);
emit notBusy(app);
} else if ( msg == "mkdir(QString)" ) {
QString dir;
stream >> dir;
if ( !dir.isEmpty() )
mkdir( dir );
} else if ( msg == "rdiffGenSig(QString,QString)" ) {
QString baseFile, sigFile;
stream >> baseFile >> sigFile;
QRsync::generateSignature( baseFile, sigFile );
} else if ( msg == "rdiffGenDiff(QString,QString,QString)" ) {
QString baseFile, sigFile, deltaFile;
stream >> baseFile >> sigFile >> deltaFile;
QRsync::generateDiff( baseFile, sigFile, deltaFile );
} else if ( msg == "rdiffApplyPatch(QString,QString)" ) {
QString baseFile, deltaFile;
stream >> baseFile >> deltaFile;
if ( !QFile::exists( baseFile ) ) {
QFile f( baseFile );
f.open( IO_WriteOnly );
f.close();
}
QRsync::applyDiff( baseFile, deltaFile );
#ifndef QT_NO_COP
QCopEnvelope e( "QPE/Desktop", "patchApplied(QString)" );
e << baseFile;
#endif
} else if ( msg == "rdiffCleanup()" ) {
mkdir( "/tmp/rdiff" );
QDir dir;
dir.setPath( "/tmp/rdiff" );
QStringList entries = dir.entryList();
for ( QStringList::Iterator it = entries.begin(); it != entries.end(); ++it )
dir.remove( *it );
} else if ( msg == "sendHandshakeInfo()" ) {
QString home = getenv( "HOME" );
#ifndef QT_NO_COP
QCopEnvelope e( "QPE/Desktop", "handshakeInfo(QString,bool)" );
e << home;
int locked = (int) Desktop::screenLocked();
e << locked;
#endif
} else if ( msg == "autoStart(QString)" ) {
QString appName;
stream >> appName;
Config cfg( "autostart" );
cfg.setGroup( "AutoStart" );
if ( appName.compare("clear") == 0){
cfg.writeEntry("Apps", "");
}
} else if ( msg == "autoStart(QString,QString)" ) {
QString modifier, appName;
stream >> modifier >> appName;
Config cfg( "autostart" );
cfg.setGroup( "AutoStart" );
if ( modifier.compare("add") == 0 ){
// only add if appname is entered
if (!appName.isEmpty()) {
cfg.writeEntry("Apps", appName);
}
} else if (modifier.compare("remove") == 0 ) {
// need to change for multiple entries
// actually remove is right now simular to clear, but in future there
// should be multiple apps in autostart possible.
QString checkName;
checkName = cfg.readEntry("Apps", "");
if (checkName == appName) {
cfg.writeEntry("Apps", "");
}
}
// case the autostart feature should be delayed
} else if ( msg == "autoStart(QString,QString,QString)") {
QString modifier, appName, delay;
stream >> modifier >> appName >> delay;
Config cfg( "autostart" );
cfg.setGroup( "AutoStart" );
if ( modifier.compare("add") == 0 ){
// only add it appname is entered
if (!appName.isEmpty()) {
cfg.writeEntry("Apps", appName);
cfg.writeEntry("Delay", delay);
}
} else {
}
}
/*
* QtopiaDesktop relies on the major number
* to start with 1. We're at 0.9
* so wee need to fake at least 1.4 to be able
* to sync with QtopiaDesktop1.6
*/
else if ( msg == "sendVersionInfo()" ) {
QCopEnvelope e( "QPE/Desktop", "versionInfo(QString)" );
QString v2 = QString::fromLatin1("1.4");
e << v2;
//qDebug("version %s\n", line.latin1());
} else if ( msg == "sendCardInfo()" ) {
#ifndef QT_NO_COP
QCopEnvelope e( "QPE/Desktop", "cardInfo(QString)" );
#endif
const QList<FileSystem> &fs = storage->fileSystems();
QListIterator<FileSystem> it ( fs );
QString s;
QString homeDir = getenv("HOME");
QString hardDiskHome, hardDiskHomePath;
for ( ; it.current(); ++it ) {
int k4 = (*it)->blockSize()/256;
if ( (*it)->isRemovable() || (*it)->disk() == "/dev/mtdblock6" || (*it)->disk() == "tmpfs") {
s += (*it)->name() + "=" + (*it)->path() + "/Documents "
+ QString::number( (*it)->availBlocks() * k4/4 )
+ "K " + (*it)->options() + ";";
} else if ( (*it)->disk() == "/dev/mtdblock1" ||
(*it)->disk() == "/dev/mtdblock/1" ) {
s += (*it)->name() + "=" + homeDir + "/Documents "
+ QString::number( (*it)->availBlocks() * k4/4 )
+ "K " + (*it)->options() + ";";
} else if ( (*it)->name().contains( "Hard Disk") &&
homeDir.contains( (*it)->path() ) &&
(*it)->path().length() > hardDiskHomePath.length() ) {
hardDiskHomePath = (*it)->path();
hardDiskHome =
(*it)->name() + "=" + homeDir + "/Documents "
+ QString::number( (*it)->availBlocks() * k4/4 )
+ "K " + (*it)->options() + ";";
}
}
if ( !hardDiskHome.isEmpty() )
s += hardDiskHome;
#ifndef QT_NO_COP
e << s;
#endif
} else if ( msg == "sendSyncDate(QString)" ) {
QString app;
stream >> app;
Config cfg( "qpe" );
cfg.setGroup("SyncDate");
#ifndef QT_NO_COP
QCopEnvelope e( "QPE/Desktop", "syncDate(QString,QString)" );
e << app << cfg.readEntry( app );
#endif
//qDebug("QPE/System sendSyncDate for %s: response %s", app.latin1(),
//cfg.readEntry( app ).latin1() );
} else if ( msg == "setSyncDate(QString,QString)" ) {
QString app, date;
stream >> app >> date;
Config cfg( "qpe" );
cfg.setGroup("SyncDate");
cfg.writeEntry( app, date );
//qDebug("setSyncDate(QString,QString) %s %s", app.latin1(), date.latin1());
} else if ( msg == "startSync(QString)" ) {
QString what;
stream >> what;
delete syncDialog; syncDialog = 0;
syncDialog = new SyncDialog( this, "syncProgress", FALSE,
WStyle_Tool | WStyle_Customize |
Qt::WStyle_StaysOnTop );
syncDialog->showMaximized();
syncDialog->whatLabel->setText( "<b>" + what + "</b>" );
connect( syncDialog->buttonCancel, SIGNAL( clicked() ),
SLOT( cancelSync() ) );
} else if ( msg == "stopSync()") {
delete syncDialog; syncDialog = 0;
} else if ( msg == "getAllDocLinks()" ) {
loadDocs();
QString contents;
// Categories cats;
for ( QListIterator<DocLnk> it( docsFolder->children() ); it.current(); ++it ) {
DocLnk *doc = it.current();
QFileInfo fi( doc->file() );
if ( !fi.exists() )
continue;
bool fake = !doc->linkFileKnown();
if ( !fake ) {
QFile f( doc->linkFile() );
if ( f.open( IO_ReadOnly ) ) {
QTextStream ts( &f );
ts.setEncoding( QTextStream::UnicodeUTF8 );
contents += ts.read();
f.close();
} else
fake = TRUE;
}
if (fake) {
contents += "[Desktop Entry]\n";
contents += "Categories = " + // No tr
// cats.labels("Document View",doc->categories()).join(";") + "\n"; // No tr
Qtopia::Record::idsToString( doc->categories() ) + "\n";
contents += "Name = "+doc->name()+"\n"; // No tr
contents += "Type = "+doc->type()+"\n"; // No tr
}
contents += "File = "+doc->file()+"\n"; // No tr // (resolves path)
contents += QString("Size = %1\n").arg( fi.size() ); // No tr
}
//qDebug( "sending length %d", contents.length() );
#ifndef QT_NO_COP
QCopEnvelope e( "QPE/Desktop", "docLinks(QString)" );
e << contents;
#endif
//qDebug( "================ \n\n%s\n\n===============",
//contents.latin1() );
delete docsFolder;
docsFolder = 0;
#ifdef QWS
} else if ( msg == "setMouseProto(QString)" ) {
QString mice;
stream >> mice;
setenv("QWS_MOUSE_PROTO",mice.latin1(),1);
qwsServer->openMouse();
} else if ( msg == "setKeyboard(QString)" ) {
QString kb;
stream >> kb;
setenv("QWS_KEYBOARD",kb.latin1(),1);
qwsServer->openKeyboard();
#endif
}
}
void Launcher::cancelSync()
{
#ifndef QT_NO_COP
QCopEnvelope e( "QPE/Desktop", "cancelSync()" );
#endif
}
void Launcher::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 ( tabs->view(id) )
tabs->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 ( tabs->view(id) )
tabs->view(id)->setBackgroundType( (LauncherView::BackgroundType)mode, pixmapOrColor );
} else if ( msg == "setTextColor(QString,QString)" ) {
QString id;
stream >> id;
QString color;
stream >> color;
if ( tabs->view(id) )
tabs->view(id)->setTextColor( QColor(color) );
} 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 ( tabs->view(id) )
if ( !fam. isEmpty ( ))
tabs->view(id)->setViewFont( QFont(fam, size, weight, italic!=0) );
else
tabs->view(id)->unsetViewFont();
qDebug( "setFont: %s, %d, %d, %d", fam.latin1(), size, weight, italic );
}
else if ( msg == "setBusyIndicatorType(QString)" ) {
QString type;
stream >> type;
tabs->setBusyIndicatorType(type);
}
+ else if ( msg == "home()" ) {
+ if ( isVisibleWindow( winId ( )))
+ nextView ( );
+ else
+ raise ( );
+
+ }
}
void Launcher::storageChanged()
{
if ( in_lnk_props ) {
got_lnk_change = TRUE;
lnk_change = QString::null;
} else {
updateLink( QString::null );
}
}
bool Launcher::mkdir(const QString &localPath)
{
QDir fullDir(localPath);
if (fullDir.exists())
return true;
// at this point the directory doesn't exist
// go through the directory tree and start creating the direcotories
// that don't exist; if we can't create the directories, return false
QString dirSeps = "/";
int dirIndex = localPath.find(dirSeps);
QString checkedPath;
// didn't find any seps; weird, use the cur dir instead
if (dirIndex == -1) {
//qDebug("No seperators found in path %s", localPath.latin1());
checkedPath = QDir::currentDirPath();
}
while (checkedPath != localPath) {
// no more seperators found, use the local path
if (dirIndex == -1)
checkedPath = localPath;
else {
// the next directory to check
checkedPath = localPath.left(dirIndex) + "/";
// advance the iterator; the next dir seperator
dirIndex = localPath.find(dirSeps, dirIndex+1);
}
QDir checkDir(checkedPath);
if (!checkDir.exists()) {
//qDebug("mkdir making dir %s", checkedPath.latin1());
if (!checkDir.mkdir(checkedPath)) {
qDebug("Unable to make directory %s", checkedPath.latin1());
return FALSE;
}
}
}
return TRUE;
}
void Launcher::preloadApps()
{
Config cfg("Launcher");
cfg.setGroup("Preload");
QStringList apps = cfg.readListEntry("Apps",',');
for (QStringList::ConstIterator it=apps.begin(); it!=apps.end(); ++it) {
#ifndef QT_NO_COP
QCopEnvelope e("QPE/Application/"+(*it).local8Bit(), "enablePreload()");
#endif
}
}
diff --git a/core/launcher/main.cpp b/core/launcher/main.cpp
index 8b91f5d..49b41d6 100644
--- a/core/launcher/main.cpp
+++ b/core/launcher/main.cpp
@@ -1,182 +1,177 @@
/**********************************************************************
** Copyright (C) 2000 Trolltech AS. All rights reserved.
**
** This file is part of Qtopia Environment.
**
** This file may be distributed and/or modified under the terms of the
** GNU General Public License version 2 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
** See http://www.trolltech.com/gpl/ for GPL licensing information.
**
** Contact info@trolltech.com if any conditions of this licensing are
** not clear to you.
**
**********************************************************************/
#include "desktop.h"
#include "taskbar.h"
#include "stabmon.h"
#include <qpe/qpeapplication.h>
#include <qpe/network.h>
#include <qpe/config.h>
#if defined( QT_QWS_SHARP ) || defined( QT_QWS_IPAQ )
#include <qpe/custom.h>
#endif
#include <opie/odevice.h>
#include <qmessagebox.h>
#include <qfile.h>
#include <qimage.h>
#include <qwindowsystem_qws.h>
#include <qpe/qcopenvelope_qws.h>
#include <qpe/alarmserver.h>
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#if defined(QT_QWS_IPAQ) || defined(QT_QWS_EBX)
#include "../calibrate/calibrate.h"
#endif
using namespace Opie;
void initEnvironment()
{
Config config("locale");
config.setGroup( "Location" );
QString tz = config.readEntry( "Timezone", getenv("TZ") );
// if not timezone set, pick New York
if (tz.isNull())
tz = "America/New_York";
setenv( "TZ", tz, 1 );
config.writeEntry( "Timezone", tz);
config.setGroup( "Language" );
QString lang = config.readEntry( "Language", getenv("LANG") );
if ( !lang.isNull() )
setenv( "LANG", lang, 1 );
}
int initApplication( int argc, char ** argv )
{
initEnvironment();
#if !defined(QT_QWS_CASSIOPEIA) && !defined(QT_QWS_IPAQ) && !defined(QT_QWS_EBX)
setenv( "QWS_SIZE", "240x320", 0 );
#endif
//Don't flicker at startup:
QWSServer::setDesktopBackground( QImage() );
DesktopApplication a( argc, argv, QApplication::GuiServer );
ODevice::inst ( )-> setSoftSuspend ( true );
{ // init backlight
QCopEnvelope e("QPE/System", "setBacklight(int)" );
e << -3; // Forced on
}
AlarmServer::initialize();
Desktop *d = new Desktop();
- QObject::connect( &a, SIGNAL(menu()), d, SLOT(raiseMenu()) );
- QObject::connect( &a, SIGNAL(datebook()), d, SLOT(raiseDatebook()) );
- QObject::connect( &a, SIGNAL(contacts()), d, SLOT(raiseContacts()) );
- QObject::connect( &a, SIGNAL(launch()), d, SLOT(raiseLauncher()) );
- QObject::connect( &a, SIGNAL(email()), d, SLOT(raiseEmail()) );
QObject::connect( &a, SIGNAL(power()), d, SLOT(togglePower()) );
QObject::connect( &a, SIGNAL(backlight()), d, SLOT(toggleLight()) );
QObject::connect( &a, SIGNAL(symbol()), d, SLOT(toggleSymbolInput()) );
QObject::connect( &a, SIGNAL(numLockStateToggle()), d, SLOT(toggleNumLockState()) );
QObject::connect( &a, SIGNAL(capsLockStateToggle()), d, SLOT(toggleCapsLockState()) );
QObject::connect( &a, SIGNAL(prepareForRestart()), d, SLOT(terminateServers()) );
(void)new SysFileMonitor(d);
Network::createServer(d);
#if defined(QT_QWS_CASSIOPEIA) || defined(QT_QWS_IPAQ) || defined(QT_QWS_EBX)
if ( !QFile::exists( "/etc/pointercal" ) ) {
// Make sure calibration widget starts on top.
Calibrate *cal = new Calibrate;
cal->exec();
delete cal;
}
#endif
d->show();
if ( QDate::currentDate ( ). year ( ) < 2000 ) {
if ( QMessageBox::information ( 0, DesktopApplication::tr( "Information" ), DesktopApplication::tr( "<p>The system date doesn't seem to be valid.\n(%1)</p><p>Do you want to correct the clock ?</p>" ). arg( TimeString::dateString ( QDate::currentDate ( ))), QMessageBox::Yes, QMessageBox::No ) == QMessageBox::Yes ) {
QCopEnvelope e ( "QPE/Application/systemtime", "setDocument(QString)" );
e << QString ( );
}
}
int rv = a.exec();
delete d;
ODevice::inst ( )-> setSoftSuspend ( false );
return rv;
}
static const char *pidfile_path = "/var/run/opie.pid";
void create_pidfile ( )
{
FILE *f;
if (( f = ::fopen ( pidfile_path, "w" ))) {
::fprintf ( f, "%d", getpid ( ));
::fclose ( f );
}
}
void remove_pidfile ( )
{
::unlink ( pidfile_path );
}
void handle_sigterm ( int /* sig */ )
{
if ( qApp )
qApp-> quit ( );
}
int main( int argc, char ** argv )
{
::signal ( SIGCHLD, SIG_IGN );
::signal ( SIGTERM, handle_sigterm );
::signal ( SIGINT, handle_sigterm );
::setsid ( );
::setpgid ( 0, 0 );
::atexit ( remove_pidfile );
create_pidfile ( );
int retVal = initApplication ( argc, argv );
// Kill them. Kill them all.
::kill ( 0, SIGTERM );
::sleep ( 1 );
::kill ( 0, SIGKILL );
return retVal;
}
diff --git a/core/launcher/opie-taskbar.control b/core/launcher/opie-taskbar.control
index 13e5715..8bf2113 100644
--- a/core/launcher/opie-taskbar.control
+++ b/core/launcher/opie-taskbar.control
@@ -1,9 +1,9 @@
-Files: bin/qpe apps/Settings/Calibrate.desktop pics/launcher plugins/applets/libsuspendapplet.so* plugins/applets/libhomeapplet.so* plugins/applets/liblogoutapplet.so*
+Files: bin/qpe apps/Settings/Calibrate.desktop pics/launcher pics/devicebuttons/*.png plugins/applets/libsuspendapplet.so* plugins/applets/libhomeapplet.so* plugins/applets/liblogoutapplet.so*
Priority: required
Section: opie/system
Maintainer: Project Opie <opie@handhelds.org>
Architecture: arm
Version: $QPE_VERSION-$SUB_VERSION.1
Depends: qt-embedded (>=$QTE_VERSION)
Description: Launcher for Opie
The "finder" or "explorer", or whatever you want to call it.
diff --git a/core/launcher/runningappbar.cpp b/core/launcher/runningappbar.cpp
index 3ac66f2..356200b 100644
--- a/core/launcher/runningappbar.cpp
+++ b/core/launcher/runningappbar.cpp
@@ -1,322 +1,313 @@
/**********************************************************************
** 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.
**
**********************************************************************
*/
#define QTOPIA_INTERNAL_PRELOADACCESS
// For "kill"
#include <sys/types.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <qdir.h>
#include <qtimer.h>
#include <qpopupmenu.h>
#include <qmessagebox.h>
#include <qpainter.h>
#include <opie/oprocess.h>
#include <qpe/qpeapplication.h>
#include <qpe/applnk.h>
#include <qpe/qcopenvelope_qws.h>
#include <qpe/global.h>
#include <qwindowsystem_qws.h>
#include "runningappbar.h"
RunningAppBar::RunningAppBar(QWidget* parent)
: QFrame(parent), m_AppLnkSet(0L), m_SelectedAppIndex( -1)
{
setBackgroundMode( PaletteBackground );
m_AppLnkSet = new AppLnkSet( QPEApplication::qpeDir() + "apps" );
#ifdef QWS
connect(qwsServer, SIGNAL(newChannel(const QString&)), this, SLOT(newQcopChannel(const QString&)));
connect(qwsServer, SIGNAL(removedChannel(const QString&)), this, SLOT(removedQcopChannel(const QString&)));
#endif
QCopChannel* channel = new QCopChannel( "QPE/System", this );
connect( channel, SIGNAL(received(const QCString&, const QByteArray&)),
this, SLOT(received(const QCString&, const QByteArray&)) );
spacing = AppLnk::smallIconSize() + 3;
}
RunningAppBar::~RunningAppBar()
{}
void RunningAppBar::newQcopChannel(const QString& channelName)
{
QString prefix("QPE/Application/");
if (channelName.startsWith(prefix)) {
QString appName = channelName.mid(prefix.length());
// qDebug("App %s just connected!", appName.latin1());
const AppLnk* newGuy = m_AppLnkSet->findExec(appName);
if (newGuy && !newGuy->isPreloaded()) {
addTask(*newGuy);
}
}
}
void RunningAppBar::removedQcopChannel(const QString& channelName)
{
QString prefix("QPE/Application/");
if (channelName.startsWith(prefix)) {
QString appName = channelName.mid(prefix.length());
qDebug("App %s just disconnected!", appName.latin1());
const AppLnk* newGuy = m_AppLnkSet->findExec(appName);
if (newGuy) {
removeTask(*newGuy);
}
}
}
void RunningAppBar::received(const QCString& msg, const QByteArray& data)
{
// Since fast apps appear and disappear without disconnecting from their
// channel we need to watch for the showing/hiding events and update according.
QDataStream stream( data, IO_ReadOnly );
if ( msg == "fastAppShowing(QString)") {
QString appName;
stream >> appName;
addTask(*m_AppLnkSet->findExec(appName));
}
else if ( msg == "fastAppHiding(QString)") {
QString appName;
stream >> appName;
removeTask(*m_AppLnkSet->findExec(appName));
}
}
void RunningAppBar::addTask(const AppLnk& appLnk)
{
// qDebug("Added %s to app list.", appLnk.name().latin1());
AppLnk* newApp = new AppLnk(appLnk);
newApp->setExec(appLnk.exec());
m_AppList.prepend(newApp);
update();
}
void RunningAppBar::removeTask(const AppLnk& appLnk)
{
unsigned int i = 0;
for (; i < m_AppList.count() ; i++) {
AppLnk* target = m_AppList.at(i);
if (target->exec() == appLnk.exec()) {
qDebug("Removing %s from app list.", appLnk.name().latin1());
m_AppList.remove();
- // grab the keyboard back, in case the app crashed/forgot
-
- QPEApplication *qpeapp = (QPEApplication *) qApp;
-
- if ( appLnk.exec() == qpeapp-> keyboardGrabbedBy ( )) {
- qDebug ( "grabbing keyboard back from %s", appLnk.name().latin1());
- qpeapp-> grabKeyboard ( );
- }
-
delete target;
}
}
update();
}
void RunningAppBar::mousePressEvent(QMouseEvent *e)
{
// Find out if the user is clicking on an app icon...
// If so, snag the index so when we repaint we show it
// as highlighed.
m_SelectedAppIndex = 0;
int x = 0;
QListIterator<AppLnk> it( m_AppList );
for ( ; it.current(); ++it, ++m_SelectedAppIndex, x += spacing ) {
if ( x + spacing <= width() ) {
if ( e->x() >= x && e->x() < x + spacing ) {
if ( m_SelectedAppIndex < (int)m_AppList.count() ) {
repaint(FALSE);
return ;
}
}
}
else {
break;
}
}
m_SelectedAppIndex = -1;
repaint( FALSE );
}
void RunningAppBar::mouseReleaseEvent(QMouseEvent *e)
{
if (e->button() == QMouseEvent::RightButton) {
return ;
}
if ( m_SelectedAppIndex >= 0 ) {
QString channel = QString("QPE/Application/") + m_AppList.at(m_SelectedAppIndex)->exec();
if (QCopChannel::isRegistered(channel.latin1())) {
// qDebug("%s is running!", m_AppList.at(m_SelectedAppIndex)->exec().latin1());
QCopEnvelope e(channel.latin1(), "raise()");
// This class will delete itself after hearing from the app or the timer expiring
(void)new AppMonitor(*m_AppList.at(m_SelectedAppIndex), *this);
}
else {
removeTask(*m_AppList.at(m_SelectedAppIndex));
}
m_SelectedAppIndex = -1;
update();
}
}
void RunningAppBar::paintEvent( QPaintEvent * )
{
QPainter p( this );
AppLnk *curApp;
int x = 0;
int y = (height() - AppLnk::smallIconSize()) / 2;
int i = 0;
//p.fillRect( 0, 0, width(), height(), colorGroup().background() );
QListIterator<AppLnk> it(m_AppList);
for (; it.current(); i++, ++it ) {
if ( x + spacing <= width() ) {
curApp = it.current();
if ( (int)i == m_SelectedAppIndex )
p.fillRect( x, y, spacing, curApp->pixmap().height() + 1, colorGroup().highlight() );
else
// p.eraseRect( x, y, spacing, curApp->pixmap().height()+1 );
p.drawPixmap( x, y, curApp->pixmap() );
x += spacing;
}
}
}
QSize RunningAppBar::sizeHint() const
{
return QSize( frameWidth(), AppLnk::smallIconSize() + frameWidth()*2 + 3 );
}
const int AppMonitor::RAISE_TIMEOUT_MS = 500;
AppMonitor::AppMonitor(const AppLnk& app, RunningAppBar& owner)
: QObject(0L), m_Owner(owner), m_App(app), m_AppKillerBox(0L)
{
QCopChannel* channel = new QCopChannel( "QPE/System", this );
connect( channel, SIGNAL(received(const QCString&, const QByteArray&)),
this, SLOT(received(const QCString&, const QByteArray&)) );
connect(&m_Timer, SIGNAL(timeout()), this, SLOT(timerExpired()));
m_Timer.start(RAISE_TIMEOUT_MS, TRUE);
}
AppMonitor::~AppMonitor()
{
if (m_AppKillerBox) {
delete m_AppKillerBox;
m_AppKillerBox = 0L;
}
}
void AppMonitor::received(const QCString& msg, const QByteArray& data)
{
QDataStream stream( data, IO_ReadOnly );
if (msg == "appRaised(QString)") {
QString appName;
stream >> appName;
if (appName == m_App.exec()) {
// qDebug("Got a heartbeat from %s", appName.latin1());
m_Timer.stop();
// Check to make sure we're not waiting on user input...
if (m_AppKillerBox) {
// If we are, we kill the dialog box, and the code waiting on the result
// will clean us up (basically the user said "no").
delete m_AppKillerBox;
m_AppKillerBox = 0L;
}
else {
// Ok, we're not waiting on user input, so clean us up now.
// WE DELETE OURSELVES HERE! Don't do anything else!!
delete this;
}
}
}
}
void AppMonitor::timerExpired()
{
// We store this incase the application responds while we're
// waiting for user input so we know not to delete ourselves. This
// will be cleaned up in the destructor.
m_AppKillerBox = new QMessageBox(tr("Application Problem"),
tr("<p>%1 is not responding.</p>").arg(m_App.name()) +
tr("<p>Would you like to force the application to exit?</p>"),
QMessageBox::Warning, QMessageBox::Yes,
QMessageBox::No | QMessageBox::Default,
QMessageBox::NoButton);
if ( m_AppKillerBox-> exec ( ) == QMessageBox::Yes ) {
QDir proc ( "/proc/", "[0-9]*", QDir::Name | QDir::Reversed, QDir::Dirs );
QStringList allprocs = proc. entryList ( );
pid_t mypid = ::getpid ( );
for ( QStringList::Iterator it = allprocs. begin ( ); it != allprocs. end ( ); ++it ) {
if (( *it ). toInt ( ) <= mypid ) // only interested in children
continue;
QCString s = QString ( "/proc/" + *it + "/stat" ). local8Bit ( );
FILE *fp = ::fopen ( s. data ( ), "r" );
if ( fp ) {
pid_t pid, ppid;
char *execptr, *exec = 0;
if ( ::fscanf ( fp, "%d %as %*c %d ", &pid, &execptr, &ppid ) == 3 ) {
exec = execptr [0] ? execptr + 1 : execptr;
if ( exec [0] )
exec [::strlen ( exec ) - 1] = 0;
if (( ppid == ::getpid ( )) && ( m_App. exec ( ). local8Bit ( ) == exec )) {
bool success = false;
qDebug ( "trying to kill pid=%d, exec=%s, ppid=%d", pid, exec, ppid );
success |= ( ::kill ( pid, SIGTERM ) == 0 );
::usleep ( 1000 * 500 );
success |= ( ::kill ( pid, SIGKILL ) == 0 );
if ( success )
m_Owner. removeTask ( m_App );
::free ( execptr );
break;
}
::free ( execptr );
}
::fclose ( fp );
}
}
}
delete this;
}
diff --git a/core/launcher/startmenu.cpp b/core/launcher/startmenu.cpp
index 88c6219..39e07c8 100644
--- a/core/launcher/startmenu.cpp
+++ b/core/launcher/startmenu.cpp
@@ -1,391 +1,392 @@
/**********************************************************************
** 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.
**
**********************************************************************/
#define INCLUDE_MENUITEM_DEF
#include "startmenu.h"
#include "sidething.h"
//#include "mrulist.h"
#include "info.h"
#include <qpe/qpeapplication.h>
#include <qpe/config.h>
#include <qpe/applnk.h>
#include <qpe/global.h>
#include <qpe/resource.h>
#include <qpe/qlibrary.h>
#include <qintdict.h>
#include <qdir.h>
#include <stdlib.h>
// #define USE_CONFIG_FILE
StartMenu::StartMenu(QWidget *parent) : QLabel( parent )
{
loadOptions();
int sz = AppLnk::smallIconSize()+3;
QPixmap pm;
pm.convertFromImage(Resource::loadImage(startButtonPixmap).smoothScale(sz,sz));
setPixmap(pm);
setFocusPolicy( NoFocus );
//setFlat( startButtonIsFlat );
apps = 0;
launchMenu = 0;
applets. setAutoDelete ( true );
sepId = 0;
reloadApps ( );
reloadApplets ( );
}
void StartMenu::mousePressEvent( QMouseEvent * )
{
launch();
if (desktopInfo)
desktopInfo->menuClicked();
}
StartMenu::~StartMenu()
{
delete apps;
}
void StartMenu::loadOptions()
{
#ifdef USE_CONFIG_FILE
// Read configuration file
Config config("StartMenu");
config.setGroup( "StartMenu" );
QString tmpBoolString1 = config.readEntry( "UseWidePopupMenu", "FALSE" );
useWidePopupMenu = ( tmpBoolString1 == "TRUE" ) ? TRUE : FALSE;
QString tmpBoolString2 = config.readEntry( "StartButtonIsFlat", "TRUE" );
startButtonIsFlat = ( tmpBoolString2 == "TRUE" ) ? TRUE : FALSE;
QString tmpBoolString3 = config.readEntry( "UseMRUList", "TRUE" );
popupMenuSidePixmap = config.readEntry( "PopupMenuSidePixmap", "launcher/sidebar" );
startButtonPixmap = config.readEntry( "StartButtonPixmap", "launcher/start_button" );
#else
// Basically just #include the .qpe_menu.conf file settings
useWidePopupMenu = FALSE;
popupMenuSidePixmap = "launcher/sidebar";
startButtonIsFlat = TRUE;
startButtonPixmap = "launcher/start_button"; // No tr
#endif
}
void StartMenu::createMenu()
{
delete launchMenu;
if ( useWidePopupMenu )
launchMenu = new PopupWithLaunchSideThing( this, &popupMenuSidePixmap );
else
launchMenu = new StartPopupMenu( this );
loadMenu ( apps, launchMenu );
loadApplets ( );
connect( launchMenu, SIGNAL(activated(int)), SLOT(itemSelected(int)) );
}
void StartMenu::reloadApps()
{
Config cfg("StartMenu");
cfg.setGroup("Menu");
bool ltabs = cfg.readBoolEntry("LauncherTabs",TRUE);
bool lot = cfg.readBoolEntry("LauncherOther",TRUE);
bool lt = ltabs || lot;
if ( launchMenu && apps && !lt )
return; // nothing to do
if ( lt ) {
delete apps;
apps = new AppLnkSet( QPEApplication::qpeDir() + "apps" );
}
if ( launchMenu ) {
launchMenu-> hide ( );
for ( QIntDictIterator<QPopupMenu> it ( tabdict ); it. current ( ); ++it ) {
launchMenu-> removeItem ( it. currentKey ( ));
delete it.current ( );
}
tabdict. clear ( );
loadMenu(apps,launchMenu);
} else {
createMenu();
}
}
void StartMenu::reloadApplets()
{
if ( launchMenu ) {
clearApplets ( );
loadApplets ( );
}
else
createMenu ( );
}
void StartMenu::itemSelected( int id )
{
const AppLnk *app = apps->find( id );
if ( app )
app->execute();
else {
MenuApplet *applet = applets. find ( id );
if ( applet )
applet-> iface-> activated ( );
}
}
bool StartMenu::loadMenu( AppLnkSet *folder, QPopupMenu *menu )
{
bool result = FALSE;
Config cfg("StartMenu");
cfg.setGroup("Menu");
bool ltabs = cfg.readBoolEntry("LauncherTabs",TRUE);
bool lot = cfg.readBoolEntry("LauncherOther",TRUE);
tabdict. clear ( );
if ( sepId )
menu-> removeItem ( sepId );
sepId = ( menu-> count ( )) ? menu-> insertSeparator ( 0 ) : 0;
if ( ltabs || lot ) {
QDict<QPopupMenu> typpop;
QStringList typs = folder->types();
for (QStringList::Iterator tit=typs.fromLast(); ; --tit) {
if ( !(*tit).isEmpty() ) {
QPopupMenu *new_menu;
if ( ltabs ) {
new_menu = new StartPopupMenu( menu );
connect( new_menu, SIGNAL(activated(int)), SLOT(itemSelected(int)) );
int id = menu->insertItem( folder->typePixmap(*tit), folder->typeName(*tit), new_menu, -1, 0 );
tabdict. insert ( id, new_menu );
} else {
new_menu = (QPopupMenu*)1;
}
typpop.insert(*tit, new_menu);
}
if ( tit == typs. begin ( ))
break;
}
QListIterator<AppLnk> it( folder->children() );
bool f=TRUE;
for ( ; it.current(); ++it ) {
AppLnk *app = it.current();
if ( app->type() == "Separator" ) { // No tr
if ( lot ) {
menu->insertSeparator();
}
} else {
f = FALSE;
QString t = app->type();
QPopupMenu* pmenu = typpop.find(t);
if ( ltabs ) {
if ( !pmenu && lot )
pmenu = menu;
} else {
if ( !pmenu )
pmenu = menu;
else
pmenu = 0;
}
if ( pmenu ) {
QString t = app->name();
t.replace(QRegExp("&"),"&&"); // escape shortcut character
pmenu->insertItem( app->pixmap(), t, app->id() );
}
result=TRUE;
}
}
}
if ( sepId && ( menu-> idAt ( 0 ) == sepId )) { // no tabs entries
menu-> removeItem ( sepId );
sepId = 0;
}
if ( !menu-> count ( )) // if we don't do this QPopupMenu will insert a dummy Separator, which won't go away later
sepId = menu-> insertSeparator ( );
return result;
}
void StartMenu::launch()
{
int y = mapToGlobal( QPoint() ).y() - launchMenu->sizeHint().height();
- if ( launchMenu->isVisible() )
+ if ( launchMenu-> isVisible ( )) {
launchMenu->hide();
+ }
else {
QWidget *active = qApp->activeWindow();
if ( active && active->isPopup() )
active->close();
launchMenu->popup( QPoint( 1, y ) );
}
}
const AppLnk* StartMenu::execToLink(const QString& appname)
{
const AppLnk* a = apps->findExec( appname );
return a;
}
void StartPopupMenu::keyPressEvent( QKeyEvent *e )
{
if ( e->key() == Key_F33 || e->key() == Key_Space ) {
// "OK" button, little hacky
QKeyEvent ke(QEvent::KeyPress, Key_Enter, 13, 0);
QPopupMenu::keyPressEvent( &ke );
} else {
QPopupMenu::keyPressEvent( e );
}
}
static int compareAppletPositions(const void *a, const void *b)
{
const MenuApplet* aa = *(const MenuApplet**)a;
const MenuApplet* ab = *(const MenuApplet**)b;
int d = aa->iface->position() - ab->iface->position();
if ( d ) return d;
return QString::compare(aa->library->library(),ab->library->library());
}
void StartMenu::clearApplets()
{
launchMenu-> hide();
for ( QIntDictIterator<MenuApplet> it ( applets ); it. current ( ); ++it ) {
MenuApplet *applet = it. current ( );
if ( launchMenu ) {
launchMenu-> removeItem ( applet-> id );
delete applet-> popup;
}
applet-> iface-> release();
applet-> library-> unload();
delete applet-> library;
}
applets.clear();
}
void StartMenu::loadApplets()
{
Config cfg( "StartMenu" );
cfg.setGroup( "Applets" );
// SafeMode causes too much problems, so we disable it for now --
// maybe we should reenable it for OPIE 1.0 - sandman 26.09.02
bool safe = false; //cfg.readBoolEntry("SafeMode",FALSE);
if ( safe && !safety_tid )
return;
cfg.writeEntry("SafeMode",TRUE);
cfg.write();
QStringList exclude = cfg.readListEntry( "ExcludeApplets", ',' );
QString lang = getenv( "LANG" );
QString path = QPEApplication::qpeDir() + "/plugins/applets";
QDir dir( path, "lib*.so" );
QStringList list = dir.entryList();
QStringList::Iterator it;
int napplets=0;
MenuApplet* *xapplets = new MenuApplet*[list.count()];
for ( it = list.begin(); it != list.end(); ++it ) {
if ( exclude.find( *it ) != exclude.end() )
continue;
MenuAppletInterface *iface = 0;
QLibrary *lib = new QLibrary( path + "/" + *it );
if (( lib->queryInterface( IID_MenuApplet, (QUnknownInterface**)&iface ) == QS_OK ) && iface ) {
MenuApplet *applet = new MenuApplet;
xapplets[napplets++] = applet;
applet->library = lib;
applet->iface = iface;
QTranslator *trans = new QTranslator(qApp);
QString type = (*it).left( (*it).find(".") );
QString tfn = QPEApplication::qpeDir()+"/i18n/"+lang+"/"+type+".qm";
if ( trans->load( tfn ))
qApp->installTranslator( trans );
else
delete trans;
} else {
exclude += *it;
delete lib;
}
}
cfg.writeEntry( "ExcludeApplets", exclude, ',' );
qsort(xapplets,napplets,sizeof(applets[0]),compareAppletPositions);
if ( sepId )
launchMenu-> removeItem ( sepId );
sepId = ( launchMenu-> count ( )) ? launchMenu-> insertSeparator ( ) : 0;
while (napplets--) {
MenuApplet *applet = xapplets[napplets];
applet-> popup = applet-> iface-> popup ( this );
if ( applet-> popup )
applet-> id = launchMenu-> insertItem ( applet-> iface-> icon ( ), applet-> iface-> text ( ), applet-> popup );
else
applet-> id = launchMenu-> insertItem ( applet-> iface-> icon ( ), applet-> iface-> text ( ) );
applets.insert ( applet-> id, new MenuApplet(*applet));
}
delete [] xapplets;
if ( sepId && ( launchMenu-> idAt ( launchMenu-> count ( ) - 1 ) == sepId )) { // no applets
launchMenu-> removeItem ( sepId );
sepId = 0;
}
if ( !launchMenu-> count ( )) // if we don't do this QPopupMenu will insert a dummy Separator, which won't go away later
sepId = launchMenu-> insertSeparator ( );
if ( !safety_tid )
safety_tid = startTimer(2000); // TT has 5000, but this is a PITA for a developer ;) (sandman)
}
void StartMenu::timerEvent(QTimerEvent* e)
{
if ( e->timerId() == safety_tid ) {
Config cfg( "StartMenu" );
cfg.setGroup( "Applets" );
cfg.writeEntry( "SafeMode", FALSE );
killTimer(safety_tid);
safety_tid = 0;
}
}
diff --git a/core/launcher/taskbar.cpp b/core/launcher/taskbar.cpp
index b4b7df6..77035a3 100644
--- a/core/launcher/taskbar.cpp
+++ b/core/launcher/taskbar.cpp
@@ -1,334 +1,344 @@
/**********************************************************************
** Copyright (C) 2000 Trolltech AS. All rights reserved.
**
** This file is part of Qtopia Environment.
**
** This file may be distributed and/or modified under the terms of the
** GNU General Public License version 2 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
** See http://www.trolltech.com/gpl/ for GPL licensing information.
**
** Contact info@trolltech.com if any conditions of this licensing are
** not clear to you.
**
*********************************************************************/
#include "startmenu.h"
#include "inputmethods.h"
#include "runningappbar.h"
#include "systray.h"
#include "calibrate.h"
#include "wait.h"
#include "appicons.h"
#include "taskbar.h"
#include "desktop.h"
#include <qpe/qpeapplication.h>
#include <qpe/qcopenvelope_qws.h>
#include <qpe/global.h>
#if defined( QT_QWS_SHARP ) || defined( QT_QWS_IPAQ )
#include <qpe/custom.h>
#endif
#include <opie/odevice.h>
#include <qlabel.h>
#include <qlayout.h>
#include <qtimer.h>
#include <qwindowsystem_qws.h>
#include <qwidgetstack.h>
#if defined( Q_WS_QWS )
#include <qwsdisplay_qws.h>
#include <qgfx_qws.h>
#endif
using namespace Opie;
#define FACTORY(T) \
static QWidget *new##T( bool maximized ) { \
QWidget *w = new T( 0, "test", QWidget::WDestructiveClose | QWidget::WGroupLeader ); \
if ( maximized ) { \
if ( qApp->desktop()->width() <= 350 ) { \
w->showMaximized(); \
} else { \
w->resize( QSize( 300, 300 ) ); \
} \
} \
w->show(); \
return w; \
}
#ifdef SINGLE_APP
#define APP(a,b,c,d) FACTORY(b)
#include "../launcher/apps.h"
#undef APP
#endif // SINGLE_APP
static Global::Command builtins[] = {
#ifdef SINGLE_APP
#define APP(a,b,c,d) { a, new##b, c },
#include "../launcher/apps.h"
#undef APP
#endif
#if defined(QT_QWS_IPAQ) || defined(QT_QWS_CASSIOPEIA) || defined(QT_QWS_SHARP)
{ "calibrate", TaskBar::calibrate, 1, 0 },
#endif
#if !defined(QT_QWS_CASSIOPEIA)
{ "shutdown", Global::shutdown, 1, 0 },
// { "run", run, 1, 0 },
#endif
{ 0, TaskBar::calibrate, 0, 0 },
};
static bool initNumLock()
{
#ifdef QPE_INITIAL_NUMLOCK_STATE
QPE_INITIAL_NUMLOCK_STATE
#endif
return FALSE;
}
class LockKeyState : public QWidget
{
public:
LockKeyState( QWidget *parent ) :
QWidget(parent),
nl(initNumLock()), cl(FALSE)
{
nl_pm = Resource::loadPixmap("numlock");
cl_pm = Resource::loadPixmap("capslock");
}
QSize sizeHint() const
{
return QSize(nl_pm.width()+2,nl_pm.width()+nl_pm.height()+1);
}
void toggleNumLockState()
{
nl = !nl; repaint();
}
void toggleCapsLockState()
{
cl = !cl; repaint();
}
void paintEvent( QPaintEvent * )
{
int y = (height()-sizeHint().height())/2;
QPainter p(this);
if ( nl )
p.drawPixmap(1,y,nl_pm);
if ( cl )
p.drawPixmap(1,y+nl_pm.height()+1,cl_pm);
}
private:
QPixmap nl_pm, cl_pm;
bool nl, cl;
};
TaskBar::~TaskBar()
{
}
TaskBar::TaskBar() : QHBox(0, 0, WStyle_Customize | WStyle_Tool | WStyle_StaysOnTop | WGroupLeader)
{
Global::setBuiltinCommands(builtins);
sm = new StartMenu( this );
inputMethods = new InputMethods( this );
connect( inputMethods, SIGNAL(inputToggled(bool)),
this, SLOT(calcMaxWindowRect()) );
//new QuickLauncher( this );
stack = new QWidgetStack( this );
stack->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Minimum ) );
label = new QLabel(stack);
//mru = new MRUList( stack );
//stack->raiseWidget( mru );
runningAppBar = new RunningAppBar(stack);
stack->raiseWidget(runningAppBar);
waitIcon = new Wait( this );
(void) new AppIcons( this );
sysTray = new SysTray( this );
// ## make customizable in some way?
lockState = new LockKeyState( this );
#if defined(Q_WS_QWS)
#if !defined(QT_NO_COP)
QCopChannel *channel = new QCopChannel( "QPE/TaskBar", this );
connect( channel, SIGNAL(received(const QCString&, const QByteArray&)),
this, SLOT(receive(const QCString&, const QByteArray&)) );
#endif
#endif
waitTimer = new QTimer( this );
connect( waitTimer, SIGNAL( timeout() ), this, SLOT( stopWait() ) );
clearer = new QTimer( this );
QObject::connect(clearer, SIGNAL(timeout()), SLOT(clearStatusBar()));
QObject::connect(clearer, SIGNAL(timeout()), sysTray, SLOT(show()));
}
void TaskBar::setStatusMessage( const QString &text )
{
if ( !text.isEmpty() ) {
label->setText( text );
stack->raiseWidget( label );
if ( sysTray && ( label->fontMetrics().width( text ) > label->width() ) )
sysTray->hide();
clearer->start( 3000, TRUE );
} else {
clearStatusBar();
}
}
void TaskBar::clearStatusBar()
{
label->clear();
stack->raiseWidget(runningAppBar);
// stack->raiseWidget( mru );
}
void TaskBar::startWait()
{
waitIcon->setWaiting( true );
// a catchall stop after 10 seconds...
waitTimer->start( 10 * 1000, true );
}
void TaskBar::stopWait(const QString& /*app*/)
{
waitTimer->stop();
//mru->addTask(sm->execToLink(app));
waitIcon->setWaiting( false );
}
void TaskBar::stopWait()
{
waitTimer->stop();
waitIcon->setWaiting( false );
}
void TaskBar::resizeEvent( QResizeEvent *e )
{
QHBox::resizeEvent( e );
calcMaxWindowRect();
}
void TaskBar::styleChange( QStyle &s )
{
QHBox::styleChange( s );
calcMaxWindowRect();
}
void TaskBar::calcMaxWindowRect()
{
#ifdef Q_WS_QWS
QRect wr;
int displayWidth = qApp->desktop()->width();
QRect ir = inputMethods->inputRect();
if ( ir.isValid() ) {
wr.setCoords( 0, 0, displayWidth-1, ir.top()-1 );
} else {
wr.setCoords( 0, 0, displayWidth-1, y()-1 );
}
#if QT_VERSION < 300
QWSServer::setMaxWindowRect( qt_screen->mapToDevice(wr,
QSize(qt_screen->width(),qt_screen->height()))
);
#else
QWSServer::setMaxWindowRect( wr );
#endif
#endif
}
void TaskBar::receive( const QCString &msg, const QByteArray &data )
{
QDataStream stream( data, IO_ReadOnly );
if ( msg == "message(QString)" ) {
QString text;
stream >> text;
setStatusMessage( text );
} else if ( msg == "hideInputMethod()" ) {
inputMethods->hideInputMethod();
} else if ( msg == "showInputMethod()" ) {
inputMethods->showInputMethod();
} else if ( msg == "reloadInputMethods()" ) {
inputMethods->loadInputMethods();
} else if ( msg == "reloadApps()" ) {
sm->reloadApps();
} else if ( msg == "reloadApplets()" ) {
sysTray->clearApplets();
sysTray->addApplets();
sm->reloadApplets();
} else if ( msg == "soundAlarm()" ) {
- Desktop::soundAlarm();
+ DesktopApplication::soundAlarm ( );
}
else if ( msg == "setLed(int,bool)" ) {
int led, status;
stream >> led >> status;
QValueList <OLed> ll = ODevice::inst ( )-> ledList ( );
if ( ll. count ( )) {
OLed l = ll. contains ( Led_Mail ) ? Led_Mail : ll [0];
bool canblink = ODevice::inst ( )-> ledStateList ( l ). contains ( Led_BlinkSlow );
ODevice::inst ( )-> setLedState ( l, status ? ( canblink ? Led_BlinkSlow : Led_On ) : Led_Off );
}
}
+ else if ( msg == "toggleMenu()" ) {
+ if ( sm-> launchMenu-> isVisible ( ))
+ sm-> launch ( );
+ else {
+ QCopEnvelope e ( "QPE/System", "toggleApplicationMenu()" );
+ }
+ }
+ else if ( msg == "toggleStartMenu()" ) {
+ sm-> launch ( );
+ }
}
QWidget *TaskBar::calibrate(bool)
{
#ifdef Q_WS_QWS
Calibrate *c = new Calibrate;
c->show();
return c;
#else
return 0;
#endif
}
void TaskBar::toggleNumLockState()
{
if ( lockState ) lockState->toggleNumLockState();
}
void TaskBar::toggleCapsLockState()
{
if ( lockState ) lockState->toggleCapsLockState();
}
void TaskBar::toggleSymbolInput()
{
if ( inputMethods->currentShown() == "Unicode" ) {
inputMethods->hideInputMethod();
} else {
inputMethods->showInputMethod("Unicode");
}
}
bool TaskBar::recoverMemory()
{
//eturn mru->quitOldApps();
return true;
}