/*************************************************************************** * * tdenetman-device_tray.cpp - A NetworkManager frontend for KDE * * Copyright (C) 2005, 2006 Novell, Inc. * * Author: Helmut Schaa , * * 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 * **************************************************************************/ class WirelessDialog; // TQt includes #include #include #include #include #include #include #include #include #include #include #include // TDE includes #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // KNM includes #include "tdenetman-device_tray.h" #include "tdenetman-menu_subhead.h" #include "tdenetman-connection_settings_dialog.h" using namespace ConnectionSettings; class DeviceTrayPrivate { public: DeviceTrayPrivate() : dev(NULL) { tooltips[TDENetworkConnectionStatus::Invalid] = i18n("Unknown"); tooltips[TDENetworkConnectionStatus::LinkUnavailable] = i18n("Down"); tooltips[TDENetworkConnectionStatus::UnManaged] = i18n("Unmanaged"); tooltips[TDENetworkConnectionStatus::Disconnected] = i18n("Disconnected"); tooltips[TDENetworkConnectionStatus::EstablishingLink] = i18n("Preparing"); tooltips[TDENetworkConnectionStatus::ConfiguringProtocols] = i18n("Configuration"); tooltips[TDENetworkConnectionStatus::NeedAuthorization] = i18n("Awaiting authentication"); tooltips[TDENetworkConnectionStatus::VerifyingProtocols] = i18n("IP configuration"); tooltips[TDENetworkConnectionStatus::Connected] = i18n("Activated"); tooltips[TDENetworkConnectionStatus::Failed] = i18n("Failed"); } ~DeviceTrayPrivate() {} TDENetworkDevice* dev; TQMap movies; TQMap pixmaps; TQMap tooltips; TQPixmap pixmapForConnState(TDENetworkConnectionStatus::TDENetworkConnectionStatus state); TQMovie movieForConnState(TDENetworkConnectionStatus::TDENetworkConnectionStatus state); TQString tooltipForConnState(TDENetworkConnectionStatus::TDENetworkConnectionStatus state); }; TQPixmap DeviceTrayPrivate::pixmapForConnState(TDENetworkConnectionStatus::TDENetworkConnectionStatus state) { TDENetworkConnectionStatus::TDENetworkConnectionStatus flag = (TDENetworkConnectionStatus::TDENetworkConnectionStatus)0x80000000; while (flag > 0) { if (state & flag) { if (pixmaps.contains(flag)) { return pixmaps[flag]; } } flag = (TDENetworkConnectionStatus::TDENetworkConnectionStatus)(flag >> 1); } return TQPixmap(); } TQMovie DeviceTrayPrivate::movieForConnState(TDENetworkConnectionStatus::TDENetworkConnectionStatus state) { TDENetworkConnectionStatus::TDENetworkConnectionStatus flag = (TDENetworkConnectionStatus::TDENetworkConnectionStatus)0x80000000; while (flag > 0) { if (state & flag) { if (movies.contains(flag)) { return movies[flag]; } } flag = (TDENetworkConnectionStatus::TDENetworkConnectionStatus)(flag >> 1); } return TQMovie(); } TQString DeviceTrayPrivate::tooltipForConnState(TDENetworkConnectionStatus::TDENetworkConnectionStatus state) { TDENetworkConnectionStatus::TDENetworkConnectionStatus flag = (TDENetworkConnectionStatus::TDENetworkConnectionStatus)0x80000000; while (flag > 0) { if (state & flag) { if (tooltips.contains(flag)) { return tooltips[flag]; } } flag = (TDENetworkConnectionStatus::TDENetworkConnectionStatus)(flag >> 1); } return TQString::null; } TDENetworkDevice* DeviceTray::getDevice() const { return d->dev; } TQString DeviceTray::getTooltipText() { TDENetworkConnectionManager* deviceConnMan = d->dev->connectionManager(); TDENetworkConnectionStatus::TDENetworkConnectionStatus state = deviceConnMan->deviceInformation().statusFlags; TQString tooltip = TQString(); if (!d->tooltipForConnState(state).isEmpty()) { tooltip += i18n("State: %1").arg(d->tooltipForConnState(state)); } return tooltip; } void DeviceTray::enterEvent (TQEvent* /*e*/) { // show tooltip TQToolTip::remove (this); TQString tooltip = getTooltipText(); if (!tooltip.isEmpty()) { TQToolTip::add (this, tooltip); } } void DeviceTray::setPixmap(const TQPixmap& pixmap) { /* int oldPixmapWidth = pixmap.size().width(); int oldPixmapHeight = pixmap.size().height(); // we want to show the interface name TQString iface = d->dev->getInterface(); // grab a font TQFont iface_font = KGlobalSettings::generalFont(); // iface_font.setBold(true); // resize the font to fit the icon's size float fontSize = iface_font.pointSizeFloat(); TQFontMetrics qfm(iface_font); int height = qfm.height(); int width = qfm.width(iface); float factor = 1.0f; float factor2 = 1.0f; if (height > (oldPixmapHeight / 2.0f)) factor = float(oldPixmapHeight / 2.0f) / float(height); if (width > (oldPixmapWidth / 1.1f)) factor2 = float(oldPixmapWidth / 1.1f) / float(width); fontSize *= (factor2 < factor) ? factor2 : factor; iface_font.setPointSizeFloat( fontSize); // draw the text to a bitmap and put is as an overlay on top of the pixmap TQPixmap iface_pixmap(oldPixmapWidth, oldPixmapHeight); iface_pixmap.fill(TQt::white); TQPainter p(&iface_pixmap); p.setFont(iface_font); p.setPen(TQt::blue); p.drawText(iface_pixmap.rect(), TQt::AlignHCenter | TQt::AlignBottom, iface); iface_pixmap.setMask(iface_pixmap.createHeuristicMask()); TQImage iface_image = iface_pixmap.convertToImage(); TQImage pixmap_with_overlay = pixmap.convertToImage(); KIconEffect::overlay(pixmap_with_overlay, iface_image); TQPixmap new_pixmap; new_pixmap.convertFromImage(pixmap_with_overlay); // call base-class setPixmap KSystemTray::setPixmap(new_pixmap); */ KSystemTray::setPixmap(pixmap); } void DeviceTray::contextMenuAboutToShow (KPopupMenu* menu) { menu->clear(); // insert title menu->insertTitle (SmallIcon ("tdenetman", TQIconSet::Automatic), "KNetworkManager", -1, -1); // let the specific device_tray add its items addMenuItems(menu); // quit menu->insertSeparator (); KAction* quitAction = actionCollection ()->action (KStdAction::name (KStdAction::Quit)); if (quitAction) { quitAction->plug (menu); } } void DeviceTray::resizeEvent ( TQResizeEvent * ) { // Honor Free Desktop specifications that allow for arbitrary system tray icon sizes loadIcons(); updateTrayIcon(m_currentIconState); } void DeviceTray::setPixmapForState(TDENetworkConnectionStatus::TDENetworkConnectionStatus state, TQMovie movie) { d->movies[state] = movie; slotUpdateDeviceState(); } void DeviceTray::setPixmapForState(TDENetworkConnectionStatus::TDENetworkConnectionStatus state, TQPixmap pixmap) { d->pixmaps[state] = pixmap; slotUpdateDeviceState(); } void DeviceTray::updateTrayIcon(TDENetworkConnectionStatus::TDENetworkConnectionStatus state) { // stop the old movie to avoid unnecessary wakups if (movie()) { movie()->pause(); } if (!d->movieForConnState(state).isNull()) { if (m_currentIconState != state) { // Clear the icon pixmap as the movie may be a different size TQPixmap nullPixmap; setPixmap(nullPixmap); } // animation desired int frame = -1; if (movie()) { frame = movie()->frameNumber(); } // set the movie setMovie(d->movieForConnState(state)); // start at the same frame as the movie before if (frame > 0) movie()->step(frame); // start the animation movie()->unpause(); } else if (!d->pixmapForConnState(state).isNull()) { setPixmap(d->pixmapForConnState(state)); } else { setPixmap(loadSizedIcon("KNetworkManager", width())); } m_currentIconState = state; } void DeviceTray::updateActions(TDENetworkConnectionStatus::TDENetworkConnectionStatus state) { // allow device deactivation only when device is activated KAction* deactivate = actionCollection()->action("deactivate_device"); if (deactivate) deactivate->setEnabled( (state & TDENetworkConnectionStatus::Connected || state & TDENetworkConnectionStatus::VerifyingProtocols || state & TDENetworkConnectionStatus::EstablishingLink || state & TDENetworkConnectionStatus::ConfiguringProtocols || state & TDENetworkConnectionStatus::NeedAuthorization) ); } void DeviceTray::updateActiveConnection(TDENetworkConnectionStatus::TDENetworkConnectionStatus state) { if (!(state & TDENetworkConnectionStatus::Connected)) { return; } } void DeviceTray::slotUpdateDeviceState(TDENetworkConnectionStatus::TDENetworkConnectionStatus state) { updateTrayIcon(state); updateActions(state); updateActiveConnection(state); } void DeviceTray::slotUpdateDeviceState() { TDENetworkConnectionManager* deviceConnMan = d->dev->connectionManager(); slotUpdateDeviceState(deviceConnMan->deviceInformation().statusFlags); } void DeviceTray::loadIcons() { d->pixmaps[TDENetworkConnectionStatus::Invalid] = loadSizedIcon("nm_no_connection", width()); d->pixmaps[TDENetworkConnectionStatus::UnManaged] = loadSizedIcon("nm_no_connection", width()); d->pixmaps[TDENetworkConnectionStatus::LinkUnavailable] = loadSizedIcon("nm_no_connection", width()); d->pixmaps[TDENetworkConnectionStatus::Disconnected] = loadSizedIcon("nm_no_connection", width()); d->movies[TDENetworkConnectionStatus::EstablishingLink] = TQMovie( KGlobal::iconLoader()->moviePath("nm_stage01_connecting", KIcon::Panel)); d->movies[TDENetworkConnectionStatus::EstablishingLink].pause(); d->movies[TDENetworkConnectionStatus::ConfiguringProtocols] = TQMovie( KGlobal::iconLoader()->moviePath("nm_stage02_connecting", KIcon::Panel)); d->movies[TDENetworkConnectionStatus::ConfiguringProtocols].pause(); d->movies[TDENetworkConnectionStatus::VerifyingProtocols] = TQMovie( KGlobal::iconLoader()->moviePath("nm_stage03_connecting", KIcon::Panel)); d->movies[TDENetworkConnectionStatus::VerifyingProtocols].pause(); d->movies[TDENetworkConnectionStatus::NeedAuthorization] = d->movies[TDENetworkConnectionStatus::ConfiguringProtocols]; d->movies[TDENetworkConnectionStatus::NeedAuthorization].pause(); d->pixmaps[TDENetworkConnectionStatus::Connected] = loadSizedIcon("ok", width()); d->pixmaps[TDENetworkConnectionStatus::Failed] = loadSizedIcon("nm_no_connection", width()); } DeviceTray::DeviceTray (TDENetworkDevice* dev) : KSystemTray () { d = new DeviceTrayPrivate(); d->dev = dev; m_currentIconState = TDENetworkConnectionStatus::Invalid; loadIcons(); // get notified when the device state changes connect(dev, TQT_SIGNAL(StateChanged(TDENetworkConnectionStatus::TDENetworkConnectionStatus)), this, TQT_SLOT(slotUpdateDeviceState(TDENetworkConnectionStatus::TDENetworkConnectionStatus))); setMouseTracking (true); // defer the initial call to slotUpdateDeviceState as it will crash knm when called directly from here // virtual method calls are not allowed in constructor TQTimer::singleShot(0, this, TQT_SLOT(slotUpdateDeviceState())); // Actions used for plugging into the menu new KAction (i18n ("Deactivate connection..."), SmallIcon ("no", TQIconSet::Automatic), 0, dev, TQT_SLOT (slotDeactivate()), actionCollection (), "deactivate_device"); } DeviceTray::~DeviceTray () { delete d; } #include "tdenetman-device_tray.moc"