/*************************************************************************** * Copyright (C) 2006 by Michael Kaufmann * * michael@enlighter.de * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include "traywindow.h" #include "openvpnmanager.h" #include "infopopup.h" #include "aboutdata.h" #include #include #include #include #include #include #include #include #include using namespace std; TrayWindow * TrayWindow::trayWindowInstance = 0L; TrayWindow * TrayWindow::systemTray( QWidget *parent, const char *name ) { if ( ! trayWindowInstance ) { trayWindowInstance = new TrayWindow( parent, name ); } trayWindowInstance->setPixmap( trayWindowInstance->loadIcon( "kovpn_disconnected" ) ); return trayWindowInstance; } TrayWindow::TrayWindow( QWidget *parent = 0, const char *name = 0 ) : KSystemTray( parent, name ) { trayIcons = new KIconLoader( "kovpn" ); aboutWindow = new KAboutApplication( new aboutData() ); // aboutDialog->setAuthor( "Michael Kaufmann", "michael@enlighter.de", "http://www.enlighter.de" ); setInactive(); mParent = parent; mAdvanced = false; /* Get context menu */ mContextMenu = contextMenu(); mDisconnectMenu = new KPopupMenu( mContextMenu ); mConnectMenu = new KPopupMenu( mContextMenu ); /* Init Info Popup Window */ passivePopup = new KPassivePopup(); QObject::connect( this, SIGNAL ( quitSelected() ), parent, SLOT ( slotQuitKovpn() ) ); /* Fill context menu */ mPreferencesMenuItem = KStdAction::preferences( parent, SLOT( slotPreferences() ), actionCollection() ); mPreferencesMenuItem->plug( mContextMenu, 1 ); mStatusMenuItem = new KAction( i18n( "&State" ), "slotState", 0, parent, SLOT( show() ), actionCollection(), "state" ); mStatusMenuItem->setIcon( "klinkstatus" ); mStatusMenuItem->plug( mContextMenu, 1 ); mLogWidgetMenuItem = new KAction( i18n( "&Messages" ), "slotMessages", 0, parent, SLOT( slotShowLogWidget() ), actionCollection(), "message" ); mLogWidgetMenuItem->setIcon( "message" ); mLogWidgetMenuItem->plug( mContextMenu, 1 ); mAboutWindowMenuItem = new KAction( i18n( "&About Kovpn" ), "slotAbout", 0, aboutWindow, SLOT( show() ), actionCollection(), "about" ); mAboutWindowMenuItem->setIcon( "about" ); mAboutWindowMenuItem->plug( mContextMenu, 1 ); mContextMenu->insertSeparator( 4 ); installEventFilter( this ); } TrayWindow::~TrayWindow() {} void TrayWindow::slotStatusChanged( openVPNManager * manager ) { switch ( manager->status().state ) { case openVPNManager::CONNECTED: trayWindowInstance->setPixmap( trayIcons->loadIcon( "kovpn_connected", KIcon::Small ) ); break; case openVPNManager::DISCONNECTED: trayWindowInstance->setPixmap( trayIcons->loadIcon( "kovpn_disconnected", KIcon::Small ) ); break; default: trayWindowInstance->setPixmap( trayIcons->loadIcon( "kovpn_connecting", KIcon::Small ) ); break; } } void TrayWindow::dereg( openVPNManager * manager ) { mConnectMenuItems[ manager->id() ] ->unplugAll(); delete mConnectMenuItems[ manager->id() ]; mDisconnectMenuItems[ manager->id() ] ->unplugAll(); delete mDisconnectMenuItems[ manager->id() ]; /* I think (int) manager is unique and static enough to be used as id for the menu */ mContextMenu->removeItem( ( size_t ) manager ); mManagerMenus.remove( manager->id() ); mOvpnManagers.remove( manager ); } void TrayWindow::reg( openVPNManager * manager ) { debug( "reg", QString( "Registering %1" ).arg( manager->id() ) ); QObject::connect( manager, SIGNAL ( signalOvpnStatusChanged( const QString &, openVPNManager::tStatus ) ), this, SLOT ( stateChanged( const QString &, openVPNManager::tStatus ) ) ); QObject::connect( manager, SIGNAL ( signalOvpnReady( const QString & ) ), this, SLOT ( ovpnReady( const QString & ) ) ); QObject::connect( manager, SIGNAL ( signalOvpnNotReady( const QString & ) ), this, SLOT ( ovpnNotReady( const QString & ) ) ); QObject::connect( manager, SIGNAL ( signalOvpnPreReady( const QString & ) ), this, SLOT ( ovpnPreReady( const QString & ) ) ); mOvpnManagers.append( manager ); mManagerMenus[ manager->id() ] = new KPopupMenu( mContextMenu ); /* I think (int) manager is unique and static enough to be used as id for the menu */ mContextMenu->insertItem( manager->id() , mManagerMenus[ manager->id() ] , ( size_t ) manager, 5 ); mManagerMenus[ manager->id() ] ->insertTitle( i18n( "Status: Unavailable" ), 0 ); mDisconnectMenuItems[ manager->id() ] = new KAction( i18n( "&Disconnect" ), "disconnect", 0, manager, SLOT( disconnect() ), actionCollection(), "disconnect" ); mDisconnectMenuItems[ manager->id() ] ->plug( mManagerMenus[ manager->id() ], 1 ); mDisconnectMenuItems[ manager->id() ] ->setIcon( "kovpn_disconnected" ); mDisconnectMenuItems[ manager->id() ] ->setEnabled( false ); mConnectMenuItems[ manager->id() ] = new KAction( i18n( "&Connect" ), "connect", 0, manager, SLOT( connect() ), actionCollection(), "connect" ); mConnectMenuItems[ manager->id() ] ->plug( mManagerMenus[ manager->id() ], 1 ); mConnectMenuItems[ manager->id() ] ->setIcon( "kovpn_connected" ); mConnectMenuItems[ manager->id() ] ->setEnabled( false ); /* Set initial state */ } void TrayWindow::setInfoPopup( const QString & id, openVPNManager::tStatus status ) { KPassivePopup * passivePopup = new KPassivePopup( this ); QVBox * vb; passivePopup->setAutoDelete( true ); // QHBox *hb = new QHBox( vb ); // QVBox *vb2 = new QVBox( hb ); // QLabel *lStatusLabel = new QLabel( "Status:", hb ); // QLabel *lStatus = new QLabel( "connected", hb ); // lStatus->setIndent( icon.width() + ( 2 * KDialog::spacingHint() ) ); // lStatusLabel->setIndent( icon.width() + 10 ); /* 10 taken from source of kdelibs */ /* infoPopup * myPopup = new infoPopup( vb ); myPopup->setLeftSpacing( icon.width() + KDialog::marginHint() - 2 ); pop->setView( vb ); pop->show();*/ static QMap mStateReported; /* The last reported state "group". used in slotOvpnStatusChanged */ switch ( status.state ) { case openVPNManager::CONNECTED: if ( mStateReported[ id ] != openVPNManager::CONNECTED ) { /* This is for "experts" */ vb = passivePopup->standardView( i18n( "OpenVPN Info for %1" ).arg( id ), QString::null, trayIcons->loadIcon( "messagebox_info", KIcon::Desktop ) ); infoPopup * MyInfoPopup = new infoPopup( vb ); if ( mAdvanced ) { MyInfoPopup->addLine( i18n( "Status" ), i18n( "Connected" ) ); MyInfoPopup->addLine( i18n( "local IP" ), QString( "%1" ).arg( status.localIP ) ); } else { MyInfoPopup->addLine( i18n( "Connection has been established" ) ); } passivePopup->setView( vb ); passivePopup->show(); // infoPopup::message( i18n( "OpenVPN Status for %1" ).arg( id ), i18n( "Connected" ), status.localIP, pop ); /* This is for DAUs */ /* passivePopup->message( KPassivePopup::Boxed, \ i18n( "OpenVPN Status" ), \ i18n( "Connection to %1 has been established" ).arg( id ), \ trayIcons->loadIcon( "messagebox_info", KIcon::Desktop ), \ this );*/ } mStateReported[ id ] = openVPNManager::CONNECTED; break; case openVPNManager::EXITING: if ( mStateReported[ id ] != openVPNManager::EXITING ) { vb = passivePopup->standardView( i18n( "OpenVPN Info for %1" ).arg( id ), QString::null, trayIcons->loadIcon( "messagebox_info", KIcon::Desktop ) ); infoPopup * MyInfoPopup = new infoPopup( vb ); if ( mAdvanced ) { MyInfoPopup->addLine( i18n( "Status" ), i18n( "Exited" ) ); } else { MyInfoPopup->addLine( i18n( "OpenVPN daemon exited" ) ); } passivePopup->setView( vb ); passivePopup->show(); // passivePopup->message( /* KPassivePopup::Boxed, */ \ // i18n( "OpenVPN Status for %1" ).arg( id ), \ // i18n( "OpenVPN daemon exited" ), \ // trayIcons->loadIcon( "messagebox_info", KIcon::Desktop ), \ // this ); } mStateReported[ id ] = openVPNManager::EXITING; break; case openVPNManager::CONNECTING: case openVPNManager::WAIT: case openVPNManager::AUTH: case openVPNManager::GET_CONFIG: case openVPNManager::ASSIGN_IP: case openVPNManager::ADD_ROUTES: case openVPNManager::RECONNECTING: case openVPNManager::DISCONNECTED: if ( mStateReported[ id ] != openVPNManager::DISCONNECTED ) { vb = passivePopup->standardView( i18n( "OpenVPN Info for %1" ).arg( id ), QString::null, trayIcons->loadIcon( "messagebox_info", KIcon::Desktop ) ); infoPopup * MyInfoPopup = new infoPopup( vb ); if ( mAdvanced ) { MyInfoPopup->addLine( i18n( "Status" ), i18n( "Disconnected" ) ); } else { MyInfoPopup->addLine( i18n( "Connection has been closed" ) ); } passivePopup->setView( vb ); passivePopup->show(); // infoPopup::message( i18n( "OpenVPN Status for %1" ).arg( id ), i18n( "Disconnected" ), QString::null, pop ); // passivePopup->message( /*KPassivePopup::Boxed, */\ // i18n( "OpenVPN Status for %1" ).arg( id ), \ // i18n( "Connection has been closed" ), \ // trayIcons->loadIcon( "messagebox_info", KIcon::Desktop ), \ // this ); } mStateReported[ id ] = openVPNManager::DISCONNECTED; break; case openVPNManager::FAILED: if ( mStateReported[ id ] != openVPNManager::FAILED ) { vb = passivePopup->standardView( i18n( "OpenVPN Info for %1" ).arg( id ), QString::null, trayIcons->loadIcon( "messagebox_info", KIcon::Desktop ) ); infoPopup * MyInfoPopup = new infoPopup( vb ); if ( mAdvanced ) { MyInfoPopup->addLine( i18n( "Status" ), i18n( "Failed" ) ); } else { MyInfoPopup->addLine( i18n( "Could not connect. Retrying..." ) ); } passivePopup->setView( vb ); passivePopup->show(); // passivePopup->message( /*KPassivePopup::Boxed, */ \ // i18n( "OpenVPN Status for %1" ).arg( id ), \ // i18n( "Could not connect. Retrying..." ), \ // trayIcons->loadIcon( "messagebox_info", KIcon::Desktop ), \ // this ); } mStateReported[ id ] = openVPNManager::FAILED; break; default: break; } } void TrayWindow::setState( TrayWindow::states state ) { switch ( state ) { case DISCONNECTED: trayWindowInstance->setPixmap( trayIcons->loadIcon( "kovpn_disconnected", KIcon::Small ) ); break; case HALF_CONNECTED: trayWindowInstance->setPixmap( trayIcons->loadIcon( "kovpn_halfconnected", KIcon::Small ) ); break; case CONNECTED: trayWindowInstance->setPixmap( trayIcons->loadIcon( "kovpn_connected", KIcon::Small ) ); break; case CONNECTING: trayWindowInstance->setPixmap( trayIcons->loadIcon( "kovpn_connecting", KIcon::Small ) ); break; case DISCONNECTED__CONNECTING: trayWindowInstance->setPixmap( trayIcons->loadIcon( "kovpn_connecting", KIcon::Small ) ); break; case HALF_CONNECTED__CONNECTING: trayWindowInstance->setPixmap( trayIcons->loadIcon( "kovpn_connecting", KIcon::Small ) ); break; case CONNECTED__CONNECTING: trayWindowInstance->setPixmap( trayIcons->loadIcon( "kovpn_connecting", KIcon::Small ) ); break; } } void TrayWindow::stateChanged( const QString & id, openVPNManager::tStatus status ) { /* Only consider managers that are ready (= they have reported a status yet). * If they become "unready" they are deleted from this map in the function "ovpnNotReady" */ mOvpnStates[ id ] = status.state; // setToolTip(); setStateMenu( id, status.state ); setEnableMenu( id, status.state ); if ( ! kovpnConfig::self() ->quietMode() ) { /* No Popup if in quiet mode. */ setInfoPopup( id, status ); } ( void ) calcState(); /* update the Icon */ setState( mState ); } void TrayWindow::ovpnPreReady( const QString & id ) { mManagerMenus[ id ] ->changeTitle( 0, i18n( "No control access" ) ); mConnectMenuItems[ id ] ->setEnabled( true ); mDisconnectMenuItems[ id ] ->setEnabled( true ); } void TrayWindow::ovpnReady( const QString & id ) { mConnectMenuItems[ id ] ->setEnabled( true ); mDisconnectMenuItems[ id ] ->setEnabled( true ); } void TrayWindow::ovpnNotReady( const QString & id ) { mConnectMenuItems[ id ] ->setEnabled( false ); mDisconnectMenuItems[ id ] ->setEnabled( false ); /* Remove this id from the list of states, because I only count the openvpn states which are available, * meaning I only count, if openvpn is running for this id. */ mOvpnStates.remove( id ); /* Recalc states, because I changed the state map mOvpnStates */ ( void ) calcState(); /* update the Icon */ setState( mState ); } void TrayWindow::setToolTip( ) { QString mToolTip; int uptime; QTime time; openVPNManager * manager; for ( unsigned int i = 0; i < mOvpnManagers.count(); i++ ) { /* The sollution in the QT Docs doesn't work here. Gives me always the same element. */ manager = mOvpnManagers.at( i ); switch ( manager->status().state ) { case openVPNManager::DISCONNECTED: if ( mAdvanced ) { mToolTip += QString( "%1
  • %2: %3
" ).arg( manager->id() ).arg( i18n( "Status" ) ).arg( i18n( "Disconnected" ) ); } else { mToolTip += QString( "%1 %2: %3" ).arg( manager->id() ).arg( i18n( "Status" ) ).arg( i18n( "Disconnected" ) ); } break; case openVPNManager::CONNECTING: if ( mAdvanced ) { mToolTip += QString( "%1
  • %2: %3
" ).arg( manager->id() ).arg( i18n( "Status" ) ).arg( i18n( "Connecting" ) ); } else { mToolTip += QString( "%1 %2: %3" ).arg( manager->id() ).arg( i18n( "Status" ) ).arg( i18n( "Connecting" ) ); } break; case openVPNManager::WAIT: if ( mAdvanced ) { mToolTip += QString( "%1
  • %2: %3
" ).arg( manager->id() ).arg( i18n( "Status" ) ).arg( i18n( "Waiting" ) ); } else { mToolTip += QString( "%1 %2: %3" ).arg( manager->id() ).arg( i18n( "Status" ) ).arg( i18n( "Waiting" ) ); } break; case openVPNManager::AUTH: if ( mAdvanced ) { mToolTip += QString( "%1
  • %2: %3
" ).arg( manager->id() ).arg( i18n( "Status" ) ).arg( i18n( "Authentication" ) ); } else { mToolTip += QString( "%1 %2: %3" ).arg( manager->id() ).arg( i18n( "Status" ) ).arg( i18n( "Authentication" ) ); } break; case openVPNManager::GET_CONFIG: if ( mAdvanced ) { mToolTip += QString( "%1
  • %2: %3
" ).arg( manager->id() ).arg( i18n( "Status" ) ).arg( i18n( "Getting remote config" ) ); } else { mToolTip += QString( "%1 %2: %3" ).arg( manager->id() ).arg( i18n( "Status" ) ).arg( i18n( "Getting remote config" ) ); } break; case openVPNManager::ASSIGN_IP: if ( mAdvanced ) { mToolTip += QString( "%1
  • %2: %3
" ).arg( manager->id() ).arg( i18n( "Status" ) ).arg( i18n( "Assigning IP address" ) ); } else { mToolTip += QString( "%1 %2: %3" ).arg( manager->id() ).arg( i18n( "Status" ) ).arg( i18n( "Assigning IP address" ) ); } break; case openVPNManager::ADD_ROUTES: if ( mAdvanced ) { mToolTip += QString( "%1
  • %2: %3
" ).arg( manager->id() ).arg( i18n( "Status" ) ).arg( i18n( "Adding routes" ) ); } else { mToolTip += QString( "%1 %2: %3" ).arg( manager->id() ).arg( i18n( "Status" ) ).arg( i18n( "Adding routes" ) ); } break; case openVPNManager::CONNECTED: if ( mAdvanced ) { /* This is for DAUs */ // mToolTip += i18n( "%1 is connected" ).arg( manager->id() ); /* This is for "experts" */ uptime = manager->uptime(); time.setHMS( ( ( uptime / 3600 ) % 60 ), ( ( uptime / 60 ) % 60 ), ( uptime % 60 ) ); mToolTip += QString( "%1
  • %2: %3
  • %4: %5
  • %6: %7
" ).arg( manager->id() ).arg( i18n( "Status" ) ).arg( i18n( "Connected" ) ).arg( i18n( "local IP" ) ).arg( manager->ip() ).arg( i18n( "Uptime" ) ).arg( KGlobal::locale() ->formatTime( time, true, true ) ); } else { mToolTip += QString( "%1 %2: %3" ).arg( manager->id() ).arg( i18n( "Status" ) ).arg( i18n( "Connected" ) ); } break; case openVPNManager::RECONNECTING: if ( mAdvanced ) { mToolTip += QString( "%1
  • %2: %3
" ).arg( manager->id() ).arg( i18n( "Status" ) ).arg( i18n( "Reconnecting" ) ); } else { mToolTip += QString( "%1 %2: %3" ).arg( manager->id() ).arg( i18n( "Status" ) ).arg( i18n( "Reconnecting" ) ); } break; case openVPNManager::EXITING: if ( mAdvanced ) { mToolTip += QString( "%1
  • %2: %3
" ).arg( manager->id() ).arg( i18n( "Status" ) ).arg( i18n( "Exiting" ) ); } else { mToolTip += QString( "%1 %2: %3" ).arg( manager->id() ).arg( i18n( "Status" ) ).arg( i18n( "Exiting" ) ); } break; case openVPNManager::UNKNOWN: default: if ( mAdvanced ) { mToolTip += QString( "%1
  • %2: %3
" ).arg( manager->id() ).arg( i18n( "Status" ) ).arg( i18n( "Unavailable" ) ); } else { mToolTip += QString( "%1 %2: %3" ).arg( manager->id() ).arg( i18n( "Status" ) ).arg( i18n( "Unavailable" ) ); } break; } if ( manager != mOvpnManagers.last() && ! mAdvanced ) { mToolTip += "
"; } } QToolTip::remove( this ); QToolTip::add( this, mToolTip ); } void TrayWindow::setEnableMenu( const QString & id, openVPNManager::states status ) { switch ( status ) { case openVPNManager::DISCONNECTED: case openVPNManager::CONNECTING: case openVPNManager::WAIT: case openVPNManager::AUTH: case openVPNManager::GET_CONFIG: case openVPNManager::ASSIGN_IP: case openVPNManager::ADD_ROUTES: case openVPNManager::RECONNECTING: mConnectMenuItems[ id ] ->setEnabled( true ); mDisconnectMenuItems[ id ] ->setEnabled( false ); break; case openVPNManager::CONNECTED: mConnectMenuItems[ id ] ->setEnabled( false ); mDisconnectMenuItems[ id ] ->setEnabled( true ); break; case openVPNManager::EXITING: mConnectMenuItems[ id ] ->setEnabled( false ); mDisconnectMenuItems[ id ] ->setEnabled( false ); break; case openVPNManager::UNKNOWN: default: mConnectMenuItems[ id ] ->setEnabled( true ); mDisconnectMenuItems[ id ] ->setEnabled( true ); break; } } void TrayWindow::setStateMenu( const QString & id, openVPNManager::states status ) { switch ( status ) { case openVPNManager::DISCONNECTED: mManagerMenus[ id ] ->changeTitle( 0, i18n( "Status" ) + ": " + i18n( "Disconnected" ) ); break; case openVPNManager::CONNECTING: mManagerMenus[ id ] ->changeTitle( 0, i18n( "Status" ) + ": " + i18n( "Connecting" ) ); break; case openVPNManager::WAIT: mManagerMenus[ id ] ->changeTitle( 0, i18n( "Status" ) + ": " + i18n( "Waiting" ) ); break; case openVPNManager::AUTH: mManagerMenus[ id ] ->changeTitle( 0, i18n( "Status" ) + ": " + i18n( "Authenticating" ) ); break; case openVPNManager::GET_CONFIG: mManagerMenus[ id ] ->changeTitle( 0, i18n( "Status" ) + ": " + i18n( "Getting remote config" ) ); break; case openVPNManager::ASSIGN_IP: mManagerMenus[ id ] ->changeTitle( 0, i18n( "Status" ) + ": " + i18n( "Assigning IP address" ) ); break; case openVPNManager::ADD_ROUTES: mManagerMenus[ id ] ->changeTitle( 0, i18n( "Status" ) + ": " + i18n( "Adding routes" ) ); break; case openVPNManager::CONNECTED: mManagerMenus[ id ] ->changeTitle( 0, i18n( "Status" ) + ": " + i18n( "Connected" ) ); break; case openVPNManager::RECONNECTING: mManagerMenus[ id ] ->changeTitle( 0, i18n( "Status" ) + ": " + i18n( "Reconnecting" ) ); break; case openVPNManager::EXITING: mManagerMenus[ id ] ->changeTitle( 0, i18n( "Status" ) + ": " + i18n( "Unavailable" ) ); break; case openVPNManager::UNKNOWN: default: mManagerMenus[ id ] ->changeTitle( 0, i18n( "Status" ) + ": " + i18n( "Unknown" ) ); break; } } TrayWindow::states TrayWindow::calcState( ) { int tConnected = 0; int tConnecting = 0; int tDisconnected = 0; /* These are the states: 1. DISCONNECTED - all managers are disconnected. 2. HALF_CONNECTED - some managers are connected, some are not. 3. CONNECTED - all managers are connected. 4. DISCONNECTED__CONNECTING - no managers is connected, some are connecting. 5. HALF_CONNECTED__CONNECTING - some managers are disconnected, some are connecting. These are the OpenVPN states: 0. EXITING 1. DISCONNECTED 2. CONNECTING 3. WAIT 4. AUTH 5. GET_CONFIG 6. ASSIGN_IP 7. ADD_ROUTES 8. RECONNECTING 9. CONNECTED Relevant groups are: 1. DISCONNECTED = DISCONNECTED, EXITING 2. CONNECTING = CONNECTING, WAIT, AUTH, GET_CONFIG, ASSIGN_IP, ADD_ROUTES, RECONNECTING 3. CONNECTED = CONNECTED ==> 1. DISCONNECTED = DISCONNECTED 2. HALF_CONNECTED = DISCONNECTED, CONNECTED 3. CONNECTED = CONNECTED 4. DISCONNECTED__CONNECTING = DISCONNECTED, CONNECTING 5. HALF_CONNECTED__CONNECTING = CONNECTED, DISCONNECTED, CONNECTING */ /* First of all, group them in the 3 groups mentioned above */ for ( QMap::Iterator it = mOvpnStates.begin(); it != mOvpnStates.end(); it++ ) { if ( it.data() == openVPNManager::CONNECTED ) tConnected++; else if ( it.data() == openVPNManager::DISCONNECTED || it.data() == openVPNManager::EXITING ) tDisconnected++; else tConnecting++; } /* Decide what state we've got */ if ( ! tDisconnected && ! tConnecting && ! tConnected ) mState = DISCONNECTED; else if ( ! tDisconnected && ! tConnecting && tConnected ) mState = CONNECTED; else if ( ! tDisconnected && tConnecting && ! tConnected ) mState = CONNECTING; else if ( ! tDisconnected && tConnecting && tConnected ) mState = CONNECTED__CONNECTING; else if ( tDisconnected && ! tConnecting && ! tConnected ) mState = DISCONNECTED; else if ( tDisconnected && ! tConnecting && tConnected ) mState = HALF_CONNECTED; else if ( tDisconnected && tConnecting && ! tConnected ) mState = DISCONNECTED__CONNECTING; else if ( tDisconnected && tConnecting && tConnected ) mState = HALF_CONNECTED__CONNECTING; debug( "stateChanged", QString( "tDisconnected : %1" ).arg( tDisconnected ) ); debug( "stateChanged", QString( "tConnecting : %1" ).arg( tConnecting ) ); debug( "stateChanged", QString( "tConnected : %1" ).arg( tConnected ) ); debug( "stateChanged", QString( "mState : %1" ).arg( mState ) ); return mState; } void TrayWindow::debug( const QString & method, const QString & message ) { #ifdef DEBUG QString myMethod ( method ); static unsigned int maxLen = 0; maxLen = QMAX( myMethod.length(), maxLen ); cout << "TrayWindow::" << myMethod.leftJustify( maxLen ) << " => " << message << endl; #endif } void TrayWindow::setAdvanced( bool advanced ) { debug( "setAdvanced" ); mAdvanced = advanced; } bool TrayWindow::eventFilter( QObject * o, QEvent * e ) { switch ( e->type() ) { case QEvent::Enter: setToolTip(); debug( "eventFilter", "QEvent::Enter" ); return false; /* false, because I want to toolTip to appear. and this is done somewhere else, but uses this event. */ break; default: debug( "eventFilter" ); return false; break; } } #include "traywindow.moc"