You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdenetworkmanager/tdenetworkmanager/src/tdenetman-tray.cpp

1151 lines
38 KiB

/***************************************************************************
*
* tdenetman-tray.cpp - A NetworkManager frontend for TDE
*
* Copyright (C) 2012 Timothy Pearson <kb9vqf@pearsoncomputing.net>
* Copyright (C) 2005, 2006 Novell, Inc.
*
* Author: Timo Hoenig <thoenig@suse.de>, <thoenig@nouse.net>
* Will Stephenson <wstephenson@suse.de>, <wstephenson@kde.org>
* Valentine Sinitsyn <e_val@inbox.ru>
* Helmut Schaa <hschaa@suse.de>, <helmut.schaa@gmx.de>
* Alexander Naumov <anaumov@suse.de>, <posix.ru@gmail.com>
* Author: Timothy Pearson <kb9vqf@pearsoncomputing.net>
*
* 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 <tqsignalmapper.h>
#include <tqevent.h>
#include <tqvbox.h>
#include <tqlayout.h>
#include <tqpushbutton.h>
#include <tqpixmap.h>
#include <tqpixmapcache.h>
#include <tqpainter.h>
#include <tqstyle.h>
#include <tqvaluelist.h>
#include <dcopclient.h>
#include <kdebug.h>
#include <kdialogbase.h>
#include <knotifyclient.h>
#include <knotifydialog.h>
#include <tdelocale.h>
#include <kstdguiitem.h>
#include <khelpmenu.h>
#include <kprocess.h>
#include <kiconloader.h>
#include <tdeconfig.h>
#include <tdemessagebox.h>
#include <tqpushbutton.h>
#include <tqlayout.h>
#include <tqlabel.h>
#include <tqapplication.h>
#include <tqdialog.h>
#include <tqfile.h>
#include "devicetraycomponent.h"
#include "tdenetman-tray.h"
#include "tdenetman-connection_settings_dialog.h"
#include "tdenetman-connection_editor.h"
#include "tdenetman-menu_subhead.h"
#include "tdenetman-wired_device_tray.h"
#include "tdenetman-wireless_device_tray.h"
#include "tdenetman-cellular_device_tray.h"
#include "vpn_tray_component.h"
#include <stdio.h>
unsigned int tdenetworkmanager_editor_dialog_count = 0;
TDENetworkConnectionStatus::TDENetworkConnectionStatus nm_device_state_global = TDENetworkConnectionStatus::Invalid;
NewSecretsDialog::NewSecretsDialog(TDENetworkConnection *connection, TQWidget * parent, const char * name, bool modal, TQt::WFlags f)
: TQDialog(parent, name, modal, f)
{
_connection = connection;
init();
}
NewSecretsDialog::~NewSecretsDialog ()
{
}
void NewSecretsDialog::slotDialogEdit()
{
ConnectionSettingsDialogImpl* dlg = new ConnectionSettingsDialogImpl(_connection, false, TQByteArray(), Tray::getInstance(), "Edit connection");
dlg->show();
close();
}
void NewSecretsDialog::reject()
{
TQDialog::reject();
}
void NewSecretsDialog::init()
{
TDENetworkConnection* conn = _connection;
// if we do not have a connection bail out
if (!conn)
{
reject();
return;
}
// show a message to the user that the connection failed
// and allow edit or cancel
TQLabel* label = new TQLabel(tqtr(" The connection %1 could not be established ").arg(conn->friendlyName), this);
TQPushButton* buttonEdit = new TQPushButton(tr("&Edit"), this);
TQPushButton* buttonCancel = new TQPushButton(tr("&Cancel"), this);
TQHBoxLayout *topLeftLayout = new TQHBoxLayout();
topLeftLayout->addWidget(buttonEdit);
topLeftLayout->addWidget(buttonCancel);
TQVBoxLayout *mainLayout = new TQVBoxLayout(this);
mainLayout->setMargin(15);
mainLayout->setSpacing(10);
mainLayout->addWidget(label);
mainLayout->addLayout(topLeftLayout);
connect(buttonEdit, TQT_SIGNAL(clicked()), TQT_SLOT(slotDialogEdit()));
connect(buttonCancel, TQT_SIGNAL(clicked()), this, TQT_SLOT(close()));
}
class TrayPrivate
{
public:
TrayPrivate(TQObject* parent)
: foregroundTrayComponent(0)
, signalMapper(parent, "signal_mapper")
, current_idx(0)
{}
~TrayPrivate() {}
static Tray* tray;
TQValueList<TrayComponent*> trayComponents;
DeviceTrayComponent * foregroundTrayComponent;
TQSignalMapper signalMapper;
TQMap<int, TQString> act_conn_map;
int current_idx;
KHelpMenu *helpMenu;
};
Tray* TrayPrivate::tray = NULL;
Tray* Tray::getInstance()
{
if (TrayPrivate::tray)
return TrayPrivate::tray;
else return (TrayPrivate::tray = new Tray());
}
void Tray::slotEditConnections()
{
TDEGlobalNetworkManager* nm = TDEGlobal::networkManager();
if (!nm) return;
if (tdenetworkmanager_editor_dialog_count == 0) nm->loadConnectionInformation();
ConnectionEditorImpl* dlg = new ConnectionEditorImpl(this, NULL, TRUE, (WFlags)TQt::WDestructiveClose);
dlg->show();
}
void Tray::slotEnableWireless()
{
TDEGlobalNetworkManager* nm = TDEGlobal::networkManager();
if (!nm) return;
nm->enableWiFi(true);
}
void Tray::slotDisableWireless()
{
TDEGlobalNetworkManager* nm = TDEGlobal::networkManager();
if (!nm) return;
nm->enableWiFi(false);
}
void Tray::slotOfflineMode()
{
TDEGlobalNetworkManager* nm = TDEGlobal::networkManager();
if (!nm) return;
nm->enableNetworking(false);
}
void Tray::slotOnlineMode()
{
TDEGlobalNetworkManager* nm = TDEGlobal::networkManager();
if (!nm) return;
nm->enableNetworking(true);
}
void Tray::slotNewVPNConnection()
{
kdDebug() << k_funcinfo << "Creating new VPN connection";
// create a new VPN connection
TDEVPNConnection* conn = new TDEVPNConnection();
// edit the new connection
ConnectionSettingsDialogImpl* dlg = new ConnectionSettingsDialogImpl(conn, true, TQByteArray(), this, "connect_something", false, TQt::WDestructiveClose);
dlg->show();
}
void Tray::slotVPNBannerShow(const TQString& vpnbanner)
{
kdDebug() << k_funcinfo << "VPN banner: " << vpnbanner;
KNotifyClient::event(winId(), "knm-nm-vpn-banner", vpnbanner);
}
void Tray::contextMenuAboutToShow (TDEPopupMenu* menu)
{
TDEGlobalNetworkManager* nm = TDEGlobal::networkManager();
// clear menu
menu->clear();
if (nm && !(nm->backendStatus() & TDENetworkGlobalManagerFlags::BackendUnavailable))
{
if (tdenetworkmanager_editor_dialog_count == 0)
{
nm->loadConnectionInformation();
}
// actions for each Device
for (TQValueList<TrayComponent*>::Iterator it = d->trayComponents.begin(); it != d->trayComponents.end(); ++it) {
(*it)->addMenuItems(menu);
}
// Submenu title
Subhead* subhead = new Subhead (menu, "subhead", TQString("Connection Management"), SmallIcon("tdenetworkmanager_disabled", TQIconSet::Automatic));
menu->insertItem (subhead, -1, -1);
// New connection
TDEAction * newConnAction = 0;
int devices = d->trayComponents.count();
if ( devices > 1 ) {
newConnAction = actionCollection ()->action ("new_connection_menu");
TDEActionMenu* newConnActionMenu = static_cast<TDEActionMenu*>(newConnAction);
newConnActionMenu->popupMenu()->clear();
TQValueList<TrayComponent*>::Iterator it;
for (it = d->trayComponents.begin(); it != d->trayComponents.end(); ++it) {
DeviceTrayComponent* dev_comp = dynamic_cast<DeviceTrayComponent*> (*it);
TDEAction * deviceNewConnAction = 0;
if (dev_comp) {
TDENetworkDevice* dev_comp_dev = dynamic_cast<TDENetworkDevice*>(hwdevices->findByUniqueID(dev_comp->device()));
if (dev_comp_dev)
{
TQString actionName = TQString("new_connection_%1").arg(dev_comp_dev->deviceNode());
TQString menuCaption = TQString("%1").arg(dev_comp_dev->deviceNode());
if (menuCaption.contains("eth", FALSE) > 0)
{
menuCaption = menuCaption.insert(0, "Wired Connection (");
}
else if (menuCaption.contains("wlan", FALSE) > 0)
{
menuCaption = menuCaption.insert(0, "Wireless Connection (");
}
else if (menuCaption.contains("pan", FALSE) > 0)
{
menuCaption = menuCaption.insert(0, "Private Area Connection (");
}
else
{
menuCaption = menuCaption.insert(0, "Unknown Connection (");
}
menuCaption = menuCaption.append(")");
deviceNewConnAction = actionCollection ()->action (actionName.utf8());
if (!deviceNewConnAction)
{
deviceNewConnAction = new TDEAction (menuCaption, 0, (*it), TQT_SLOT(newConnection()), actionCollection(), actionName.utf8());
}
newConnActionMenu->insert(deviceNewConnAction);
}
}
}
// New VPN connection option
++it;
TDEAction * deviceNewConnAction = 0;
TQString menuCaption = "VPN Connection";
TQString actionName = TQString("new_connection_%1").arg("vpn");
deviceNewConnAction = new TDEAction (menuCaption, 0, TQT_TQOBJECT(this), TQT_SLOT(slotNewVPNConnection()), actionCollection(), actionName.utf8());
newConnActionMenu->insert(deviceNewConnAction);
}
else if ( devices == 1 )
{
newConnAction = actionCollection ()->action ("new_connection");
TQT_BASE_OBJECT_NAME::disconnect( newConnAction, TQT_SIGNAL(activated()) );
TQT_BASE_OBJECT_NAME::connect( newConnAction, TQT_SIGNAL(activated()), d->trayComponents[0], TQT_SLOT(newConnection()));
}
if (newConnAction) {
newConnAction->plug(menu);
}
// turn things off
if (nm) {
TDEActionMenu* disableStuffActionMenu = static_cast<TDEActionMenu*>(actionCollection ()->action ("deactivate_menu") );
disableStuffActionMenu->popupMenu()->clear();
TDENetworkConnectionList* map = nm->connections();
d->act_conn_map.clear();
for (TDENetworkConnectionList::Iterator it = map->begin(); it != map->end(); ++it) {
TDENetworkConnection* conn = (*it);
if (!conn) {
continue;
}
TDENetworkConnectionStatus::TDENetworkConnectionStatus status = nm->checkConnectionStatus(conn->UUID);
if ((status == TDENetworkConnectionStatus::Disconnected)
|| (status == (TDENetworkConnectionStatus::Disconnected | TDENetworkConnectionStatus::LinkUnavailable))
|| (status & TDENetworkConnectionStatus::Invalid)
) {
continue;
}
TQString actionName = TQString("disable_connection_%1").arg(conn->UUID);
TDEAction * deviceNewConnAction = actionCollection ()->action (actionName.utf8());
TQString actionText = conn->friendlyName;
if (!deviceNewConnAction) {
deviceNewConnAction = new TDEAction (actionText, 0, &d->signalMapper, TQT_SLOT(map()), actionCollection(), actionName.utf8());
}
d->signalMapper.setMapping(deviceNewConnAction, d->current_idx);
d->act_conn_map.insert(d->current_idx, conn->UUID);
d->current_idx++;
disableStuffActionMenu->insert(deviceNewConnAction);
}
// disable wireless
if (nm->wiFiHardwareEnabled()) {
TDEAction* wireless = NULL;
if (nm->wiFiEnabled()) {
wireless = actionCollection ()->action ("disable_wireless");
} else {
wireless = actionCollection ()->action ("enable_wireless");
}
disableStuffActionMenu->insert(wireless);
}
// offline vs. online mode
TDEAction* switch_mode = NULL;
if (nm->backendStatus() & TDENetworkGlobalManagerFlags::Sleeping) {
switch_mode = actionCollection ()->action ("online_mode");
}
else {
switch_mode = actionCollection ()->action ("offline_mode");
}
disableStuffActionMenu->insert(switch_mode);
disableStuffActionMenu->plug(menu);
}
}
else {
Subhead* subhead = new Subhead (menu, "subhead", i18n("NetworkManager is not running"), SmallIcon("process-stop", TQIconSet::Automatic));
menu->insertItem (subhead, -1, -1);
}
// Notifications
TDEAction* notif = actionCollection()->action("configure_notifications");
notif->plug(menu);
// Connection Editor
TDEAction* edit = actionCollection ()->action ("edit_connections");
edit->plug(menu);
// quit
menu->insertSeparator();
menu->insertItem(SmallIcon("help"), i18n("&Help"), d->helpMenu->menu());
TDEAction* quitAction = actionCollection ()->action (KStdAction::name (KStdAction::Quit));
if (quitAction) {
quitAction->plug (menu);
}
}
void
Tray::setBaseStateIcon(TDENetworkGlobalManagerFlags::TDENetworkGlobalManagerFlags nm_state)
{
// change tray icon according to NM's state
if ((nm_state == TDENetworkGlobalManagerFlags::Unknown)
|| (nm_state & TDENetworkGlobalManagerFlags::Sleeping)
|| (nm_state & TDENetworkGlobalManagerFlags::EstablishingLink)
|| (nm_state & TDENetworkGlobalManagerFlags::Disconnected)
|| (nm_state & TDENetworkGlobalManagerFlags::BackendUnavailable)) {
setPixmap (m_pixmapCache["tdenetworkmanager_disabled"]);
}
else if (nm_state & TDENetworkGlobalManagerFlags::Connected) {
setPixmap (m_pixmapCache["tdenetworkmanager"]);
}
}
void
Tray::slotStateChanged(TDENetworkGlobalManagerFlags::TDENetworkGlobalManagerFlags newState, TDENetworkGlobalManagerFlags::TDENetworkGlobalManagerFlags prevState)
{
setBaseStateIcon(newState);
#ifdef DEBUG_STATE
printf("NM state: 0x%08x\n", newState);
#endif // DEBUG_STATE
showActiveDeviceTray();
}
void
Tray::enterEvent (TQEvent* /*e*/)
{
// show tooltip
TQToolTip::remove (this);
TQString tooltip = "";
// build up the tooltip from all tray components
for (TQValueList<TrayComponent*>::Iterator it = d->trayComponents.begin(); it != d->trayComponents.end(); ++it)
{
TrayComponent* comp = *it;
if (comp->getToolTipText().isEmpty()) {
continue;
}
if (!tooltip.isEmpty()) {
tooltip += "\n\n";
}
tooltip += comp->getToolTipText().join("\n");
}
if (!tooltip.isEmpty()) {
TQToolTip::add (this, tooltip);
}
}
void
Tray::slotSecretsNeeded(TDENetworkConnection* connection, const TQStringList& hints, bool request_new)
{
// For now assume secrets are already in NM...
}
void Tray::slotAddDeviceTrayComponent(TQString dev)
{
createDeviceTrayComponent(dev);
}
void Tray::slotRemoveDeviceTrayComponent(TQString dev)
{
for (TQValueList<TrayComponent*>::Iterator it = d->trayComponents.begin(); it != d->trayComponents.end(); ++it)
{
DeviceTrayComponent* dev_comp = dynamic_cast<DeviceTrayComponent*>(*it);
if (!dev_comp) {
continue;
}
if (dev_comp->device() == dev)
{
if (d->foregroundTrayComponent && dev_comp->device() == d->foregroundTrayComponent->device() ) {
d->foregroundTrayComponent = NULL;
}
// remove the appropriate action
TDENetworkDevice* dev_comp_dev = dynamic_cast<TDENetworkDevice*>(hwdevices->findByUniqueID(dev_comp->device()));
if (dev_comp_dev) {
TQString actionName = TQString("new_connection_%1").arg(dev_comp_dev->deviceNode());
TDEAction * deviceNewConnAction = actionCollection ()->action (actionName.utf8());
if (!deviceNewConnAction) {
delete deviceNewConnAction;
deviceNewConnAction = NULL;
}
}
// remove device_tray and delete it
d->trayComponents.remove(it);
delete dev_comp;
if (contextMenu()->isVisible()) {
contextMenu()->hide();
}
break;
}
}
}
void Tray::createDeviceTrayComponent(TQString dev)
{
bool trayExists = false;
// check if we have already a trayicon for this device
for (TQValueList<TrayComponent*>::Iterator it = d->trayComponents.begin(); it != d->trayComponents.end(); ++it)
{
DeviceTrayComponent* dev_comp = dynamic_cast<DeviceTrayComponent*> (*it);
if (dev_comp)
if (dev_comp->device() == dev)
{
trayExists = true;
break;
}
}
// create the appropriate device tray icon
if (!trayExists)
{
DeviceTrayComponent* devTray = 0;
TDENetworkDevice* new_tray_dev = dynamic_cast<TDENetworkDevice*>(hwdevices->findByUniqueID(dev));
TDENetworkConnectionManager* deviceConnMan = (new_tray_dev ? new_tray_dev->connectionManager() : NULL);
// different tray icons for different device types!
if (deviceConnMan)
{
switch (deviceConnMan->deviceType())
{
case TDENetworkDeviceType::WiredEthernet:
devTray = new WiredDeviceTray(dev, this, "wired_device_tray");
break;
case TDENetworkDeviceType::WiFi:
devTray = new WirelessDeviceTray(dev, this, "wireless_device_tray");
break;
case TDENetworkDeviceType::Modem:
devTray = new CellularDeviceTray(dev, this, "cellular_device_tray");
break;
default:
kdWarning() << k_funcinfo << "UDI: " << dev << " has unknown devicetype: " << deviceConnMan->deviceType() << endl;
}
}
if(devTray)
{
connect(devTray, TQT_SIGNAL(needsCenterStage(TrayComponent*, bool)), TQT_SLOT(trayComponentNeedsCenterStage(TrayComponent*, bool)));
connect(devTray, TQT_SIGNAL(uiUpdated()), TQT_SLOT(trayUiChanged()));
d->trayComponents.append(devTray);
//WILLTODO: sort
}
}
}
void Tray::createVPNTrayComponent()
{
bool trayExists = false;
// check if we have already a trayicon for this device
for (TQValueList<TrayComponent*>::Iterator it = d->trayComponents.begin(); it != d->trayComponents.end(); ++it)
{
VPNTrayComponent* vpn_comp = dynamic_cast<VPNTrayComponent*> (*it);
if (vpn_comp)
{
trayExists = true;
break;
}
}
// create the appropriate device tray icon
if (!trayExists)
{
TrayComponent* devTray = new VPNTrayComponent(this, "vpn_device_tray");
if(devTray)
{
d->trayComponents.append(devTray);
//WILLTODO: sort
}
}
}
void Tray::updateDeviceTrays()
{
// create one tray-icon for each device
TDEGenericHardwareList devices = hwdevices->listByDeviceClass(TDEGenericDeviceType::Network);
// check for newly added devices
for (TDEGenericHardwareList::iterator it = devices.begin(); it != devices.end(); ++it)
{
TDENetworkDevice* dev = dynamic_cast<TDENetworkDevice*>(*it);
if (dev) {
createDeviceTrayComponent(dev->uniqueID());
}
else {
kdWarning() << k_funcinfo << "got a NULL-Device" << endl;
}
}
// add the VPN componenet as it is not associated with a device
createVPNTrayComponent();
// show an active device if one is present
showActiveDeviceTray();
}
void Tray::mousePressEvent( TQMouseEvent *e )
{
if ( !TQT_TQRECT_OBJECT(rect()).contains( e->pos() ) ) {
return;
}
switch ( e->button() ) {
case Qt::LeftButton:
contextMenuAboutToShow(contextMenu());
contextMenu()->popup(e->globalPos());
break;
default:
KSystemTray::mousePressEvent( e );
break;
}
}
void Tray::slotDeactivateConnection(int index)
{
TDEGlobalNetworkManager* nm = TDEGlobal::networkManager();
if (!nm) return;
TDENetworkConnection* conn = nm->findConnectionByUUID(d->act_conn_map[index]);
if (conn) {
nm->deactivateConnection(conn->UUID);
}
}
void Tray::connectTrayDeviceManager() {
if (d->foregroundTrayComponent) {
TDENetworkDevice* foreground_tray_dev = dynamic_cast<TDENetworkDevice*>(hwdevices->findByUniqueID(d->foregroundTrayComponent->device()));
if (foreground_tray_dev) {
TDENetworkConnectionManager* deviceConnMan = foreground_tray_dev->connectionManager();
if (deviceConnMan) {
slotUpdateDeviceState(deviceConnMan->deviceStatus().statusFlags, d->foregroundTrayComponent->lastKnownState, TQString());
connect(deviceConnMan, TQT_SIGNAL(networkDeviceStateChanged(TDENetworkConnectionStatus::TDENetworkConnectionStatus, TDENetworkConnectionStatus::TDENetworkConnectionStatus, TQString)), this, TQT_SLOT(slotUpdateDeviceState(TDENetworkConnectionStatus::TDENetworkConnectionStatus, TDENetworkConnectionStatus::TDENetworkConnectionStatus, TQString)));
}
}
}
}
void Tray::disconnectTrayDeviceManager() {
if (d->foregroundTrayComponent) {
TDENetworkDevice* foreground_tray_dev = dynamic_cast<TDENetworkDevice*>(hwdevices->findByUniqueID(d->foregroundTrayComponent->device()));
if (foreground_tray_dev) {
TDENetworkConnectionManager* deviceConnMan = foreground_tray_dev->connectionManager();
if (deviceConnMan) {
slotUpdateDeviceState(deviceConnMan->deviceStatus().statusFlags, d->foregroundTrayComponent->lastKnownState, TQString());
disconnect(deviceConnMan, TQT_SIGNAL(networkDeviceStateChanged(TDENetworkConnectionStatus::TDENetworkConnectionStatus, TDENetworkConnectionStatus::TDENetworkConnectionStatus, TQString)), this, 0);
}
}
}
}
void Tray::updateTrayDeviceManagerState() {
if (d->foregroundTrayComponent) {
TDENetworkDevice* foreground_tray_dev = dynamic_cast<TDENetworkDevice*>(hwdevices->findByUniqueID(d->foregroundTrayComponent->device()));
if (foreground_tray_dev) {
TDENetworkConnectionManager* deviceConnMan = foreground_tray_dev->connectionManager();
if (deviceConnMan) {
slotUpdateDeviceState(deviceConnMan->deviceStatus().statusFlags, d->foregroundTrayComponent->lastKnownState, TQString());
}
}
}
}
void Tray::trayComponentNeedsCenterStage(TrayComponent *component, bool needsIt)
{
TDEGlobalNetworkManager* nm = TDEGlobal::networkManager();
DeviceTrayComponent * dtc = dynamic_cast<DeviceTrayComponent*>(component);
if (nm && dtc)
{
TDENetworkDevice* dtc_comp_dev = dynamic_cast<TDENetworkDevice*>(hwdevices->findByUniqueID(dtc->device()));
kdDebug()
<< k_funcinfo
<< (dtc_comp_dev ? dtc_comp_dev->deviceNode() : TQString("<unknown device>"))
<< " : " << needsIt
<< endl;
if (needsIt) {
if (d->foregroundTrayComponent) {
disconnectTrayDeviceManager();
}
d->foregroundTrayComponent = dtc;
connectTrayDeviceManager();
}
else {
disconnectTrayDeviceManager();
d->foregroundTrayComponent = NULL;
// use active default
TQStringList defaultDevices = nm->defaultNetworkDevices();
if (defaultDevices.count() > 0) {
// identify the new foreground
for (TQValueList<TrayComponent*>::Iterator it = d->trayComponents.begin(); it != d->trayComponents.end(); ++it) {
DeviceTrayComponent* newDtc = dynamic_cast<DeviceTrayComponent*> (*it);
if ( newDtc && newDtc->device() == defaultDevices[0] ) {
d->foregroundTrayComponent = newDtc;
break;
}
}
if (d->foregroundTrayComponent) {
TDENetworkDevice* newDtc_dev = dynamic_cast<TDENetworkDevice*>(hwdevices->findByUniqueID(d->foregroundTrayComponent->device()));
kdDebug()
<< " Device "
<< (dtc_comp_dev ? dtc_comp_dev->deviceNode() : TQString("<unknown device>"))
<< " background, new foreground device: "
<< (newDtc_dev ? newDtc_dev->deviceNode() : TQString("<unknown device>"))
<< endl;
connectTrayDeviceManager();
updateTrayDeviceManagerState();
}
}
// Make sure a relevant foregroundTrayComponent is shown at all times...
showActiveDeviceTray();
}
}
}
void Tray::slotUpdateDeviceState()
{
// FIXME
}
void Tray::slotUpdateDeviceState(TDENetworkConnectionStatus::TDENetworkConnectionStatus newState, TDENetworkConnectionStatus::TDENetworkConnectionStatus prevState, TQString deviceNode)
{
#ifdef DEBUG_STATE
printf("Device state: 0x%08x was: 0x%08x\n", newState, prevState);
#endif // DEBUG_STATE
if (newState != prevState) {
if (d->foregroundTrayComponent) {
d->foregroundTrayComponent->lastKnownState = newState;
}
updateTrayIcon(newState);
updateActiveConnection(newState);
}
}
void Tray::trayUiChanged()
{
DeviceTrayComponent * dtc = d->foregroundTrayComponent;
if (dtc) {
TDENetworkDevice* dtc_comp_dev = dynamic_cast<TDENetworkDevice*>(hwdevices->findByUniqueID(dtc->device()));
if (dtc_comp_dev)
{
TDENetworkConnectionManager* deviceConnMan = dtc_comp_dev->connectionManager();
if (deviceConnMan)
{
updateTrayIcon(deviceConnMan->deviceStatus().statusFlags);
}
}
}
}
void Tray::showActiveDeviceTray() {
// If the current foreground tray device is deactivated, find the first active device and use it instead
bool needsNewDeviceTrayComponent = true;
if (d->foregroundTrayComponent)
{
needsNewDeviceTrayComponent = false;
TDENetworkDevice* dtc_comp_dev = dynamic_cast<TDENetworkDevice*>(hwdevices->findByUniqueID(d->foregroundTrayComponent->device()));
TDENetworkConnectionManager* deviceConnMan = (dtc_comp_dev ? dtc_comp_dev->connectionManager() : NULL);
if (deviceConnMan)
{
TDENetworkConnectionStatus::TDENetworkConnectionStatus statusFlags = deviceConnMan->deviceStatus().statusFlags;
if ((statusFlags == TDENetworkConnectionStatus::Disconnected)
|| (statusFlags == (TDENetworkConnectionStatus::Disconnected | TDENetworkConnectionStatus::LinkUnavailable))
|| (statusFlags & TDENetworkConnectionStatus::Invalid))
{
needsNewDeviceTrayComponent = true;
}
}
}
if (needsNewDeviceTrayComponent) {
disconnectTrayDeviceManager();
d->foregroundTrayComponent = NULL;
for (TQValueList<TrayComponent*>::Iterator it = d->trayComponents.begin(); it != d->trayComponents.end(); ++it) {
DeviceTrayComponent* newDtc = dynamic_cast<DeviceTrayComponent*> (*it);
if (newDtc) {
TDENetworkDevice* dtc_comp_dev = dynamic_cast<TDENetworkDevice*>(hwdevices->findByUniqueID(newDtc->device()));
TDENetworkConnectionManager* deviceConnMan = (dtc_comp_dev ? dtc_comp_dev->connectionManager() : NULL);
if (deviceConnMan)
{
TDENetworkConnectionStatus::TDENetworkConnectionStatus statusFlags = deviceConnMan->deviceStatus().statusFlags;
if ((statusFlags == TDENetworkConnectionStatus::Disconnected)
|| (statusFlags == (TDENetworkConnectionStatus::Disconnected | TDENetworkConnectionStatus::LinkUnavailable))
|| (statusFlags & TDENetworkConnectionStatus::Invalid)
)
{
continue;
}
else
{
d->foregroundTrayComponent = newDtc;
break;
}
}
}
}
if (d->foregroundTrayComponent != NULL) {
connectTrayDeviceManager();
updateTrayDeviceManagerState();
}
}
trayUiChanged();
}
void Tray::updateTrayIcon(TDENetworkConnectionStatus::TDENetworkConnectionStatus state)
{
// Get all active connections
char active_vpn=0;
char found_any_active_connection=0;
TDEGlobalNetworkManager* nm = TDEGlobal::networkManager();
// Make sure the current state will be displayed
if (d->foregroundTrayComponent) {
TDENetworkDevice* foreground_tray_dev = dynamic_cast<TDENetworkDevice*>(hwdevices->findByUniqueID(d->foregroundTrayComponent->device()));
if (foreground_tray_dev) {
TDENetworkConnectionManager* deviceConnMan = foreground_tray_dev->connectionManager();
if (deviceConnMan) {
state = deviceConnMan->deviceStatus().statusFlags;
}
}
}
TDENetworkGlobalManagerFlags::TDENetworkGlobalManagerFlags globalState = (nm ? nm->backendStatus() : TDENetworkGlobalManagerFlags::Unknown);
// get all available VPN Connections
active_vpn = 0;
if ((globalState & TDENetworkGlobalManagerFlags::VPNConnected) | ((globalState & TDENetworkGlobalManagerFlags::VPNDisconnected) && (globalState & TDENetworkGlobalManagerFlags::VPNEstablishingLink))) {
active_vpn = 1;
}
found_any_active_connection = 0;
if ((globalState & TDENetworkGlobalManagerFlags::Connected) | ((globalState & TDENetworkGlobalManagerFlags::Disconnected) && (globalState & TDENetworkGlobalManagerFlags::EstablishingLink))) {
found_any_active_connection = 1;
}
#ifdef DEBUG_STATE
// if (found_any_active_connection == 1) {
// printf("Active connection found\n");
// }
#endif // DEBUG_STATE
TDENetworkGlobalManagerFlags::TDENetworkGlobalManagerFlags current_vpn_state = (globalState & TDENetworkGlobalManagerFlags::VPNMask);
if ((current_vpn_state & TDENetworkGlobalManagerFlags::VPNFailed) || (current_vpn_state & TDENetworkGlobalManagerFlags::VPNDisconnected)) {
active_vpn = 0;
}
// stop the old movie to avoid unnecessary wakups
DeviceTrayComponent * dtc = d->foregroundTrayComponent;
if (movie()) {
movie()->pause();
}
if (active_vpn == 0) {
if ((dtc) && (found_any_active_connection == 1)) {
TQMovie stateMovie = dtc->movieForState(state);
if (!stateMovie.isNull()) {
// animation desired
int frame = -1;
if (movie()) {
frame = movie()->frameNumber();
}
// set the movie
setMovie(stateMovie);
// start at the same frame as the movie before
if (frame > 0) {
movie()->step(frame);
}
// start the animation
movie()->unpause();
}
else {
TQPixmap statePixmap = dtc->pixmapForState(state);
if (!statePixmap.isNull()) {
setPixmap(statePixmap);
}
else {
setPixmap(m_pixmapCache["tdenetworkmanager"]);
}
}
}
else {
setBaseStateIcon(globalState);
}
}
else {
TDENetworkGlobalManagerFlags::TDENetworkGlobalManagerFlags current_vpn_state = (globalState & TDENetworkGlobalManagerFlags::VPNMask);
#ifdef DEBUG_STATE
printf("VPN state: 0x%08x\n", current_vpn_state);
//printf("Activated is: %d\n", TDENetworkConnectionStatus::Connected);
#endif // DEBUG_STATE
// stop the old movie to avoid unnecessary wakups
DeviceTrayComponent * dtc = d->foregroundTrayComponent;
if (movie())
movie()->pause();
if (dtc) {
if (current_vpn_state & TDENetworkGlobalManagerFlags::VPNConnected) {
setPixmap(m_pixmapCache["nm_device_vpn"]);
}
if ((current_vpn_state & TDENetworkGlobalManagerFlags::VPNEstablishingLink)
|| (current_vpn_state & TDENetworkGlobalManagerFlags::VPNNeedAuthorization)
|| (current_vpn_state & TDENetworkGlobalManagerFlags::VPNConfiguringProtocols)
|| (current_vpn_state & TDENetworkGlobalManagerFlags::VPNVerifyingProtocols)) {
int frame = -1;
if (movie()) {
frame = movie()->frameNumber();
}
// set the movie
if ((current_vpn_state & TDENetworkGlobalManagerFlags::VPNEstablishingLink)
|| (current_vpn_state & TDENetworkGlobalManagerFlags::VPNNeedAuthorization)) {
setMovie(TQMovie(m_movieCache["nm_stage02_connecting_vpn"]));
}
if ((current_vpn_state & TDENetworkGlobalManagerFlags::VPNConfiguringProtocols)
|| (current_vpn_state & TDENetworkGlobalManagerFlags::VPNVerifyingProtocols)) {
setMovie(TQMovie(m_movieCache["nm_stage03_connecting_vpn"]));
}
// start at the same frame as the movie before
if (frame > 0) {
movie()->step(frame);
}
// start the animation
movie()->unpause();
}
}
}
nm_device_state_global = state;
#ifdef DEBUG_STATE
//printf("Device state: 0x%08x\n", nm_device_state_global);
#endif // DEBUG_STATE
}
void Tray::updateActiveConnection(TDENetworkConnectionStatus::TDENetworkConnectionStatus state)
{
if (state != TDENetworkConnectionStatus::Connected) {
return;
}
}
void Tray::slotDeviceAddedNotify(TDENetworkDevice* dev)
{
kdDebug() << "Tray::slotDeviceAddedNotify" << endl;
if( dev && !dev->deviceNode().isEmpty() ) {
KNotifyClient::event( winId(), "tdenm-nm-device-added", i18n("New network device %1 found").arg(dev->deviceNode()) );
}
}
void Tray::slotDeviceRemovedNotify(TDENetworkDevice* dev)
{
kdDebug() << "Tray::slotDeviceRemovedNotify" << endl;
if( dev && !dev->deviceNode().isEmpty() ) {
KNotifyClient::event( winId(), "tdenm-nm-device-removed", i18n("Network device %1 removed").arg(dev->deviceNode()) );
}
}
void Tray::slotStateChangedNotify(TDENetworkGlobalManagerFlags::TDENetworkGlobalManagerFlags newState, TDENetworkGlobalManagerFlags::TDENetworkGlobalManagerFlags prevState)
{
TDENetworkGlobalManagerFlags::TDENetworkGlobalManagerFlags nm_state = newState;
// popup notification according to NM's state
if (nm_state & TDENetworkGlobalManagerFlags::EstablishingLink) {
KNotifyClient::event( winId(), "tdenm-nm-connecting", i18n("NetworkManager is connecting") );
}
else if (nm_state & TDENetworkGlobalManagerFlags::Disconnected) {
KNotifyClient::event( winId(), "tdenm-nm-disconnected", i18n("NetworkManager is now disconnected") );
}
else if (nm_state & TDENetworkGlobalManagerFlags::Connected) {
KNotifyClient::event( winId(), "tdenm-nm-connected", i18n("NetworkManager is now connected") );
}
else if (nm_state & TDENetworkGlobalManagerFlags::Sleeping) {
KNotifyClient::event( winId(), "tdenm-nm-sleeping", i18n("TDENetworkManager Offline") );
}
else if (nm_state & TDENetworkGlobalManagerFlags::Unknown) {
//
}
}
void Tray::slotEditNotifications()
{
KNotifyDialog::configure(this);
}
void Tray::slotGenericDeviceAdded(TDEGenericDevice *dev)
{
TDENetworkDevice* netdev = dynamic_cast<TDENetworkDevice*>(dev);
if (netdev) {
slotAddDeviceTrayComponent(netdev->uniqueID());
slotDeviceAddedNotify(netdev);
}
}
void Tray::slotGenericDeviceRemoved(TDEGenericDevice *dev)
{
TDENetworkDevice* netdev = dynamic_cast<TDENetworkDevice*>(dev);
if (netdev) {
slotRemoveDeviceTrayComponent(netdev->uniqueID());
slotDeviceRemovedNotify(netdev);
}
}
void Tray::slotVPNEventHandler(TDENetworkVPNEventType::TDENetworkVPNEventType event, TQString message)
{
if (event == TDENetworkVPNEventType::LoginBanner) {
slotVPNBannerShow(message);
}
}
TQPixmap Tray::pixmapForName(TQString pixmapPath)
{
if (pixmapPath != "") {
return KSystemTray::loadIcon(pixmapPath);
}
else {
return TQPixmap();
}
}
TQMovie Tray::movieForName(TQString moviePath)
{
if (moviePath != "") {
return TQMovie(TDEGlobal::iconLoader()->moviePath(moviePath, TDEIcon::Panel, width()));
}
else {
return TQMovie();
}
}
TQByteArray Tray::movieFileData(TQString movieName) {
TQByteArray ret;
TQString fileName = TDEGlobal::iconLoader()->moviePath(movieName, TDEIcon::Panel, width());
if (fileName != "") {
TQFile file(fileName);
if (file.exists()) {
if (file.open(IO_ReadOnly)) {
ret = file.readAll();
file.close();
}
}
}
return ret;
}
void Tray::updateGraphicsCache() {
m_pixmapCache["tdenetworkmanager"] = pixmapForName("tdenetworkmanager");
m_pixmapCache["tdenetworkmanager_disabled"] = pixmapForName("tdenetworkmanager_disabled");
m_pixmapCache["nm_no_connection"] = pixmapForName("nm_no_connection");
m_pixmapCache["nm_device_vpn"] = pixmapForName("nm_device_vpn");
m_pixmapCache["ok"] = pixmapForName("ok");
m_pixmapCache["nm_signal_00"] = pixmapForName("nm_signal_00");
m_pixmapCache["nm_signal_25"] = pixmapForName("nm_signal_25");
m_pixmapCache["nm_signal_50"] = pixmapForName("nm_signal_50");
m_pixmapCache["nm_signal_75"] = pixmapForName("nm_signal_75");
m_pixmapCache["nm_signal_100"] = pixmapForName("nm_signal_100");
m_movieCache["nm_stage01_connecting"] = movieFileData("nm_stage01_connecting");
m_movieCache["nm_stage02_connecting"] = movieFileData("nm_stage02_connecting");
m_movieCache["nm_stage03_connecting"] = movieFileData("nm_stage03_connecting");
m_movieCache["nm_stage02_connecting_vpn"] = movieFileData("nm_stage02_connecting_vpn");
m_movieCache["nm_stage03_connecting_vpn"] = movieFileData("nm_stage03_connecting_vpn");
}
void Tray::resizeEvent(TQResizeEvent *) {
updateGraphicsCache();
}
Tray::Tray() : KSystemTray()
{
hwdevices = TDEGlobal::hardwareDevices();
updateGraphicsCache();
d = new TrayPrivate(TQT_TQOBJECT(this));
d->helpMenu = new KHelpMenu(0, TDEGlobal::instance()->aboutData(), false);
connect(&d->signalMapper, TQT_SIGNAL(mapped(int)), this, TQT_SLOT(slotDeactivateConnection(int)));
setPixmap (m_pixmapCache["tdenetworkmanager"]);
setMouseTracking (true);
// Actions used for plugging into the menu
new TDEAction (i18n ("Switch to offline mode"),
SmallIcon ("no", TQIconSet::Automatic), 0,
TQT_TQOBJECT(this), TQT_SLOT (slotOfflineMode()), actionCollection (), "offline_mode");
new TDEAction (i18n ("Switch to online mode"),
SmallIcon ("ok", TQIconSet::Automatic), 0,
TQT_TQOBJECT(this), TQT_SLOT (slotOnlineMode()), actionCollection (), "online_mode");
new TDEAction (i18n ("Disable Wireless"),
SmallIcon ("wireless_off", TQIconSet::Automatic), 0,
TQT_TQOBJECT(this), TQT_SLOT (slotDisableWireless()), actionCollection (), "disable_wireless");
new TDEAction (i18n ("Enable Wireless"),
SmallIcon ("wireless", TQIconSet::Automatic), 0,
TQT_TQOBJECT(this), TQT_SLOT (slotEnableWireless()), actionCollection (), "enable_wireless");
new TDEAction (i18n ("Edit Connections"),
SmallIcon ("edit", TQIconSet::Automatic), 0,
TQT_TQOBJECT(this), TQT_SLOT (slotEditConnections()), actionCollection (), "edit_connections");
new TDEAction (i18n ("Configure Notifications"),
SmallIcon ("knotify", TQIconSet::Automatic), 0,
TQT_TQOBJECT(this), TQT_SLOT (slotEditNotifications()), actionCollection (), "configure_notifications");
// this action is only connected when the menu is shown, hence the 0 receiver
new TDEAction (i18n ("New connection ..."),
SmallIcon ("document-new", TQIconSet::Automatic), 0,
TQT_TQOBJECT(this), 0, actionCollection (), "new_connection");
new TDEActionMenu (i18n ("New connection ..."),
SmallIcon ("document-new", TQIconSet::Automatic),
actionCollection(), "new_connection_menu");
new TDEActionMenu (i18n ("Deactivate connection..."),
SmallIcon ("no", TQIconSet::Automatic),
actionCollection (), "deactivate_menu");
// get notified when NM's state changes
connect(TDEGlobal::networkManager(), TQT_SIGNAL(networkConnectionStateChanged(TDENetworkGlobalManagerFlags::TDENetworkGlobalManagerFlags, TDENetworkGlobalManagerFlags::TDENetworkGlobalManagerFlags)), this, TQT_SLOT(slotStateChanged(TDENetworkGlobalManagerFlags::TDENetworkGlobalManagerFlags, TDENetworkGlobalManagerFlags::TDENetworkGlobalManagerFlags)));
// get notified about new/removed devices
connect(hwdevices, TQT_SIGNAL(hardwareAdded(TDEGenericDevice*)), this, TQT_SLOT(slotGenericDeviceAdded(TDEGenericDevice*)));
connect(hwdevices, TQT_SIGNAL(hardwareRemoved(TDEGenericDevice*)), this, TQT_SLOT(slotGenericDeviceRemoved(TDEGenericDevice*)));
// Notifications
connect(TDEGlobal::networkManager(), TQT_SIGNAL(networkConnectionStateChanged(TDENetworkGlobalManagerFlags::TDENetworkGlobalManagerFlags, TDENetworkGlobalManagerFlags::TDENetworkGlobalManagerFlags)), this, TQT_SLOT(slotStateChangedNotify(TDENetworkGlobalManagerFlags::TDENetworkGlobalManagerFlags, TDENetworkGlobalManagerFlags::TDENetworkGlobalManagerFlags)));
connect(TDEGlobal::networkManager(), TQT_SIGNAL(vpnEvent(TDENetworkVPNEventType::TDENetworkVPNEventType, TQString)), this, TQT_SLOT(slotVPNEventHandler(TDENetworkVPNEventType::TDENetworkVPNEventType, TQString)));
// Get connection list
TDEGlobalNetworkManager* nm = TDEGlobal::networkManager();
if (nm) {
if (tdenetworkmanager_editor_dialog_count == 0) nm->loadConnectionInformation();
}
// initial setup of the device-trays
updateDeviceTrays();
slotStateChanged(nm ? nm->backendStatus() : TDENetworkGlobalManagerFlags::Unknown, TDENetworkGlobalManagerFlags::Unknown);
}
Tray::~Tray ()
{
delete d;
}
#include "tdenetman-tray.moc"