summaryrefslogtreecommitdiffstats
path: root/src/knemod
diff options
context:
space:
mode:
Diffstat (limited to 'src/knemod')
-rw-r--r--src/knemod/Makefile.am47
-rw-r--r--src/knemod/backends/Makefile.am22
-rw-r--r--src/knemod/backends/backendbase.cpp38
-rw-r--r--src/knemod/backends/backendbase.h68
-rw-r--r--src/knemod/backends/daemonregistry.h54
-rw-r--r--src/knemod/backends/kcmregistry.h61
-rw-r--r--src/knemod/backends/nettoolsbackend.cpp498
-rw-r--r--src/knemod/backends/nettoolsbackend.h72
-rw-r--r--src/knemod/backends/sysbackend.cpp428
-rw-r--r--src/knemod/backends/sysbackend.h54
-rw-r--r--src/knemod/eventsrc220
-rw-r--r--src/knemod/global.h130
-rw-r--r--src/knemod/interface.cpp487
-rw-r--r--src/knemod/interface.h243
-rw-r--r--src/knemod/interfaceicon.cpp309
-rw-r--r--src/knemod/interfaceicon.h105
-rw-r--r--src/knemod/interfacemonitor.cpp100
-rw-r--r--src/knemod/interfacemonitor.h72
-rw-r--r--src/knemod/interfacestatistics.cpp384
-rw-r--r--src/knemod/interfacestatistics.h191
-rw-r--r--src/knemod/interfacestatisticsdialog.cpp139
-rw-r--r--src/knemod/interfacestatisticsdialog.h68
-rw-r--r--src/knemod/interfacestatisticsdlg.ui230
-rw-r--r--src/knemod/interfacestatusdialog.cpp308
-rw-r--r--src/knemod/interfacestatusdialog.h89
-rw-r--r--src/knemod/interfacestatusdlg.ui759
-rw-r--r--src/knemod/interfacetooltip.cpp204
-rw-r--r--src/knemod/interfacetooltip.h72
-rw-r--r--src/knemod/interfacetray.cpp121
-rw-r--r--src/knemod/interfacetray.h81
-rw-r--r--src/knemod/knemod.desktop41
-rw-r--r--src/knemod/knemodaemon.cpp344
-rw-r--r--src/knemod/knemodaemon.h120
-rw-r--r--src/knemod/pics/Makefile.am2
-rw-r--r--src/knemod/pics/cr16-app-knemo.pngbin0 -> 947 bytes
-rw-r--r--src/knemod/pics/cr22-action-network_connected.pngbin0 -> 1057 bytes
-rw-r--r--src/knemod/pics/cr22-action-network_connected_lan.pngbin0 -> 849 bytes
-rw-r--r--src/knemod/pics/cr22-action-network_connected_ppp.pngbin0 -> 587 bytes
-rw-r--r--src/knemod/pics/cr22-action-network_connected_wlan.pngbin0 -> 461 bytes
-rw-r--r--src/knemod/pics/cr22-action-network_disconnected.pngbin0 -> 1305 bytes
-rw-r--r--src/knemod/pics/cr22-action-network_disconnected_lan.pngbin0 -> 745 bytes
-rw-r--r--src/knemod/pics/cr22-action-network_disconnected_ppp.pngbin0 -> 641 bytes
-rw-r--r--src/knemod/pics/cr22-action-network_disconnected_wlan.pngbin0 -> 472 bytes
-rw-r--r--src/knemod/pics/cr22-action-network_incoming.pngbin0 -> 1144 bytes
-rw-r--r--src/knemod/pics/cr22-action-network_incoming_lan.pngbin0 -> 1121 bytes
-rw-r--r--src/knemod/pics/cr22-action-network_incoming_ppp.pngbin0 -> 980 bytes
-rw-r--r--src/knemod/pics/cr22-action-network_incoming_wlan.pngbin0 -> 943 bytes
-rw-r--r--src/knemod/pics/cr22-action-network_outgoing.pngbin0 -> 1153 bytes
-rw-r--r--src/knemod/pics/cr22-action-network_outgoing_lan.pngbin0 -> 1164 bytes
-rw-r--r--src/knemod/pics/cr22-action-network_outgoing_ppp.pngbin0 -> 1021 bytes
-rw-r--r--src/knemod/pics/cr22-action-network_outgoing_wlan.pngbin0 -> 799 bytes
-rw-r--r--src/knemod/pics/cr22-action-network_traffic.pngbin0 -> 1062 bytes
-rw-r--r--src/knemod/pics/cr22-action-network_traffic_lan.pngbin0 -> 1416 bytes
-rw-r--r--src/knemod/pics/cr22-action-network_traffic_ppp.pngbin0 -> 1298 bytes
-rw-r--r--src/knemod/pics/cr22-action-network_traffic_wlan.pngbin0 -> 1152 bytes
-rw-r--r--src/knemod/pics/cr32-app-knemo.pngbin0 -> 2711 bytes
-rw-r--r--src/knemod/signalplotter.cpp706
-rw-r--r--src/knemod/signalplotter.h160
58 files changed, 7027 insertions, 0 deletions
diff --git a/src/knemod/Makefile.am b/src/knemod/Makefile.am
new file mode 100644
index 0000000..a9496bc
--- /dev/null
+++ b/src/knemod/Makefile.am
@@ -0,0 +1,47 @@
+## Makefile.am for knemo
+
+messages: rc.cpp
+ $(XGETTEXT) *.cpp -o $(podir)/knemod.pot
+
+# this has all of the subdirectories that make will recurse into. if
+# there are none, comment this out
+SUBDIRS = pics backends
+
+# this is the program that gets installed. it's name is used for all
+# of the other Makefile.am variables
+kde_module_LTLIBRARIES = kded_knemod.la
+
+# set the include path for X, qt and KDE
+INCLUDES = -I$(srcdir)/../common -I$(srcdir)/backends $(all_includes)
+
+# the library search path.
+kded_knemod_la_LDFLAGS = -module -avoid-version $(all_libraries)
+
+# the libraries to link against.
+kded_knemod_la_LIBADD = $(LIB_KIO) $(LIB_KUTILS) backends/libknemo_backends.la
+
+# which sources should be compiled for knemo
+kded_knemod_la_SOURCES = knemodaemon.cpp knemodaemon.skel interface.cpp \
+ interfaceicon.cpp interfacetray.cpp \
+ interfacemonitor.cpp \
+ interfacestatusdlg.ui interfacestatusdialog.cpp \
+ interfacetooltip.cpp signalplotter.cpp \
+ interfacestatistics.cpp interfacestatisticsdlg.ui \
+ interfacestatisticsdialog.cpp
+
+# these are the headers for your project
+noinst_HEADERS = knemodaemon.h interface.h interfaceicon.h \
+ interfacemonitor.h \
+ interfacestatusdialog.h interfacetray.h \
+ interfacetooltip.h signalplotter.h \
+ interfacestatistics.h global.h \
+ interfacestatisticsdialog.h
+
+# let automoc handle all of the meta source files (moc)
+METASOURCES = AUTO
+
+services_DATA = knemod.desktop
+servicesdir = $(kde_servicesdir)/kded
+
+mydata_DATA = eventsrc
+mydatadir = $(kde_datadir)/knemo
diff --git a/src/knemod/backends/Makefile.am b/src/knemod/backends/Makefile.am
new file mode 100644
index 0000000..aab0fd0
--- /dev/null
+++ b/src/knemod/backends/Makefile.am
@@ -0,0 +1,22 @@
+## Makefile.am for knemo backends
+
+noinst_LTLIBRARIES = libknemo_backends.la
+
+# set the include path for X, qt and KDE
+INCLUDES = -I$(srcdir)/.. -I$(srcdir)/../../common $(all_includes)
+
+# the library search path.
+libknemo_backends_la_LDFLAGS = -module -avoid-version $(all_libraries)
+
+# the libraries to link against.
+libknemo_backends_la_LIBADD = $(LIB_KIO) $(LIB_KUTILS)
+
+# which sources should be compiled as backends
+libknemo_backends_la_SOURCES = backendbase.cpp nettoolsbackend.cpp sysbackend.cpp
+
+# the headers of the backends
+noinst_HEADERS = backendbase.h nettoolsbackend.h sysbackend.h
+
+# let automoc handle all of the meta source files (moc)
+METASOURCES = AUTO
+
diff --git a/src/knemod/backends/backendbase.cpp b/src/knemod/backends/backendbase.cpp
new file mode 100644
index 0000000..82da372
--- /dev/null
+++ b/src/knemod/backends/backendbase.cpp
@@ -0,0 +1,38 @@
+/* This file is part of KNemo
+ Copyright (C) 2006 Percy Leonhardt <[email protected]>
+
+ KNemo is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of
+ the License, or (at your option) any later version.
+
+ KNemo 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 Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "backendbase.h"
+
+BackendBase::BackendBase( QDict<Interface>& interfaces )
+ : mInterfaces( interfaces )
+{
+}
+
+BackendBase::~BackendBase()
+{
+}
+
+void BackendBase::updateComplete()
+{
+ QDictIterator<Interface> ifIt( mInterfaces );
+ for ( ; ifIt.current(); ++ifIt )
+ {
+ ifIt.current()->activateMonitor();
+ }
+}
diff --git a/src/knemod/backends/backendbase.h b/src/knemod/backends/backendbase.h
new file mode 100644
index 0000000..183e40a
--- /dev/null
+++ b/src/knemod/backends/backendbase.h
@@ -0,0 +1,68 @@
+/* This file is part of KNemo
+ Copyright (C) 2006 Percy Leonhardt <[email protected]>
+
+ KNemo is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of
+ the License, or (at your option) any later version.
+
+ KNemo 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 Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef BACKENDBASE_H
+#define BACKENDBASE_H
+
+#include <qdict.h>
+#include <qstring.h>
+
+#include <klocale.h>
+
+#include "data.h"
+#include "interface.h"
+
+/**
+ * This is the baseclass for all backends. Every backend that
+ * should be used for KNemo must inherit from this class.
+ *
+ * @short Baseclass for all backends
+ * @author Percy Leonhardt <[email protected]>
+ */
+
+class BackendBase
+{
+public:
+ BackendBase( QDict<Interface>& interfaces );
+ virtual ~BackendBase();
+
+ /**
+ * Create an instance of this backend because KNemo
+ * does not know about the different types of backends.
+ */
+
+ /**
+ * This function is called from KNemo whenever the
+ * backend shall update the information of the
+ * interfaces in the QDict.
+ */
+ virtual void update() = 0;
+
+protected:
+ /**
+ * Call this function when you have completed the
+ * update. It will trigger the interfaces to check
+ * if there state has changed.
+ */
+ void updateComplete();
+
+ const QDict<Interface>& mInterfaces;
+};
+
+#endif // BACKENDBASE_H
diff --git a/src/knemod/backends/daemonregistry.h b/src/knemod/backends/daemonregistry.h
new file mode 100644
index 0000000..ba4638d
--- /dev/null
+++ b/src/knemod/backends/daemonregistry.h
@@ -0,0 +1,54 @@
+/* This file is part of KNemo
+ Copyright (C) 2006 Percy Leonhardt <[email protected]>
+
+ KNemo is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of
+ the License, or (at your option) any later version.
+
+ KNemo 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 Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef DAEMONREGISTRY_H
+#define DAEMONREGISTRY_H
+
+#include <qstring.h>
+
+#include <klocale.h>
+
+#include "backendbase.h"
+#include "sysbackend.h"
+#include "nettoolsbackend.h"
+
+/**
+ * This registry tells KNemo what backends are available
+ * and how they can be created. It is only used by the daemon
+ * to create the selected backend. Two registries were
+ * necessary to avoid linking the KCM module against all backends.
+ *
+ * @short Registry for all backends
+ * @author Percy Leonhardt <[email protected]>
+ */
+
+struct DaemonRegistryEntry
+{
+ QString name;
+ BackendBase* (*function) ( QDict<Interface>& );
+};
+
+DaemonRegistryEntry DaemonRegistry[] =
+{
+ { "Nettools", NetToolsBackend::createInstance },
+ { "Sys", SysBackend::createInstance },
+ { QString::null, 0 }
+};
+
+#endif // DAEMONREGISTRY_H
diff --git a/src/knemod/backends/kcmregistry.h b/src/knemod/backends/kcmregistry.h
new file mode 100644
index 0000000..23820ac
--- /dev/null
+++ b/src/knemod/backends/kcmregistry.h
@@ -0,0 +1,61 @@
+/* This file is part of KNemo
+ Copyright (C) 2006 Percy Leonhardt <[email protected]>
+
+ KNemo is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of
+ the License, or (at your option) any later version.
+
+ KNemo 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 Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KCMREGISTRY_H
+#define KCMREGISTRY_H
+
+#include <qstring.h>
+
+#include <klocale.h>
+
+/**
+ * This registry tells the KCM module what backends are available
+ * and how they can be created. It also offers a short description
+ * for every backend that is used in the configuration dialog of KNemo.
+ * It should describe how a backend gathers its information.
+ *
+ * @short Registry for all backends
+ * @author Percy Leonhardt <[email protected]>
+ */
+
+struct KCMRegistryEntry
+{
+ QString name;
+ QString description;
+};
+
+KCMRegistryEntry KCMRegistry[] =
+{
+ { "Nettools",
+ i18n( "Uses the tools from the nettool packge like ifconfig, " \
+ "iwconfig and route to read the necessary information " \
+ "from the ouput of these commands.\n" \
+ "This backend works rather stable but causes a relativly " \
+ "high CPU load." ) },
+ { "Sys",
+ i18n( "Uses the sys filesystem available in 2.6 kernels and " \
+ "direct system calls to the Linux kernel.\n" \
+ "This backend is rather new, so expect minor problems. " \
+ "As an advantage this backend should reduce the CPU load " \
+ "and should not access the harddisc while gathering " \
+ "information." ) },
+ { QString::null, QString::null }
+};
+
+#endif // KCMREGISTRY_H
diff --git a/src/knemod/backends/nettoolsbackend.cpp b/src/knemod/backends/nettoolsbackend.cpp
new file mode 100644
index 0000000..dca42e1
--- /dev/null
+++ b/src/knemod/backends/nettoolsbackend.cpp
@@ -0,0 +1,498 @@
+/* This file is part of KNemo
+ Copyright (C) 2004, 2006 Percy Leonhardt <[email protected]>
+
+ KNemo is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of
+ the License, or (at your option) any later version.
+
+ KNemo 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 Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <qmap.h>
+#include <qregexp.h>
+#include <qstringlist.h>
+
+#include <kdebug.h>
+#include <kprocess.h>
+#include <kio/global.h>
+
+#include "nettoolsbackend.h"
+
+#include "config.h"
+
+NetToolsBackend::NetToolsBackend( QDict<Interface>& interfaces )
+ : QObject(),
+ BackendBase( interfaces ),
+ mRouteProcess(0L),
+ mIfconfigProcess(0L),
+ mIwconfigProcess(0L)
+{
+}
+
+NetToolsBackend::~NetToolsBackend()
+{
+ if ( mRouteProcess )
+ {
+ mRouteProcess->kill();
+ delete mRouteProcess;
+ }
+ if ( mIfconfigProcess )
+ {
+ mIfconfigProcess->kill();
+ delete mIfconfigProcess;
+ }
+ if ( mIwconfigProcess )
+ {
+ mIwconfigProcess->kill();
+ delete mIwconfigProcess;
+ }
+}
+
+BackendBase* NetToolsBackend::createInstance( QDict<Interface>& interfaces )
+{
+ return new NetToolsBackend( interfaces );
+}
+
+void NetToolsBackend::update()
+{
+ if ( !mIfconfigProcess )
+ {
+ mIfconfigStdout = QString::null;
+ mIfconfigProcess = new KProcess();
+ mIfconfigProcess->setEnvironment( "LANG", "C" );
+ mIfconfigProcess->setEnvironment( "LC_ALL", "C" );
+ *mIfconfigProcess << PATH_IFCONFIG << "-a";
+ connect( mIfconfigProcess, SIGNAL( receivedStdout( KProcess*, char*, int ) ),
+ this, SLOT( ifconfigProcessStdout( KProcess*, char*, int ) ) );
+ connect( mIfconfigProcess, SIGNAL( processExited( KProcess* ) ),
+ this, SLOT( ifconfigProcessExited( KProcess* ) ) );
+
+ if ( !mIfconfigProcess->start( KProcess::NotifyOnExit, KProcess::Stdout ) )
+ {
+ delete mIfconfigProcess;
+ mIfconfigProcess = 0L;
+ }
+ }
+
+#ifdef PATH_IWCONFIG
+ if ( !mIwconfigProcess )
+ {
+ mIwconfigStdout = QString::null;
+ mIwconfigProcess = new KProcess();
+ mIwconfigProcess->setEnvironment( "LANG", "C" );
+ mIwconfigProcess->setEnvironment( "LC_ALL", "C" );
+ *mIwconfigProcess << PATH_IWCONFIG;
+ connect( mIwconfigProcess, SIGNAL( receivedStdout( KProcess*, char*, int ) ),
+ this, SLOT( iwconfigProcessStdout( KProcess*, char*, int ) ) );
+ connect( mIwconfigProcess, SIGNAL( receivedStderr( KProcess*, char*, int ) ),
+ this, SLOT( iwconfigProcessStdout( KProcess*, char*, int ) ) );
+ connect( mIwconfigProcess, SIGNAL( processExited( KProcess* ) ),
+ this, SLOT( iwconfigProcessExited( KProcess* ) ) );
+
+ if ( !mIwconfigProcess->start( KProcess::NotifyOnExit, KProcess::AllOutput ) )
+ {
+ delete mIwconfigProcess;
+ mIwconfigProcess = 0L;
+ }
+ }
+#endif
+
+#ifdef PATH_ROUTE
+ if ( !mRouteProcess )
+ {
+ mRouteStdout = QString::null;
+ mRouteProcess = new KProcess();
+ mRouteProcess->setEnvironment( "LANG", "C" );
+ mRouteProcess->setEnvironment( "LC_ALL", "C" );
+ *mRouteProcess << PATH_ROUTE << "-n";
+ connect( mRouteProcess, SIGNAL( receivedStdout( KProcess*, char*, int ) ),
+ this, SLOT( routeProcessStdout( KProcess*, char*, int ) ) );
+ connect( mRouteProcess, SIGNAL( receivedStderr( KProcess*, char*, int ) ),
+ this, SLOT( routeProcessStdout( KProcess*, char*, int ) ) );
+ connect( mRouteProcess, SIGNAL( processExited( KProcess* ) ),
+ this, SLOT( routeProcessExited( KProcess* ) ) );
+
+ if ( !mRouteProcess->start( KProcess::NotifyOnExit, KProcess::AllOutput ) )
+ {
+ delete mRouteProcess;
+ mRouteProcess = 0L;
+ }
+ }
+#endif
+}
+
+void NetToolsBackend::routeProcessExited( KProcess* process )
+{
+ if ( process == mRouteProcess )
+ {
+ mRouteProcess->deleteLater(); // we're in a slot connected to mRouteProcess
+ mRouteProcess = 0L;
+ parseRouteOutput();
+ }
+}
+
+void NetToolsBackend::routeProcessStdout( KProcess*, char* buffer, int buflen )
+{
+ mRouteStdout += QString::fromLatin1( buffer, buflen );
+}
+
+void NetToolsBackend::ifconfigProcessExited( KProcess* process )
+{
+ if ( process == mIfconfigProcess )
+ {
+ delete mIfconfigProcess;
+ mIfconfigProcess = 0L;
+ parseIfconfigOutput();
+ }
+}
+
+void NetToolsBackend::ifconfigProcessStdout( KProcess*, char* buffer, int buflen )
+{
+ mIfconfigStdout += QString::fromLatin1( buffer, buflen );
+}
+
+void NetToolsBackend::iwconfigProcessExited( KProcess* process )
+{
+ if ( process == mIwconfigProcess )
+ {
+ delete mIwconfigProcess;
+ mIwconfigProcess = 0L;
+ parseIwconfigOutput();
+ }
+}
+
+void NetToolsBackend::iwconfigProcessStdout( KProcess*, char* buffer, int buflen )
+{
+ mIwconfigStdout += QString::fromLatin1( buffer, buflen );
+}
+
+void NetToolsBackend::parseIfconfigOutput()
+{
+ /* mIfconfigStdout contains the complete output of 'ifconfig' which we
+ * are going to parse here.
+ */
+ QMap<QString, QString> configs;
+ QStringList ifList = QStringList::split( "\n\n", mIfconfigStdout );
+ QStringList::Iterator it;
+ for ( it = ifList.begin(); it != ifList.end(); ++it )
+ {
+ int index = ( *it ).find( ' ' );
+ if ( index == -1 )
+ continue;
+ QString key = ( *it ).left( index );
+ configs[key] = ( *it ).mid( index );
+ }
+
+ /* We loop over the interfaces the user wishs to monitor.
+ * If we find the interface in the output of 'ifconfig'
+ * we update its data, otherwise we mark it as
+ * 'not existing'.
+ */
+ QDictIterator<Interface> ifIt( mInterfaces );
+ for ( ; ifIt.current(); ++ifIt )
+ {
+ QString key = ifIt.currentKey();
+ Interface* interface = ifIt.current();
+
+ if ( configs.find( key ) == configs.end() )
+ {
+ // The interface does not exist. Meaning the driver
+ // isn't loaded and/or the interface has not been created.
+ interface->getData().existing = false;
+ interface->getData().available = false;
+ }
+ // JJ 2005-07-18: use RUNNING instead of UP to detect whether interface is connected
+ else if ( !configs[key].contains( "inet " ) ||
+ !configs[key].contains( "RUNNING" ) )
+ {
+ // The interface is up or has an IP assigned but not both
+ interface->getData().existing = true;
+ interface->getData().available = false;
+ }
+ else
+ {
+ // ...determine the type of the interface
+ if ( configs[key].contains( "Ethernet" ) )
+ interface->setType( Interface::ETHERNET );
+ else
+ interface->setType( Interface::PPP );
+
+ // Update the interface.
+ interface->getData().existing = true;
+ interface->getData().available = true;
+ updateInterfaceData( configs[key], interface->getData(), interface->getType() );
+ }
+ }
+ updateComplete();
+}
+
+void NetToolsBackend::updateInterfaceData( QString& config, InterfaceData& data, int type )
+{
+ QRegExp regExp( ".*RX.*:(\\d+).*:\\d+.*:\\d+.*:\\d+" );
+ if ( regExp.search( config ) > -1 )
+ data.rxPackets = regExp.cap( 1 ).toULong();
+
+ regExp.setPattern( ".*TX.*:(\\d+).*:\\d+.*:\\d+.*:\\d+" );
+ if ( regExp.search( config ) > -1 )
+ data.txPackets = regExp.cap( 1 ).toULong();
+
+ regExp.setPattern( "RX bytes:(\\d+)\\s*\\(\\d+\\.\\d+\\s*\\w+\\)" );
+ if ( regExp.search( config ) > -1 )
+ {
+ // We count the traffic on ourself to avoid an overflow after
+ // 4GB of traffic.
+ unsigned long currentRxBytes = regExp.cap( 1 ).toULong();
+ if ( currentRxBytes < data.prevRxBytes )
+ {
+ // there was an overflow
+ if ( type == Interface::ETHERNET )
+ {
+ // This makes data counting more accurate but will not work
+ // for interfaces that reset the transfered data to zero
+ // when deactivated like ppp does.
+ data.rxBytes += 0xFFFFFFFF - data.prevRxBytes;
+ }
+ data.prevRxBytes = 0L;
+ }
+ if ( data.rxBytes == 0L )
+ {
+ // on startup set to currently received bytes
+ data.rxBytes = currentRxBytes;
+ // this is new: KNemo only counts the traffic transfered
+ // while it is running. Important to not falsify statistics!
+ data.prevRxBytes = currentRxBytes;
+ }
+ else
+ // afterwards only add difference to previous number of bytes
+ data.rxBytes += currentRxBytes - data.prevRxBytes;
+
+ data.incomingBytes = currentRxBytes - data.prevRxBytes;
+ data.prevRxBytes = currentRxBytes;
+ data.rxString = KIO::convertSize( data.rxBytes );
+ }
+
+ regExp.setPattern( "TX bytes:(\\d+)\\s*\\(\\d+\\.\\d+\\s*\\w+\\)" );
+ if ( regExp.search( config ) > -1 )
+ {
+ // We count the traffic on ourself to avoid an overflow after
+ // 4GB of traffic.
+ unsigned long currentTxBytes = regExp.cap( 1 ).toULong();
+ if ( currentTxBytes < data.prevTxBytes )
+ {
+ // there was an overflow
+ if ( type == Interface::ETHERNET )
+ {
+ // This makes data counting more accurate but will not work
+ // for interfaces that reset the transfered data to zero
+ // when deactivated like ppp does.
+ data.txBytes += 0xFFFFFFFF - data.prevTxBytes;
+ }
+ data.prevTxBytes = 0L;
+ }
+ if ( data.txBytes == 0L )
+ {
+ // on startup set to currently transmitted bytes
+ data.txBytes = currentTxBytes;
+ // this is new: KNemo only counts the traffic transfered
+ // while it is running. Important to not falsify statistics!
+ data.prevTxBytes = currentTxBytes;
+ }
+ else
+ // afterwards only add difference to previous number of bytes
+ data.txBytes += currentTxBytes - data.prevTxBytes;
+
+ data.outgoingBytes = currentTxBytes - data.prevTxBytes;
+ data.prevTxBytes = currentTxBytes;
+ data.txString = KIO::convertSize( data.txBytes );
+ }
+
+ regExp.setPattern( "inet\\s+\\w+:(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})" );
+ if ( regExp.search( config ) > -1 )
+ data.ipAddress = regExp.cap( 1 );
+
+ regExp.setPattern( "(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}).*(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}).*(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})" );
+ if ( regExp.search( config ) > -1 )
+ {
+ data.broadcastAddress = regExp.cap( 2 );
+ data.subnetMask = regExp.cap( 3 );
+ }
+
+ if ( type == Interface::ETHERNET )
+ {
+ regExp.setPattern( "(.{2}:.{2}:.{2}:.{2}:.{2}:.{2})" );
+ if ( regExp.search( config ) > -1 )
+ data.hwAddress = regExp.cap( 1 );
+ }
+ else if ( type == Interface::PPP )
+ {
+ regExp.setPattern( "(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}).*(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}).*(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})" );
+ if ( regExp.search( config ) > -1 )
+ data.ptpAddress = regExp.cap( 2 );
+ }
+}
+
+void NetToolsBackend::parseIwconfigOutput()
+{
+ /* mIwconfigStdout contains the complete output of 'iwconfig' which we
+ * are going to parse here.
+ */
+ QMap<QString, QString> configs;
+ QStringList ifList = QStringList::split( "\n\n", mIwconfigStdout );
+ QStringList::Iterator it;
+ for ( it = ifList.begin(); it != ifList.end(); ++it )
+ {
+ int index = ( *it ).find( ' ' );
+ if ( index == -1 )
+ continue;
+ QString key = ( *it ).left( index );
+ configs[key] = ( *it ).mid( index );
+ }
+
+ /* We loop over the interfaces the user wishs to monitor.
+ * If we find the interface in the output of 'iwconfig'
+ * we update its data.
+ */
+ QDictIterator<Interface> ifIt( mInterfaces );
+ for ( ; ifIt.current(); ++ifIt )
+ {
+ QString key = ifIt.currentKey();
+ Interface* interface = ifIt.current();
+
+ if ( configs.find( key ) == configs.end() )
+ {
+ // The interface was not found.
+ continue;
+ }
+ else if ( configs[key].contains( "no wireless extensions" ) )
+ {
+ // The interface isn't a wireless device.
+ interface->getData().wirelessDevice = false;
+ }
+ else
+ {
+ // Update the wireless data of the interface.
+ interface->getData().wirelessDevice = true;
+ updateWirelessData( configs[key], interface->getWirelessData() );
+ }
+ }
+}
+
+void NetToolsBackend::updateWirelessData( QString& config, WirelessData& data )
+{
+ QRegExp regExp( "ESSID:([^\"][\\S]*)" );
+ if ( regExp.search( config ) > -1 )
+ data.essid = regExp.cap( 1 );
+ else
+ {
+ regExp.setPattern( "ESSID:\"([^\"]*)" );
+ if ( regExp.search( config ) > -1 )
+ data.essid = regExp.cap( 1 );
+ else
+ data.essid = QString::null;
+ }
+
+ regExp.setPattern( "Mode:(\\w*)" );
+ if ( regExp.search( config ) > -1 )
+ data.mode = regExp.cap( 1 );
+
+ regExp.setPattern( "Frequency:([\\w|\\.]*\\s*\\w*)" );
+ if ( regExp.search( config ) > -1 )
+ {
+ data.frequency = regExp.cap( 1 );
+ data.channel = "-";
+ }
+ else
+ {
+ data.frequency = "-";
+ regExp.setPattern( "Channel:(\\d*)" );
+ if ( regExp.search( config ) > -1 )
+ data.channel = regExp.cap( 1 );
+ else
+ data.channel = "-";
+ }
+
+ regExp.setPattern( "Bit Rate[=:](\\d*\\s*[\\w/]*)" );
+ if ( regExp.search( config ) > -1 )
+ data.bitRate = regExp.cap( 1 );
+
+ regExp.setPattern( "(.{2}:.{2}:.{2}:.{2}:.{2}:.{2})" );
+ if ( regExp.search( config ) > -1 )
+ data.accessPoint = regExp.cap( 1 );
+
+ regExp.setPattern( "Nickname:\"(\\w*)\"" );
+ if ( regExp.search( config ) > -1 )
+ data.nickName = regExp.cap( 1 );
+
+ regExp.setPattern( "Link Quality[=:]([\\d]*)" );
+ if ( regExp.search( config ) > -1 )
+ data.linkQuality = regExp.cap( 1 );
+
+ regExp.setPattern( "Encryption key:" );
+ if ( regExp.search( config ) > -1 )
+ {
+ regExp.setPattern( "Encryption key:off" );
+ if ( regExp.search( config ) > -1 )
+ {
+ data.encryption = false;
+ }
+ else
+ {
+ data.encryption = true;
+ }
+ }
+ else
+ {
+ data.encryption = false;
+ }
+}
+
+void NetToolsBackend::parseRouteOutput()
+{
+ /* mRouteStdout contains the complete output of 'route' which we
+ * are going to parse here.
+ */
+ QMap<QString, QStringList> configs;
+ QStringList routeList = QStringList::split( "\n", mRouteStdout );
+ QStringList::Iterator it;
+ for ( it = routeList.begin(); it != routeList.end(); ++it )
+ {
+ QStringList routeParameter = QStringList::split( " ", *it );
+ if ( routeParameter.count() < 8 ) // no routing entry
+ continue;
+ if ( routeParameter[0] != "0.0.0.0" ) // no default route
+ continue;
+ configs[routeParameter[7]] = routeParameter;
+ }
+
+ /* We loop over the interfaces the user wishs to monitor.
+ * If we find the interface in the output of 'route' we update
+ * the data of the interface.
+ */
+ QDictIterator<Interface> ifIt( mInterfaces );
+ for ( ; ifIt.current(); ++ifIt )
+ {
+ QString key = ifIt.currentKey();
+ Interface* interface = ifIt.current();
+
+ if ( configs.find( key ) != configs.end() )
+ {
+ // Update the default gateway.
+ QStringList routeParameter = configs[key];
+ interface->getData().defaultGateway = routeParameter[1];
+ }
+ else
+ {
+ // Reset the default gateway.
+ interface->getData().defaultGateway = QString::null;
+ }
+ }
+}
diff --git a/src/knemod/backends/nettoolsbackend.h b/src/knemod/backends/nettoolsbackend.h
new file mode 100644
index 0000000..788938c
--- /dev/null
+++ b/src/knemod/backends/nettoolsbackend.h
@@ -0,0 +1,72 @@
+/* This file is part of KNemo
+ Copyright (C) 2004 Percy Leonhardt <[email protected]>
+
+ KNemo is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of
+ the License, or (at your option) any later version.
+
+ KNemo 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 Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef NETTOOLSBACKEND_H
+#define NETTOOLSBACKEND_H
+
+#include <qobject.h>
+
+#include "backendbase.h"
+
+class KProcess;
+
+/**
+ * The nettools backend runs 'ifconfig', 'iwconfig' and 'route'
+ * and parses their output. It then triggers the interface
+ * monitor to look for changes in the state of the interface.
+ *
+ * @short Update the information of the interfaces via nettools
+ * @author Percy Leonhardt <[email protected]>
+ */
+
+class NetToolsBackend : public QObject, BackendBase
+{
+ Q_OBJECT
+public:
+ NetToolsBackend(QDict<Interface>& interfaces );
+ virtual ~NetToolsBackend();
+
+ static BackendBase* createInstance( QDict<Interface>& interfaces );
+
+ void update();
+
+private slots:
+ void routeProcessExited( KProcess* process );
+ void routeProcessStdout( KProcess* process, char* buffer, int buflen );
+ void ifconfigProcessExited( KProcess* process );
+ void ifconfigProcessStdout( KProcess* process, char* buffer, int buflen );
+ void iwconfigProcessExited( KProcess* process );
+ void iwconfigProcessStdout( KProcess* process, char* buffer, int buflen );
+
+private:
+ void parseRouteOutput();
+ void parseIfconfigOutput();
+ void updateInterfaceData( QString& config, InterfaceData& data, int type );
+ void parseIwconfigOutput();
+ void updateWirelessData( QString& config, WirelessData& data );
+
+ QString mRouteStdout;
+ QString mIfconfigStdout;
+ QString mIwconfigStdout;
+ KProcess* mRouteProcess;
+ KProcess* mIfconfigProcess;
+ KProcess* mIwconfigProcess;
+};
+
+#endif // NETTOOLSBACKEND_H
diff --git a/src/knemod/backends/sysbackend.cpp b/src/knemod/backends/sysbackend.cpp
new file mode 100644
index 0000000..2caf325
--- /dev/null
+++ b/src/knemod/backends/sysbackend.cpp
@@ -0,0 +1,428 @@
+/* This file is part of KNemo
+ Copyright (C) 2006 Percy Leonhardt <[email protected]>
+
+ KNemo is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of
+ the License, or (at your option) any later version.
+
+ KNemo 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 Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include <arpa/inet.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+#include <qmap.h>
+#include <qdir.h>
+#include <qregexp.h>
+#include <qstringlist.h>
+
+#include <kdebug.h>
+#include <kprocess.h>
+#include <kio/global.h>
+
+#include "sysbackend.h"
+
+#include "config.h"
+
+#ifdef HAVE_LIBIW
+#include <iwlib.h>
+#else
+#include <net/if.h>
+#endif
+
+#define RTF_GATEWAY 0x0002
+#define SYSPATH "/sys/class/net/"
+#define PROCROUTE "/proc/net/route"
+
+SysBackend::SysBackend( QDict<Interface>& interfaces )
+ : BackendBase( interfaces )
+{
+}
+
+SysBackend::~SysBackend()
+{
+}
+
+BackendBase* SysBackend::createInstance( QDict<Interface>& interfaces )
+{
+ return new SysBackend( interfaces );
+}
+
+void SysBackend::update()
+{
+ QDir dir( SYSPATH );
+ QStringList ifList = dir.entryList( QDir::Dirs );
+
+ QDictIterator<Interface> ifIt( mInterfaces );
+ for ( ; ifIt.current(); ++ifIt )
+ {
+ QString key = ifIt.currentKey();
+ Interface* interface = ifIt.current();
+
+ if ( ifList.find( key ) == ifList.end() )
+ {
+ // The interface does not exist. Meaning the driver
+ // isn't loaded and/or the interface has not been created.
+ interface->getData().existing = false;
+ interface->getData().available = false;
+ }
+ else
+ {
+ if ( QFile::exists( SYSPATH + key + "/wireless" ) )
+ {
+ interface->getData().wirelessDevice = true;
+ }
+
+ unsigned int carrier = 0;
+ if ( !readNumberFromFile( SYSPATH + key + "/carrier", carrier ) ||
+ carrier == 0 )
+ {
+ // The interface is there but not useable.
+ interface->getData().existing = true;
+ interface->getData().available = false;
+ }
+ else
+ {
+ // ...determine the type of the interface
+ unsigned int type = 0;
+ if ( readNumberFromFile( SYSPATH + key + "/type", type ) &&
+ type == 512 )
+ {
+ interface->setType( Interface::PPP );
+ }
+ else
+ {
+ interface->setType( Interface::ETHERNET );
+ }
+
+ // Update the interface.
+ interface->getData().existing = true;
+ interface->getData().available = true;
+ updateInterfaceData( key, interface->getData(), interface->getType() );
+
+ if ( interface->getData().wirelessDevice == true )
+ {
+ updateWirelessData( key, interface->getWirelessData() );
+ }
+ }
+ }
+ }
+ updateComplete();
+}
+
+bool SysBackend::readNumberFromFile( const QString& fileName, unsigned int& value )
+{
+ FILE* file = fopen( fileName.latin1(), "r" );
+ if ( file != NULL )
+ {
+ if ( fscanf( file, "%ul", &value ) > 0 )
+ {
+ fclose( file );
+ return true;
+ }
+ fclose( file );
+ }
+
+ return false;
+}
+
+bool SysBackend::readStringFromFile( const QString& fileName, QString& string )
+{
+ char buffer[64];
+ FILE* file = fopen( fileName.latin1(), "r" );
+ if ( file != NULL )
+ {
+ if ( fscanf( file, "%s", buffer ) > 0 )
+ {
+ fclose( file );
+ string = buffer;
+ return true;
+ }
+ fclose( file );
+ }
+
+ return false;
+}
+
+void SysBackend::updateInterfaceData( const QString& ifName, InterfaceData& data, int type )
+{
+ QString ifFolder = SYSPATH + ifName + "/";
+
+ unsigned int rxPackets = 0;
+ if ( readNumberFromFile( ifFolder + "statistics/rx_packets", rxPackets ) )
+ {
+ data.rxPackets = rxPackets;
+ }
+
+ unsigned int txPackets = 0;
+ if ( readNumberFromFile( ifFolder + "statistics/tx_packets", txPackets ) )
+ {
+ data.txPackets = txPackets;
+ }
+
+ unsigned int rxBytes = 0;
+ if ( readNumberFromFile( ifFolder + "statistics/rx_bytes", rxBytes ) )
+ {
+ // We count the traffic on ourself to avoid an overflow after
+ // 4GB of traffic.
+ if ( rxBytes < data.prevRxBytes )
+ {
+ // there was an overflow
+ if ( type == Interface::ETHERNET )
+ {
+ // This makes data counting more accurate but will not work
+ // for interfaces that reset the transfered data to zero
+ // when deactivated like ppp does.
+ data.rxBytes += 0xFFFFFFFF - data.prevRxBytes;
+ }
+ data.prevRxBytes = 0L;
+ }
+ if ( data.rxBytes == 0L )
+ {
+ // on startup set to currently received bytes
+ data.rxBytes = rxBytes;
+ // this is new: KNemo only counts the traffic transfered
+ // while it is running. Important to not falsify statistics!
+ data.prevRxBytes = rxBytes;
+ }
+ else
+ // afterwards only add difference to previous number of bytes
+ data.rxBytes += rxBytes - data.prevRxBytes;
+
+ data.incomingBytes = rxBytes - data.prevRxBytes;
+ data.prevRxBytes = rxBytes;
+ data.rxString = KIO::convertSize( data.rxBytes );
+ }
+
+ unsigned int txBytes = 0;
+ if ( readNumberFromFile( ifFolder + "statistics/tx_bytes", txBytes ) )
+ {
+ // We count the traffic on ourself to avoid an overflow after
+ // 4GB of traffic.
+ if ( txBytes < data.prevTxBytes )
+ {
+ // there was an overflow
+ if ( type == Interface::ETHERNET )
+ {
+ // This makes data counting more accurate but will not work
+ // for interfaces that reset the transfered data to zero
+ // when deactivated like ppp does.
+ data.txBytes += 0xFFFFFFFF - data.prevTxBytes;
+ }
+ data.prevTxBytes = 0L;
+ }
+ if ( data.txBytes == 0L )
+ {
+ // on startup set to currently received bytes
+ data.txBytes = txBytes;
+ // this is new: KNemo only counts the traffic transfered
+ // while it is running. Important to not falsify statistics!
+ data.prevTxBytes = txBytes;
+ }
+ else
+ // afterwards only add difference to previous number of bytes
+ data.txBytes += txBytes - data.prevTxBytes;
+
+ data.outgoingBytes = txBytes - data.prevTxBytes;
+ data.prevTxBytes = txBytes;
+ data.txString = KIO::convertSize( data.txBytes );
+ }
+
+ if ( type == Interface::ETHERNET )
+ {
+ QString hwAddress;
+ if ( readStringFromFile( ifFolder + "address", hwAddress ) )
+ {
+ data.hwAddress = hwAddress;
+ }
+
+ // for the default gateway we use the proc filesystem
+ QFile routeFile( PROCROUTE );
+ if ( routeFile.open( IO_ReadOnly ) )
+ {
+ QString routeData( routeFile.readAll().data() );
+ QStringList routeEntries = QStringList::split( "\n", routeData );
+ QStringList::Iterator it;
+ for ( it = routeEntries.begin(); it != routeEntries.end(); ++it )
+ {
+ QRegExp regExp( ".*\\s+[\\w\\d]{8}\\s+([\\w\\d]{8})\\s+(\\d{4})" );
+ if ( ( regExp.search( *it ) > -1 )
+ && ( regExp.cap( 2 ).toUInt() & RTF_GATEWAY ) )
+ {
+ bool ok;
+ struct in_addr in;
+ in.s_addr = regExp.cap( 1 ).toULong( &ok, 16 );
+ data.defaultGateway = inet_ntoa( in );
+ break;
+ }
+ }
+ routeFile.close();
+ }
+
+ }
+
+ // use ioctls for the rest
+ int fd;
+ struct ifreq ifr;
+ if ( ( fd = socket(AF_INET, SOCK_DGRAM, 0) ) > -1 )
+ {
+ strcpy( ifr.ifr_name, ifName.latin1() );
+ ifr.ifr_addr.sa_family = AF_INET;
+ if ( ioctl( fd, SIOCGIFADDR, &ifr ) > -1 )
+ {
+ data.ipAddress = inet_ntoa(((struct sockaddr_in*)&ifr.ifr_addr)->sin_addr);
+ }
+ if ( ioctl( fd, SIOCGIFDSTADDR, &ifr) > -1 )
+ {
+ data.ptpAddress = inet_ntoa(((struct sockaddr_in*)&ifr.ifr_dstaddr)->sin_addr);
+ }
+
+ if ( ioctl( fd, SIOCGIFBRDADDR, &ifr ) > -1 )
+ {
+ data.broadcastAddress = inet_ntoa(((struct sockaddr_in*)&ifr.ifr_broadaddr)->sin_addr);
+ }
+
+ if ( ioctl( fd, SIOCGIFNETMASK, &ifr ) > -1 )
+ {
+ data.subnetMask = inet_ntoa(((struct sockaddr_in*)&ifr.ifr_netmask)->sin_addr);
+ }
+ close( fd );
+ }
+}
+
+void SysBackend::updateWirelessData( const QString& ifName, WirelessData& data )
+{
+ QString wirelessFolder = SYSPATH + ifName + "/wireless/";
+
+ unsigned int link = 0;
+ if ( readNumberFromFile( wirelessFolder + "link", link ) )
+ {
+ data.linkQuality = QString::number( link );
+ }
+
+#ifdef HAVE_LIBIW
+ // The following code was taken from iwconfig.c and iwlib.c.
+ int fd;
+ if ( ( fd = iw_sockets_open() ) > 0 )
+ {
+ struct iwreq wrq;
+ char buffer[128];
+ if ( iw_get_ext( fd, ifName.latin1(), SIOCGIWFREQ, &wrq ) >= 0 )
+ {
+ int channel = -1;
+ double freq = iw_freq2float( &( wrq.u.freq ) );
+ struct iw_range range;
+ if( iw_get_range_info( fd, ifName.latin1(), &range ) >= 0 )
+ {
+ if ( freq < KILO )
+ {
+ channel = iw_channel_to_freq( (int) freq, &freq, &range );
+ }
+ else
+ {
+ channel = iw_freq_to_channel( freq, &range );
+ }
+ iw_print_freq_value( buffer, sizeof( buffer ), freq );
+ data.frequency = buffer;
+ data.channel = QString::number( channel );
+ }
+ }
+
+ char essid[IW_ESSID_MAX_SIZE + 1];
+ memset( essid, 0, IW_ESSID_MAX_SIZE + 1 );
+ wrq.u.essid.pointer = (caddr_t) essid;
+ wrq.u.essid.length = IW_ESSID_MAX_SIZE + 1;
+ wrq.u.essid.flags = 0;
+ if ( iw_get_ext( fd, ifName.latin1(), SIOCGIWESSID, &wrq ) >= 0 )
+ {
+ if ( wrq.u.data.flags > 0 )
+ {
+ data.essid = essid;
+ }
+ else
+ {
+ data.essid = "any";
+ }
+ }
+
+ if ( iw_get_ext( fd, ifName.latin1(), SIOCGIWAP, &wrq ) >= 0 )
+ {
+ char ap_addr[128];
+ iw_ether_ntop( (const ether_addr*) wrq.u.ap_addr.sa_data, ap_addr);
+ data.accessPoint = ap_addr;
+ }
+
+ memset( essid, 0, IW_ESSID_MAX_SIZE + 1 );
+ wrq.u.essid.pointer = (caddr_t) essid;
+ wrq.u.essid.length = IW_ESSID_MAX_SIZE + 1;
+ wrq.u.essid.flags = 0;
+ if ( iw_get_ext( fd, ifName.latin1(), SIOCGIWNICKN, &wrq ) >= 0 )
+ {
+ if ( wrq.u.data.length > 1 )
+ {
+ data.nickName = essid;
+ }
+ else
+ {
+ data.nickName = QString::null;
+ }
+ }
+
+ if ( iw_get_ext( fd, ifName.latin1(), SIOCGIWRATE, &wrq ) >= 0 )
+ {
+ iwparam bitrate;
+ memcpy (&(bitrate), &(wrq.u.bitrate), sizeof (iwparam));
+ iw_print_bitrate( buffer, sizeof( buffer ), wrq.u.bitrate.value );
+ data.bitRate = buffer;
+ }
+
+ if ( iw_get_ext( fd, ifName.latin1(), SIOCGIWMODE, &wrq ) >= 0 )
+ {
+ int mode = wrq.u.mode;
+ if ( mode < IW_NUM_OPER_MODE && mode >= 0 )
+ {
+ data.mode = iw_operation_mode[mode];
+ }
+ else
+ {
+ data.mode = QString::null;
+ }
+ }
+
+ unsigned char key[IW_ENCODING_TOKEN_MAX];
+ wrq.u.data.pointer = (caddr_t) key;
+ wrq.u.data.length = IW_ENCODING_TOKEN_MAX;
+ wrq.u.data.flags = 0;
+ if ( iw_get_ext( fd, ifName.latin1(), SIOCGIWENCODE, &wrq ) >= 0 )
+ {
+ if ( ( wrq.u.data.flags & IW_ENCODE_DISABLED ) || ( wrq.u.data.length == 0 ) )
+ {
+ data.encryption = false;
+ }
+ else
+ {
+ data.encryption = true;
+ }
+ }
+ else
+ {
+ data.encryption = false;
+ }
+ close( fd );
+ }
+#endif
+}
+
diff --git a/src/knemod/backends/sysbackend.h b/src/knemod/backends/sysbackend.h
new file mode 100644
index 0000000..10650b6
--- /dev/null
+++ b/src/knemod/backends/sysbackend.h
@@ -0,0 +1,54 @@
+/* This file is part of KNemo
+ Copyright (C) 2006 Percy Leonhardt <[email protected]>
+
+ KNemo is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of
+ the License, or (at your option) any later version.
+
+ KNemo 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 Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef SYSBACKEND_H
+#define SYSBACKEND_H
+
+#include "backendbase.h"
+
+/**
+ * The sys backend uses the sys filesystem available in 2.6
+ * kernels. It reads all necessary information from the files
+ * and folders located at /sys and parses their output.
+ * It then triggers the interface monitor to look for changes
+ * in the state of the interface.
+ *
+ * @short Update the information of the interfaces via sys filesystem
+ * @author Percy Leonhardt <[email protected]>
+ */
+
+class SysBackend : public BackendBase
+{
+public:
+ SysBackend(QDict<Interface>& interfaces );
+ virtual ~SysBackend();
+
+ static BackendBase* createInstance( QDict<Interface>& interfaces );
+
+ void update();
+
+private:
+ bool readNumberFromFile( const QString& fileName, unsigned int& value );
+ bool readStringFromFile( const QString& fileName, QString& string );
+ void updateWirelessData( const QString& ifName, WirelessData& data );
+ void updateInterfaceData( const QString& ifName, InterfaceData& data, int type );
+
+};
+
+#endif // SYSBACKEND_H
diff --git a/src/knemod/eventsrc b/src/knemod/eventsrc
new file mode 100644
index 0000000..13f8aff
--- /dev/null
+++ b/src/knemod/eventsrc
@@ -0,0 +1,220 @@
+[!Global!]
+IconName=knemo
+Comment=KDE Network Monitor
+Comment[bg]=Монитор на мрежата
+Comment[br]=Eveshaer ar rouedad evit KDE
+Comment[cs]=KDE monitor sítě
+Comment[da]=KDE's netværksovervågning
+Comment[de]=KDE-Netzwerkmonitor
+Comment[el]=Επίβλεψη δικτύου του KDE
+Comment[es]=Monitor de red de KDE
+Comment[et]=KDE võrgumonitor
+Comment[ga]=Monatóir Líonra KDE
+Comment[gl]=Un Monitor de Rede para KDE
+Comment[it]=Monitor di rete di KDE
+Comment[ja]=KDE ネットワークモニタ
+Comment[ka]=KDE-ის ქსელის მონიტორი
+Comment[lt]=Tinklo įrenginių stebėjimo KDE programa
+Comment[nl]=KDE networkmonitor
+Comment[pa]=KDE ਨੈਟਵਰਕ ਨਿਗਰਾਨ
+Comment[pl]=Monitor sieci dla KDE
+Comment[pt]=Monitor da Rede do KDE
+Comment[pt_BR]=Monitor de Rede do KDE
+Comment[ru]=Сетевой монитор KDE
+Comment[sr]=Надгледање мреже за KDE
+Comment[sr@Latn]=Nadgledanje mreže za KDE
+Comment[sv]=KDE-nätverksövervakning
+Comment[tr]=KDE Ağ İzleyici
+Comment[uk]=Монітор мережі для KDE
+Comment[xx]=xxKDE Network Monitorxx
+Comment[zh_CN]=KDE 网络监视器
+
+[knemo_connected]
+Name=Connected
+Name[bg]=Активно
+Name[br]=Kevreet
+Name[ca]=Connectat
+Name[cs]=Připojen
+Name[cy]=Wedi cysylltu
+Name[da]=Forbundet
+Name[de]=Verbunden
+Name[el]=Συνδέθηκε
+Name[es]=Conectado
+Name[et]=Ühendatud
+Name[fr]=Connecté
+Name[ga]=Nasctha
+Name[gl]=Conectado
+Name[hi]=कनेक्टेड
+Name[it]=Connesso
+Name[ja]=接続
+Name[ka]=დაკავშირებულია
+Name[lt]=Prijungta
+Name[nl]=Verbonden
+Name[pa]=ਜੁੜਿਆ
+Name[pl]=Podłączony
+Name[pt]=Ligado
+Name[pt_BR]=Conectado
+Name[ru]=Соединено
+Name[sr]=Повезан
+Name[sr@Latn]=Povezan
+Name[sv]=Uppkopplat
+Name[ta]=இணைக்கப்பட்டது
+Name[tr]=Bağlı
+Name[uk]=З'єднано
+Name[xx]=xxConnectedxx
+Name[zh_CN]=已连接
+Comment=Interface is connected
+Comment[bg]=Интерфейсът е активен
+Comment[br]=Kevreet eo an etrefas
+Comment[cs]=Rozhraní je připojeno
+Comment[da]=Grænseflade er forbundet
+Comment[de]=Die Schnittstelle ist verbunden
+Comment[el]=Η διασύνδεση είναι συνδεδεμένη
+Comment[es]=La interfaz está conectada
+Comment[et]=Liides on ühendatud
+Comment[ga]=Tá an comhéadan nasctha
+Comment[gl]=A interface está conectada
+Comment[it]=L'interfaccia è connessa
+Comment[ja]=インターフェースが接続されました
+Comment[ka]=ინტერფეისი დაკავშირებულია
+Comment[lt]=Įrenginys prijungtas
+Comment[nl]=Interface is verbonden
+Comment[pa]=ਇੰਟਰਫੇਸ ਜੁੜਿਆ ਹੈ
+Comment[pl]=Interfejs jest podłączony
+Comment[pt]=A interface foi ligada
+Comment[pt_BR]=A interface está conectada
+Comment[ru]=Интерфейс подключен
+Comment[sr]=Интерфејс је повезан
+Comment[sr@Latn]=Interfejs je povezan
+Comment[sv]=Gränssnittet är uppkopplat
+Comment[tr]=Arayüz bağlandı
+Comment[uk]=Інтерфейс з'єднано
+Comment[xx]=xxInterface is connectedxx
+Comment[zh_CN]=接口已连接
+default_sound=KDE_Dialog_Appear.wav
+default_presentation=17
+
+[knemo_disconnected]
+Name=Disconnected
+Name[bg]=Неактивен
+Name[br]=Digevreet
+Name[ca]=Desconnectat
+Name[cs]=Odpojen
+Name[cy]=Datgysylltwyd
+Name[da]=Afbrudt
+Name[de]=Getrennt
+Name[el]=Αποσυνδέθηκε
+Name[es]=Desconectado
+Name[et]=Lahutatud
+Name[fr]=Déconnecté
+Name[ga]=Dínasctha
+Name[gl]=Desconectada
+Name[hi]=डिस्कनेक्टेड
+Name[it]=Disconnesso
+Name[ja]=切断
+Name[ka]=კავშირი გაწყვეტილია
+Name[lt]=Atjungta
+Name[nl]=Niet verbonden
+Name[pa]=ਜੁੜਿਆ ਨਹੀਂ
+Name[pl]=Rozłączony
+Name[pt]=Desligado
+Name[pt_BR]=Desconectado
+Name[ru]=Отключено
+Name[sr]=Неповезан
+Name[sr@Latn]=Nepovezan
+Name[sv]=Nerkopplat
+Name[ta]=துண்டிக்கப்பட்டது
+Name[tr]=Bağlantı kesildi
+Name[uk]=Роз'єднано
+Name[xx]=xxDisconnectedxx
+Name[zh_CN]=已断开
+Comment=Interface is disconnected
+Comment[bg]=Интерфейсът е неактивен
+Comment[br]=Digevreet eo an etrefas
+Comment[cs]=Rozhraní je odpojeno
+Comment[da]=Grænseflade er afbrudt
+Comment[de]=Die Schnittstelle ist nicht verbunden
+Comment[el]=Η διασύνδεση αποσυνδέθηκε
+Comment[es]=La interfaz está desconectada
+Comment[et]=Liides on lahutatud
+Comment[ga]=Tá an comhéadan dínasctha
+Comment[gl]=A interface está desconectada
+Comment[it]=L'interfaccia è disconnessa
+Comment[ja]=インターフェースが切断されました
+Comment[ka]=ინტერფეისის კავშირი გაწყვეტილია
+Comment[lt]=Įrenginys atjungtas
+Comment[nl]=Interface is niet verbonden
+Comment[pa]=ਇੰਟਰਫੇਸ ਜੁੜਿਆ ਨਹੀਂ ਹੈ
+Comment[pl]=Interfejs jest rozłączony
+Comment[pt]=A interface foi desligada
+Comment[pt_BR]=A interface está desconectada
+Comment[ru]=Интерфейс не подключен
+Comment[sr]=Интерфејс је неповезан
+Comment[sr@Latn]=Interfejs je nepovezan
+Comment[sv]=Gränssnittet är nerkopplat
+Comment[tr]=Arayüz bağlantısı kesildi
+Comment[uk]=Інтерфейс роз'єднано
+Comment[xx]=xxInterface is disconnectedxx
+Comment[zh_CN]=接口已断开
+default_sound=KDE_Dialog_Disappear.wav
+default_presentation=17
+
+[knemo_notexisting]
+Name=Not existing
+Name[bg]=Несъществуващ
+Name[br]=N'eo ket endeo
+Name[cs]=Neexistuje
+Name[da]=Eksisterer ikke
+Name[de]=Existiert nicht
+Name[el]=Δεν υπάρχει
+Name[es]=Inexistente
+Name[et]=Pole olemas
+Name[ga]=Níl sé ann
+Name[gl]=Non existe
+Name[it]=Inesistente
+Name[ja]=存在しません
+Name[ka]=არ არსებობს
+Name[lt]=Nėra
+Name[nl]=Niet-bestaand
+Name[pa]=ਮੌਜੂਦ ਨਹੀਂ
+Name[pl]=Nie istnieje
+Name[pt]=Não existente
+Name[pt_BR]=Inexistente
+Name[ru]=Не существует
+Name[sr]=Не постоји
+Name[sr@Latn]=Ne postoji
+Name[sv]=Existerar inte
+Name[tr]=Mevcut değil
+Name[uk]=Не існує
+Name[xx]=xxNot existingxx
+Name[zh_CN]=不存在
+Comment=Interface does not exist
+Comment[bg]=Интерфейсът не съществува
+Comment[br]=N'eo ket endeo an etrefas
+Comment[cs]=Rozhraní neexistuje
+Comment[da]=Grænsefladen eksisterer ikke
+Comment[de]=Die Schnittstelle existiert nicht
+Comment[el]=Η διασύνδεση δεν υπάρχει
+Comment[es]=La interfaz no existe
+Comment[et]=Liidest pole olemas
+Comment[ga]=Níl an comhéadan ann
+Comment[gl]=A interface non existe
+Comment[it]=L'interfaccia non esiste
+Comment[ja]=インターフェースが存在しません
+Comment[ka]=ინტერფეისი არ არსებობს
+Comment[lt]=Įrenginio nėra
+Comment[nl]=De interface bestaat niet
+Comment[pa]=ਇੰਟਰਫੇਸ ਮੌਜੂਦ ਨਹੀਂ ਹੈ
+Comment[pl]=Interfejs nie istnieje
+Comment[pt]=A interface não existe
+Comment[pt_BR]=A interface não existe
+Comment[ru]=Интерфейс не существует
+Comment[sr]=Интерфејс не постоји
+Comment[sr@Latn]=Interfejs ne postoji
+Comment[sv]=Gränssnittet finns inte
+Comment[tr]=Arayüz mevcut değil
+Comment[uk]=Інтерфейсу не існує
+Comment[xx]=xxInterface does not existxx
+Comment[zh_CN]=接口不存在
+default_sound=KDE_Notify.wav
+default_presentation=0
diff --git a/src/knemod/global.h b/src/knemod/global.h
new file mode 100644
index 0000000..d00a54e
--- /dev/null
+++ b/src/knemod/global.h
@@ -0,0 +1,130 @@
+/* This file is part of KNemo
+ Copyright (C) 2005 Percy Leonhardt <[email protected]>
+
+ KNemo is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of
+ the License, or (at your option) any later version.
+
+ KNemo 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 Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef GLOBAL_H
+#define GLOBAL_H
+
+#include <qpair.h>
+#include <qcolor.h>
+#include <qstring.h>
+
+/**
+ * This file contains data structures and enums used in the knemo daemon.
+ *
+ * @short Daemon wide structures and enums
+ * @author Percy Leonhardt <[email protected]>
+ */
+
+struct GeneralData
+{
+ int toolTipContent;
+ int pollInterval;
+ int saveInterval;
+ QString statisticsDir;
+};
+
+struct InterfaceData
+{
+ InterfaceData()
+ : existing( false ),
+ available( false ),
+ wirelessDevice( false ),
+ prevRxPackets( 0L ),
+ prevTxPackets( 0L ),
+ rxPackets( 0L ),
+ txPackets( 0L ),
+ prevRxBytes( 0L ),
+ prevTxBytes( 0L ),
+ incomingBytes( 0L ),
+ outgoingBytes( 0L ),
+ rxBytes( 0L ),
+ txBytes( 0L )
+ {}
+
+ bool existing;
+ bool available;
+ bool wirelessDevice;
+ unsigned long prevRxPackets;
+ unsigned long prevTxPackets;
+ unsigned long rxPackets;
+ unsigned long txPackets;
+ unsigned long prevRxBytes;
+ unsigned long prevTxBytes;
+ unsigned long incomingBytes;
+ unsigned long outgoingBytes;
+ QString ipAddress;
+ QString subnetMask;
+ QString hwAddress;
+ QString ptpAddress;
+ QString broadcastAddress;
+ QString defaultGateway;
+ QString rxString;
+ QString txString;
+ Q_UINT64 rxBytes;
+ Q_UINT64 txBytes;
+};
+
+struct WirelessData
+{
+ QString essid;
+ QString mode;
+ QString frequency;
+ QString channel;
+ QString bitRate;
+ QString linkQuality;
+ QString accessPoint;
+ QString nickName;
+ bool encryption;
+};
+
+struct PlotterSettings
+{
+ int pixel;
+ int count;
+ int distance;
+ int fontSize;
+ int minimumValue;
+ int maximumValue;
+ bool labels;
+ bool topBar;
+ bool showIncoming;
+ bool showOutgoing;
+ bool verticalLines;
+ bool horizontalLines;
+ bool automaticDetection;
+ bool verticalLinesScroll;
+ QColor colorVLines;
+ QColor colorHLines;
+ QColor colorIncoming;
+ QColor colorOutgoing;
+ QColor colorBackground;
+};
+
+struct StatisticEntry
+{
+ int day;
+ int month;
+ int year;
+ Q_UINT64 rxBytes;
+ Q_UINT64 txBytes;
+};
+
+extern QPair<QString, int> ToolTips[];
+
+#endif // GLOBAL_H
diff --git a/src/knemod/interface.cpp b/src/knemod/interface.cpp
new file mode 100644
index 0000000..2378662
--- /dev/null
+++ b/src/knemod/interface.cpp
@@ -0,0 +1,487 @@
+/* This file is part of KNemo
+ Copyright (C) 2004, 2006 Percy Leonhardt <[email protected]>
+
+ KNemo is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of
+ the License, or (at your option) any later version.
+
+ KNemo 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 Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <qtimer.h>
+#include <qpixmap.h>
+
+#include <kwin.h>
+#include <kdebug.h>
+#include <klocale.h>
+#include <kwinmodule.h>
+#include <kiconloader.h>
+
+#include "interface.h"
+#include "signalplotter.h"
+#include "interfacestatistics.h"
+#include "interfacestatusdialog.h"
+#include "interfacestatisticsdialog.h"
+
+Interface::Interface( QString ifname,
+ const GeneralData& generalData,
+ const PlotterSettings& plotterSettings )
+ : QObject(),
+ mType( UNKNOWN_TYPE ),
+ mState( UNKNOWN_STATE ),
+ mOutgoingPos( 0 ),
+ mIncomingPos( 0 ),
+ mName( ifname ),
+ mPlotterTimer( 0 ),
+ mIcon( this ),
+ mStatistics( 0 ),
+ mStatusDialog( 0 ),
+ mStatisticsDialog( 0 ),
+ mPlotter( 0 ),
+ mVisibleBeams( NONE ),
+ mGeneralData( generalData ),
+ mPlotterSettings( plotterSettings )
+{
+ connect( &mMonitor, SIGNAL( statusChanged( int ) ),
+ &mIcon, SLOT( updateStatus( int ) ) );
+ connect( &mMonitor, SIGNAL( available( int ) ),
+ &mIcon, SLOT( updateTrayStatus( int ) ) );
+ connect( &mMonitor, SIGNAL( notAvailable( int ) ),
+ &mIcon, SLOT( updateTrayStatus( int ) ) );
+ connect( &mMonitor, SIGNAL( notExisting( int ) ),
+ &mIcon, SLOT( updateTrayStatus( int ) ) );
+ connect( &mMonitor, SIGNAL( available( int ) ),
+ this, SLOT( setStartTime( int ) ) );
+ connect( &mMonitor, SIGNAL( statusChanged( int ) ),
+ this, SLOT( resetData( int ) ) );
+ connect( &mIcon, SIGNAL( statisticsSelected() ),
+ this, SLOT( showStatisticsDialog() ) );
+}
+
+Interface::~Interface()
+{
+ if ( mStatusDialog != 0 )
+ {
+ delete mStatusDialog;
+ }
+ if ( mPlotter != 0 )
+ {
+ delete mPlotter;
+ }
+ if ( mPlotterTimer != 0 )
+ {
+ mPlotterTimer->stop();
+ delete mPlotterTimer;
+ }
+ if ( mStatistics != 0 )
+ {
+ // this will also delete a possibly open statistics dialog
+ stopStatistics();
+ }
+}
+
+void Interface::configChanged()
+{
+ // UNKNOWN_STATE to avoid notification
+ mIcon.updateTrayStatus( UNKNOWN_STATE );
+ // handle changed iconset by user
+ mIcon.updateStatus( mState );
+ mIcon.updateToolTip();
+ mIcon.updateMenu();
+
+ if ( mPlotter != 0L )
+ {
+ configurePlotter();
+ }
+
+ if ( mStatistics != 0 )
+ {
+ mStatistics->configChanged();
+ }
+
+ if ( mSettings.activateStatistics && mStatistics == 0 )
+ {
+ // user turned on statistics
+ startStatistics();
+ }
+ else if ( !mSettings.activateStatistics && mStatistics != 0 )
+ {
+ // user turned off statistics
+ stopStatistics();
+ }
+
+ if ( mStatusDialog )
+ {
+ mStatusDialog->setStatisticsGroupEnabled( mSettings.activateStatistics );
+ }
+}
+
+void Interface::activateMonitor()
+{
+ mMonitor.checkStatus( this );
+}
+
+void Interface::setStartTime( int )
+{
+ mStartTime.setDate( QDate::currentDate() );
+ mStartTime.setTime( QTime::currentTime() );
+}
+
+void Interface::showStatusDialog()
+{
+ // Toggle the status dialog.
+ // First click will show the status dialog, second will hide it.
+ if ( mStatusDialog == 0L )
+ {
+ mStatusDialog = new InterfaceStatusDialog( this );
+ connect( &mMonitor, SIGNAL( available( int ) ),
+ mStatusDialog, SLOT( enableNetworkGroups( int ) ) );
+ connect( &mMonitor, SIGNAL( notAvailable( int ) ),
+ mStatusDialog, SLOT( disableNetworkGroups( int ) ) );
+ connect( &mMonitor, SIGNAL( notExisting( int ) ),
+ mStatusDialog, SLOT( disableNetworkGroups( int ) ) );
+ if ( mStatistics != 0 )
+ {
+ connect( mStatistics, SIGNAL( currentEntryChanged() ),
+ mStatusDialog, SLOT( statisticsChanged() ) );
+ mStatusDialog->statisticsChanged();
+ }
+ activateOrHide( mStatusDialog, true );
+ }
+ else
+ {
+ // Toggle the status dialog.
+ activateOrHide( mStatusDialog );
+ }
+}
+
+void Interface::showSignalPlotter( bool wasMiddleButton )
+{
+ // No plotter, create it.
+ if ( mPlotter == 0L )
+ {
+ mPlotter = new SignalPlotter( 0L, mName.local8Bit() );
+ mPlotter->setIcon( SmallIcon( "knemo" ) );
+ mPlotter->setCaption( mName + " " + i18n( "Traffic" ) );
+ mPlotter->setTitle( mName );
+ configurePlotter();
+ activateOrHide( mPlotter, true );
+
+ mPlotterTimer = new QTimer();
+ connect( mPlotterTimer, SIGNAL( timeout() ),
+ this, SLOT( updatePlotter() ) );
+ mPlotterTimer->start( 1000 );
+ }
+ else
+ {
+ if ( wasMiddleButton )
+ {
+ // Toggle the signal plotter.
+ activateOrHide( mPlotter );
+ }
+ else
+ {
+ // Called from the context menu, show the dialog.
+ activateOrHide( mPlotter, true );
+ }
+ }
+}
+
+void Interface::showStatisticsDialog()
+{
+ if ( mStatisticsDialog == 0 )
+ {
+ mStatisticsDialog = new InterfaceStatisticsDialog( this );
+ if ( mStatistics == 0 )
+ {
+ // should never happen but you never know...
+ startStatistics();
+ }
+ connect( mStatistics, SIGNAL( dayStatisticsChanged() ),
+ mStatisticsDialog, SLOT( updateDays() ) );
+ connect( mStatistics, SIGNAL( monthStatisticsChanged() ),
+ mStatisticsDialog, SLOT( updateMonths() ) );
+ connect( mStatistics, SIGNAL( yearStatisticsChanged() ),
+ mStatisticsDialog, SLOT( updateYears() ) );
+ connect( mStatistics, SIGNAL( currentEntryChanged() ),
+ mStatisticsDialog, SLOT( updateCurrentEntry() ) );
+ connect( mStatisticsDialog, SIGNAL( clearDailyStatisticsClicked() ),
+ mStatistics, SLOT( clearDayStatistics() ) );
+ connect( mStatisticsDialog, SIGNAL( clearMonthlyStatisticsClicked() ),
+ mStatistics, SLOT( clearMonthStatistics() ) );
+ connect( mStatisticsDialog, SIGNAL( clearYearlyStatisticsClicked() ),
+ mStatistics, SLOT( clearYearStatistics() ) );
+
+ mStatisticsDialog->updateDays();
+ mStatisticsDialog->updateMonths();
+ mStatisticsDialog->updateYears();
+ }
+ mStatisticsDialog->show();
+}
+
+void Interface::resetData( int state )
+{
+ // For PPP interfaces we will reset all data to zero when the
+ // interface gets disconnected. If the driver also resets its data
+ // (like PPP seems to do) we will start from zero for every new
+ // connection.
+ if ( mType == PPP &&
+ ( state == NOT_AVAILABLE ||
+ state == NOT_EXISTING ) )
+ {
+ mData.prevTxBytes = mData.txBytes = 0;
+ mData.prevRxBytes = mData.rxBytes = 0;
+ mData.prevTxPackets = mData.txPackets = 0;
+ mData.prevRxPackets = mData.rxPackets = 0;
+ }
+}
+
+void Interface::updatePlotter()
+{
+ if ( mPlotter )
+ {
+ double outgoingBytes = mData.outgoingBytes / 1024.0 / (double) mGeneralData.pollInterval;
+ double incomingBytes = mData.incomingBytes / 1024.0 / (double) mGeneralData.pollInterval;
+
+ QValueList<double> trafficList;
+ switch ( mVisibleBeams )
+ {
+ case BOTH:
+ if ( mIncomingPos == 1 )
+ {
+ trafficList.append( outgoingBytes );
+ trafficList.append( incomingBytes );
+ }
+ else
+ {
+ trafficList.append( incomingBytes );
+ trafficList.append( outgoingBytes );
+ }
+ mPlotter->addSample( trafficList );
+ break;
+ case INCOMING_TRAFFIC:
+ trafficList.append( incomingBytes );
+ mPlotter->addSample( trafficList );
+ break;
+ case OUTGOING_TRAFFIC:
+ trafficList.append( outgoingBytes );
+ mPlotter->addSample( trafficList );
+ break;
+ case NONE:
+ break;
+ }
+ }
+}
+
+void Interface::configurePlotter()
+{
+ mPlotter->setFontSize( mPlotterSettings.fontSize );
+ if ( !mPlotterSettings.automaticDetection )
+ {
+ mPlotter->setMinValue( mPlotterSettings.minimumValue );
+ mPlotter->setMaxValue( mPlotterSettings.maximumValue );
+ }
+ mPlotter->setHorizontalScale( mPlotterSettings.pixel );
+ mPlotter->setHorizontalLinesCount( mPlotterSettings.count );
+ mPlotter->setVerticalLinesDistance( mPlotterSettings.distance );
+ mPlotter->setShowLabels( mPlotterSettings.labels );
+ mPlotter->setShowTopBar( mPlotterSettings.topBar );
+ mPlotter->setShowVerticalLines( mPlotterSettings.verticalLines );
+ mPlotter->setShowHorizontalLines( mPlotterSettings.horizontalLines );
+ mPlotter->setUseAutoRange( mPlotterSettings.automaticDetection );
+ mPlotter->setVerticalLinesScroll( mPlotterSettings.verticalLinesScroll );
+ mPlotter->setVerticalLinesColor( mPlotterSettings.colorVLines );
+ mPlotter->setHorizontalLinesColor( mPlotterSettings.colorHLines );
+ mPlotter->setBackgroundColor( mPlotterSettings.colorBackground );
+
+ // add or remove beams according to user settings
+ VisibleBeams nextVisibleBeams = NONE;
+ if ( mPlotterSettings.showOutgoing )
+ nextVisibleBeams = (VisibleBeams) ( nextVisibleBeams | OUTGOING_TRAFFIC );
+ if ( mPlotterSettings.showIncoming )
+ nextVisibleBeams = (VisibleBeams) ( nextVisibleBeams | INCOMING_TRAFFIC );
+
+ QValueList<QColor>& colors = mPlotter->beamColors();
+ switch( mVisibleBeams )
+ {
+ case NONE:
+ if ( nextVisibleBeams == BOTH )
+ {
+ mOutgoingPos = 0;
+ mPlotter->addBeam( mPlotterSettings.colorOutgoing );
+ mIncomingPos = 1;
+ mPlotter->addBeam( mPlotterSettings.colorIncoming );
+ }
+ else if ( nextVisibleBeams == OUTGOING_TRAFFIC )
+ {
+ mOutgoingPos = 0;
+ mPlotter->addBeam( mPlotterSettings.colorOutgoing );
+ }
+ else if ( nextVisibleBeams == INCOMING_TRAFFIC )
+ {
+ mIncomingPos = 0;
+ mPlotter->addBeam( mPlotterSettings.colorIncoming );
+ }
+ break;
+ case INCOMING_TRAFFIC:
+ if ( nextVisibleBeams == BOTH )
+ {
+ mOutgoingPos = 1;
+ mPlotter->addBeam( mPlotterSettings.colorOutgoing );
+ }
+ else if ( nextVisibleBeams == OUTGOING_TRAFFIC )
+ {
+ mPlotter->removeBeam( mIncomingPos );
+ mOutgoingPos = 0;
+ mPlotter->addBeam( mPlotterSettings.colorOutgoing );
+ }
+ else if ( nextVisibleBeams == INCOMING_TRAFFIC )
+ {
+ colors[mIncomingPos] = ( mPlotterSettings.colorIncoming );
+ }
+ else if ( nextVisibleBeams == NONE )
+ {
+ mPlotter->removeBeam( mIncomingPos );
+ }
+ break;
+ case OUTGOING_TRAFFIC:
+ if ( nextVisibleBeams == BOTH )
+ {
+ mIncomingPos = 1;
+ mPlotter->addBeam( mPlotterSettings.colorIncoming );
+ }
+ else if ( nextVisibleBeams == INCOMING_TRAFFIC )
+ {
+ mPlotter->removeBeam( mOutgoingPos );
+ mIncomingPos = 0;
+ mPlotter->addBeam( mPlotterSettings.colorIncoming );
+ }
+ else if ( nextVisibleBeams == OUTGOING_TRAFFIC )
+ {
+ colors[mOutgoingPos] = ( mPlotterSettings.colorOutgoing );
+ }
+ else if ( nextVisibleBeams == NONE )
+ {
+ mPlotter->removeBeam( mOutgoingPos );
+ }
+ break;
+ case BOTH:
+ if ( nextVisibleBeams == BOTH )
+ {
+ colors[mIncomingPos] = ( mPlotterSettings.colorIncoming );
+ colors[mOutgoingPos] = ( mPlotterSettings.colorOutgoing );
+ }
+ else if ( nextVisibleBeams == OUTGOING_TRAFFIC )
+ {
+ mOutgoingPos = 0;
+ mPlotter->removeBeam( mIncomingPos );
+ }
+ else if ( nextVisibleBeams == INCOMING_TRAFFIC )
+ {
+ mIncomingPos = 0;
+ mPlotter->removeBeam( mOutgoingPos );
+ }
+ else if ( nextVisibleBeams == NONE )
+ {
+ mPlotter->removeBeam( 0 );
+ mPlotter->removeBeam( 0 );
+ }
+ break;
+ }
+ mVisibleBeams = nextVisibleBeams;
+ mPlotter->repaint();
+}
+
+void Interface::startStatistics()
+{
+ mStatistics = new InterfaceStatistics( this );
+ connect( &mMonitor, SIGNAL( incomingData( unsigned long ) ),
+ mStatistics, SLOT( addIncomingData( unsigned long ) ) );
+ connect( &mMonitor, SIGNAL( outgoingData( unsigned long ) ),
+ mStatistics, SLOT( addOutgoingData( unsigned long ) ) );
+ if ( mStatusDialog != 0 )
+ {
+ connect( mStatistics, SIGNAL( currentEntryChanged() ),
+ mStatusDialog, SLOT( statisticsChanged() ) );
+ mStatusDialog->statisticsChanged();
+ }
+
+ mStatistics->loadStatistics();
+}
+
+void Interface::stopStatistics()
+{
+ if ( mStatisticsDialog != 0 )
+ {
+ // this will close an open statistics dialog
+ delete mStatisticsDialog;
+ mStatisticsDialog = 0;
+ }
+
+ mStatistics->saveStatistics();
+
+ delete mStatistics;
+ mStatistics = 0;
+}
+
+// taken from ksystemtray.cpp
+void Interface::activateOrHide( QWidget* widget, bool onlyActivate )
+{
+ if ( !widget )
+ return;
+
+ KWin::WindowInfo info1 = KWin::windowInfo( widget->winId(), NET::XAWMState | NET::WMState );
+ // mapped = visible (but possibly obscured)
+ bool mapped = (info1.mappingState() == NET::Visible) && !info1.isMinimized();
+ // - not mapped -> show, raise, focus
+ // - mapped
+ // - obscured -> raise, focus
+ // - not obscured -> hide
+ if( !mapped )
+ {
+ KWin::setOnDesktop( widget->winId(), KWin::currentDesktop() );
+ widget->show();
+ widget->raise();
+ KWin::activateWindow( widget->winId() );
+ }
+ else
+ {
+ KWinModule module;
+ for( QValueList< WId >::ConstIterator it = module.stackingOrder().fromLast();
+ it != module.stackingOrder().end() && (*it) != widget->winId();
+ --it )
+ {
+ KWin::WindowInfo info2 = KWin::windowInfo( *it, (unsigned long)
+ NET::WMGeometry | NET::XAWMState | NET::WMState | NET::WMWindowType );
+ if( info2.mappingState() != NET::Visible )
+ continue; // not visible on current desktop -> ignore
+ if( !info2.geometry().intersects( widget->geometry()))
+ continue; // not obscuring the window -> ignore
+ if( !info1.hasState( NET::KeepAbove ) && info2.hasState( NET::KeepAbove ))
+ continue; // obscured by window kept above -> ignore
+ NET::WindowType type = info2.windowType( NET::NormalMask | NET::DesktopMask
+ | NET::DockMask | NET::ToolbarMask | NET::MenuMask | NET::DialogMask
+ | NET::OverrideMask | NET::TopMenuMask | NET::UtilityMask | NET::SplashMask );
+ if( type == NET::Dock || type == NET::TopMenu )
+ continue; // obscured by dock or topmenu -> ignore
+ widget->raise();
+ KWin::activateWindow( widget->winId());
+ return;
+ }
+ if ( !onlyActivate )
+ {
+ widget->hide();
+ }
+ }
+}
+
+#include "interface.moc"
diff --git a/src/knemod/interface.h b/src/knemod/interface.h
new file mode 100644
index 0000000..06bea0a
--- /dev/null
+++ b/src/knemod/interface.h
@@ -0,0 +1,243 @@
+/* This file is part of KNemo
+ Copyright (C) 2004, 2006 Percy Leonhardt <[email protected]>
+
+ KNemo is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of
+ the License, or (at your option) any later version.
+
+ KNemo 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 Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef INTERFACE_H
+#define INTERFACE_H
+
+#include <qobject.h>
+#include <qstring.h>
+#include <qdatetime.h>
+
+#include "data.h"
+#include "global.h"
+#include "interfaceicon.h"
+#include "interfacemonitor.h"
+
+class QTimer;
+class SignalPlotter;
+class InterfaceStatistics;
+class InterfaceStatusDialog;
+class InterfaceStatisticsDialog;
+
+/**
+ * This class is the central place for all things that belong to an
+ * interface. It stores some information and knows about the interface
+ * data, icon, monitor and settings.
+ *
+ * @short Central class for every interface
+ * @author Percy Leonhardt <[email protected]>
+ */
+class Interface : public QObject
+{
+ Q_OBJECT
+public:
+ /**
+ * Default Constructor
+ */
+ Interface(QString ifname,
+ const GeneralData& generalData,
+ const PlotterSettings& plotterSettings );
+
+ /**
+ * Default Destructor
+ */
+ virtual ~Interface();
+
+ void setType( int type )
+ {
+ mType = type;
+ }
+
+ int getType()
+ {
+ return mType;
+ }
+
+ void setState( int state )
+ {
+ mState = state;
+ }
+
+ int getState()
+ {
+ return mState;
+ }
+
+ const QDateTime& getStartTime() const
+ {
+ return mStartTime;
+ }
+
+ const QString& getName() const
+ {
+ return mName;
+ }
+
+ InterfaceData& getData()
+ {
+ return mData;
+ }
+
+ InterfaceSettings& getSettings()
+ {
+ return mSettings;
+ }
+
+ WirelessData& getWirelessData()
+ {
+ return mWirelessData;
+ }
+
+ const GeneralData& getGeneralData() const
+ {
+ return mGeneralData;
+ }
+
+ InterfaceStatistics* getStatistics()
+ {
+ return mStatistics;
+ }
+
+ /**
+ * Called from reparseConfiguration() when the user changed
+ * the settings.
+ */
+ void configChanged();
+
+ /**
+ * Called from the interface updater class after new data from
+ * 'ifconfig' has been read. This will trigger the monitor to
+ * to look for changes in interface data or interface state.
+ */
+ void activateMonitor();
+
+ enum InterfaceState
+ {
+ UNKNOWN_STATE = -1,
+ NOT_EXISTING = 0,
+ NOT_AVAILABLE = 1,
+ AVAILABLE = 2,
+ RX_TRAFFIC = 4,
+ TX_TRAFFIC = 8
+ };
+
+ enum InterfaceType
+ {
+ UNKNOWN_TYPE,
+ ETHERNET,
+ PPP
+ };
+
+ enum IconSet
+ {
+ MONITOR = 0,
+ MODEM,
+ NETWORK,
+ WIRELESS
+ };
+
+public slots:
+ /*
+ * Called when the user left-clicks on the tray icon
+ * Toggles the status dialog by showing it on the first click and
+ * hiding it on the second click.
+ */
+ void showStatusDialog();
+
+ /*
+ * Called when the user middle-clicks on the tray icon
+ * Toggles the signal plotter that displays the incoming and
+ * outgoing traffic.
+ */
+ void showSignalPlotter( bool wasMiddleButton );
+
+ /*
+ * Called when the user selects the appropriate entry in the context menu.
+ */
+ void showStatisticsDialog();
+
+ /*
+ * Reset data when PPP interface is disconnected
+ */
+ void resetData( int state );
+
+private slots:
+ /**
+ * Start the uptimer when the interface is connected
+ */
+ void setStartTime( int );
+
+ /**
+ * Update the signal plotter with new data
+ */
+ void updatePlotter();
+
+ /**
+ * Configure the signal plotter with user settings
+ */
+ void configurePlotter();
+
+private:
+ /**
+ * Start the statistics and load previously saved ones
+ */
+ void startStatistics();
+
+ /**
+ * Store the statistics and stop collecting any further data
+ */
+ void stopStatistics();
+
+ /**
+ * The following function is taken from ksystemtray.cpp for
+ * correct show, raise, focus and hide of status dialog and
+ * signal plotter.
+ */
+ void activateOrHide( QWidget* widget, bool onlyActivate = false );
+
+ enum VisibleBeams
+ {
+ NONE = 0,
+ INCOMING_TRAFFIC = 1,
+ OUTGOING_TRAFFIC = 2,
+ BOTH = 3
+ };
+
+ int mType;
+ int mState;
+ int mOutgoingPos;
+ int mIncomingPos;
+ QString mName;
+ QTimer* mPlotterTimer;
+ QDateTime mStartTime;
+ InterfaceIcon mIcon;
+ InterfaceData mData;
+ InterfaceMonitor mMonitor;
+ InterfaceSettings mSettings;
+ InterfaceStatistics* mStatistics;
+ WirelessData mWirelessData;
+ InterfaceStatusDialog* mStatusDialog;
+ InterfaceStatisticsDialog* mStatisticsDialog;
+ SignalPlotter* mPlotter;
+ VisibleBeams mVisibleBeams;
+ const GeneralData& mGeneralData;
+ const PlotterSettings& mPlotterSettings;
+};
+
+#endif // INTERFACE_H
diff --git a/src/knemod/interfaceicon.cpp b/src/knemod/interfaceicon.cpp
new file mode 100644
index 0000000..4bda3df
--- /dev/null
+++ b/src/knemod/interfaceicon.cpp
@@ -0,0 +1,309 @@
+/* This file is part of KNemo
+ Copyright (C) 2004, 2005 Percy Leonhardt <[email protected]>
+
+ KNemo is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of
+ the License, or (at your option) any later version.
+
+ KNemo 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 Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <unistd.h>
+
+#include <qpixmap.h>
+
+#include <kdebug.h>
+#include <kglobal.h>
+#include <klocale.h>
+#include <kprocess.h>
+#include <kpopupmenu.h>
+#include <kiconloader.h>
+#include <knotifyclient.h>
+
+#include "data.h"
+#include "interface.h"
+#include "knemodaemon.h"
+#include "interfaceicon.h"
+#include "interfacetray.h"
+#include "interfacemonitor.h"
+#include "interfacetooltip.h"
+
+const QString InterfaceIcon::ICON_DISCONNECTED = "network_disconnected";
+const QString InterfaceIcon::ICON_CONNECTED = "network_connected";
+const QString InterfaceIcon::ICON_INCOMING = "network_incoming";
+const QString InterfaceIcon::ICON_OUTGOING = "network_outgoing";
+const QString InterfaceIcon::ICON_TRAFFIC = "network_traffic";
+const QString InterfaceIcon::SUFFIX_PPP = "_ppp";
+const QString InterfaceIcon::SUFFIX_LAN = "_lan";
+const QString InterfaceIcon::SUFFIX_WLAN = "_wlan";
+
+InterfaceIcon::InterfaceIcon( Interface* interface )
+ : QObject(),
+ mInterface( interface ),
+ mTray( 0L )
+{
+}
+
+InterfaceIcon::~InterfaceIcon()
+{
+ if ( mTray != 0L )
+ delete mTray;
+}
+
+void InterfaceIcon::updateStatus( int status )
+{
+ if ( mTray == 0L )
+ return;
+
+ // If the user wants something different than the default icons
+ // append the correct suffix to the filename.
+ QString suffix;
+ if ( mInterface->getSettings().iconSet == Interface::NETWORK )
+ {
+ suffix = SUFFIX_LAN;
+ }
+ else if ( mInterface->getSettings().iconSet == Interface::WIRELESS )
+ {
+ suffix = SUFFIX_WLAN;
+ }
+ else if ( mInterface->getSettings().iconSet == Interface::MODEM )
+ {
+ suffix = SUFFIX_PPP;
+ }
+ else
+ {
+ suffix = ""; // use standard icons
+ }
+
+ // Now set the correct icon depending on the status of the interface.
+ if ( status == Interface::NOT_AVAILABLE ||
+ status == Interface::NOT_EXISTING )
+ {
+ mTray->setPixmap( mTray->loadIcon( ICON_DISCONNECTED + suffix ) );
+ }
+ else if ( ( status & Interface::RX_TRAFFIC ) &&
+ ( status & Interface::TX_TRAFFIC ) )
+ {
+ mTray->setPixmap( mTray->loadIcon( ICON_TRAFFIC + suffix ) );
+ }
+ else if ( status & Interface::RX_TRAFFIC )
+ {
+ mTray->setPixmap( mTray->loadIcon( ICON_INCOMING + suffix ) );
+ }
+ else if ( status & Interface::TX_TRAFFIC )
+ {
+ mTray->setPixmap( mTray->loadIcon( ICON_OUTGOING + suffix ) );
+ }
+ else
+ {
+ mTray->setPixmap( mTray->loadIcon( ICON_CONNECTED + suffix ) );
+ }
+}
+
+void InterfaceIcon::updateToolTip()
+{
+ if ( mTray == 0L )
+ return;
+
+ QString toolTip = mInterface->getSettings().alias;
+ if ( toolTip == QString::null )
+ toolTip = mInterface->getName();
+ new InterfaceToolTip( mInterface, mTray );
+}
+
+void InterfaceIcon::updateMenu()
+{
+ if ( mTray == 0L )
+ return;
+
+ // Remove all old entries.
+ KPopupMenu* menu = mTray->contextMenu();
+ int count = menu->count();
+ for ( int i = 0; i < count - 6; i++ )
+ menu->removeItemAt( 6 );
+
+ InterfaceSettings& settings = mInterface->getSettings();
+
+ // If the user wants statistics, add an entry to show them.
+ if ( settings.activateStatistics )
+ {
+ menu->insertItem( i18n( "Open &Statistics" ), this,
+ SIGNAL( statisticsSelected() ) );
+ }
+
+ // If the user wants custom commands, add them.
+ if ( settings.customCommands )
+ {
+ menu->insertSeparator();
+ QValueVector<InterfaceCommand>::iterator it;
+ for ( it = settings.commands.begin(); it != settings.commands.end(); it++ )
+ (*it).id = menu->insertItem( (*it).menuText );
+ }
+}
+
+void InterfaceIcon::updateTrayStatus( int previousState )
+{
+ bool interfaceExists = mInterface->getData().existing;
+ bool interfaceAvailable = mInterface->getData().available;
+ bool hideWhenNotExisting = mInterface->getSettings().hideWhenNotExisting;
+ bool hideWhenNotAvailable = mInterface->getSettings().hideWhenNotAvailable;
+
+ // notification 'interface not available'
+ if ( !interfaceAvailable && mTray != 0L &&
+ previousState == Interface::AVAILABLE )
+ {
+ /* When KNemo is starting we don't show the change in connection
+ * status as this would be annoying when KDE starts.
+ */
+ QString title;
+ if ( mInterface->getSettings().alias != QString::null )
+ title = mInterface->getSettings().alias;
+ else
+ title = mInterface->getName();
+
+ KNotifyClient::event( mTray->winId(), "knemo_disconnected",
+ title + ":\n" + i18n( "Not connected." ) );
+ /* Wait half a second before deleting the tray so that the call
+ * to the notification daemon has a chance to run before the
+ * winId gets invalid.
+ */
+ usleep( 500000 );
+ }
+
+ // notification 'interface not existing'
+ if ( !interfaceExists && mTray != 0L &&
+ previousState != Interface::UNKNOWN_STATE )
+ {
+ /* When KNemo is starting we don't show the change in connection
+ * status as this would be annoying when KDE starts.
+ */
+ QString title;
+ if ( mInterface->getSettings().alias != QString::null )
+ title = mInterface->getSettings().alias;
+ else
+ title = mInterface->getName();
+
+ KNotifyClient::event( mTray->winId(), "knemo_notexisting",
+ title + ":\n" + i18n( "Not existing." ) );
+ /* Wait half a second before deleting the tray so that the call
+ * to the notification daemon has a chance to run before the
+ * winId gets invalid.
+ */
+ usleep( 500000 );
+ }
+
+ /* Remove the icon if
+ * - the interface is not available and the option to hide it is selected
+ * - the interface does not exist, the option to hide it is selected
+ * and the other option is not selected
+ */
+ if ( mTray != 0L &&
+ ( ( !interfaceAvailable && hideWhenNotAvailable ) ||
+ ( !interfaceExists && hideWhenNotExisting && !hideWhenNotAvailable ) ) )
+ {
+ delete mTray;
+ mTray = 0L;
+ }
+ /* Create the icon if
+ * - the interface is available
+ * - the interface is not available and the option to hide it is not
+ * selected and the interface does exist
+ * - the interface does not exist and the option to hide it is not selected
+ * and the other option is not selected
+ */
+ else if ( mTray == 0L &&
+ ( interfaceAvailable ||
+ ( !interfaceAvailable && !hideWhenNotAvailable && interfaceExists ) ||
+ ( !interfaceExists && !hideWhenNotExisting && !hideWhenNotAvailable ) ) )
+ {
+ mTray = new InterfaceTray( mInterface->getName() );
+ QToolTip::add( mTray, mInterface->getName() );
+ KPopupMenu* menu = mTray->contextMenu();
+ connect( menu, SIGNAL( activated( int ) ),
+ this, SLOT( menuActivated( int ) ) );
+ connect( mTray, SIGNAL( leftClicked() ),
+ mInterface, SLOT( showStatusDialog() ) );
+ connect( mTray, SIGNAL( graphSelected( bool ) ),
+ mInterface, SLOT( showSignalPlotter( bool ) ) );
+ connect( mTray, SIGNAL( configSelected() ),
+ this, SLOT( showConfigDialog() ) );
+
+ updateStatus( mInterface->getState() );
+ updateToolTip();
+ updateMenu();
+ mTray->show();
+ }
+
+ // notification 'interface available'
+ if ( interfaceAvailable && mTray != 0L &&
+ previousState != Interface::UNKNOWN_STATE )
+ {
+ /* When KNemo is starting we don't show the change in connection
+ * status as this would be annoying when KDE starts.
+ */
+ QString title;
+ if ( mInterface->getSettings().alias != QString::null )
+ title = mInterface->getSettings().alias;
+ else
+ title = mInterface->getName();
+
+ /* Wait half a second before calling the notification daemon
+ * so that the winId of the tray is valid when used below.
+ */
+ usleep( 500000 );
+ if ( mInterface->getData().wirelessDevice )
+ {
+ KNotifyClient::event( mTray->winId(), "knemo_connected",
+ title + ":\n" + i18n( "Connection established to\n" ) +
+ mInterface->getWirelessData().essid );
+ }
+ else
+ {
+ KNotifyClient::event( mTray->winId(), "knemo_connected",
+ title + ":\n" + i18n( "Connection established." ) );
+ }
+ }
+}
+
+void InterfaceIcon::showConfigDialog()
+{
+ KNemoDaemon::sSelectedInterface = mInterface->getName();
+
+ KProcess process;
+ process << "kcmshell" << "kcm_knemo";
+ process.start( KProcess::DontCare );
+}
+
+void InterfaceIcon::menuActivated( int id )
+{
+ InterfaceSettings& settings = mInterface->getSettings();
+ QValueVector<InterfaceCommand>::iterator it;
+ for ( it = settings.commands.begin(); it != settings.commands.end(); it++ )
+ {
+ if ( (*it).id == id )
+ {
+ KProcess process;
+ if ( (*it).runAsRoot )
+ {
+ process << "kdesu";
+ process << (*it).command;
+ }
+ else
+ process << QStringList::split( ' ', (*it).command );
+
+ process.start( KProcess::DontCare );
+ break;
+ }
+ }
+}
+
+#include "interfaceicon.moc"
diff --git a/src/knemod/interfaceicon.h b/src/knemod/interfaceicon.h
new file mode 100644
index 0000000..96d320b
--- /dev/null
+++ b/src/knemod/interfaceicon.h
@@ -0,0 +1,105 @@
+/* This file is part of KNemo
+ Copyright (C) 2004, 2005 Percy Leonhardt <[email protected]>
+
+ KNemo is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of
+ the License, or (at your option) any later version.
+
+ KNemo 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 Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef INTERFACEICON_H
+#define INTERFACEICON_H
+
+#include <qobject.h>
+#include <qstring.h>
+
+class Interface;
+class InterfaceTray;
+
+/**
+ * This is the logical representation of the systemtray icon. It handles
+ * creation and deletion of the real icon, setting the tooltip, setting
+ * the correct icon image and displaying of the settings dialog.
+ *
+ * @short Logical representation of the systemtray icon
+ * @author Percy Leonhardt <[email protected]>
+ */
+
+class InterfaceIcon : public QObject
+{
+ Q_OBJECT
+public:
+ /**
+ * Default Constructor
+ */
+ InterfaceIcon( Interface* interface );
+
+ /**
+ * Default Destructor
+ */
+ virtual ~InterfaceIcon();
+
+ /*
+ * Change the tooltip according to the alias of the interface
+ */
+ void updateToolTip();
+
+ /*
+ * Fill the context menu with entries if the user configured
+ * start and stop command
+ */
+ void updateMenu();
+
+signals:
+ void statisticsSelected();
+
+public slots:
+ /*
+ * Changes the icon image displayed in the tray
+ */
+ void updateStatus( int status );
+
+ /*
+ * Creates or deletes the tray icon
+ */
+ void updateTrayStatus( int previousState );
+
+private slots:
+ /*
+ * Called when the user selects 'Configure KNemo' from the context menu
+ */
+ void showConfigDialog();
+
+ /*
+ * Called when the user setup custom commands and selects one
+ * in the context menu
+ */
+ void menuActivated( int id );
+
+private:
+ // the interface this icon belongs to
+ Interface* mInterface;
+ // the real tray icon
+ InterfaceTray* mTray;
+
+ static const QString ICON_DISCONNECTED;
+ static const QString ICON_CONNECTED;
+ static const QString ICON_INCOMING;
+ static const QString ICON_OUTGOING;
+ static const QString ICON_TRAFFIC;
+ static const QString SUFFIX_PPP;
+ static const QString SUFFIX_LAN;
+ static const QString SUFFIX_WLAN;
+};
+
+#endif // INTERFACEICON_H
diff --git a/src/knemod/interfacemonitor.cpp b/src/knemod/interfacemonitor.cpp
new file mode 100644
index 0000000..b75d35e
--- /dev/null
+++ b/src/knemod/interfacemonitor.cpp
@@ -0,0 +1,100 @@
+/* This file is part of KNemo
+ Copyright (C) 2004, 2006 Percy Leonhardt <[email protected]>
+
+ KNemo is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of
+ the License, or (at your option) any later version.
+
+ KNemo 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 Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <kdebug.h>
+
+#include "interface.h"
+#include "interfacemonitor.h"
+
+InterfaceMonitor::InterfaceMonitor( QObject* parent, const char* name )
+ : QObject( parent, name )
+{
+}
+
+InterfaceMonitor::~InterfaceMonitor()
+{
+}
+
+void InterfaceMonitor::checkStatus( Interface* interface )
+{
+ int currentState;
+ int previousState = interface->getState();
+ InterfaceData& data = interface->getData();
+ int trafficThreshold = interface->getSettings().trafficThreshold;
+
+ if ( !data.existing )
+ // the interface does not exist
+ currentState = Interface::NOT_EXISTING;
+ else if ( !data.available )
+ // the interface exists but is not connected
+ currentState = Interface::NOT_AVAILABLE;
+ else
+ {
+ // the interface is connected, look for traffic
+ currentState = Interface::AVAILABLE;
+ if ( ( data.rxPackets - data.prevRxPackets ) > (unsigned int) trafficThreshold )
+ currentState |= Interface::RX_TRAFFIC;
+ if ( ( data.txPackets - data.prevTxPackets ) > (unsigned int) trafficThreshold )
+ currentState |= Interface::TX_TRAFFIC;
+ }
+
+ // update the statistics
+ if ( data.incomingBytes > 0 )
+ {
+ emit incomingData( data.incomingBytes );
+ }
+ if ( data.outgoingBytes > 0 )
+ {
+ emit outgoingData( data.outgoingBytes );
+ }
+
+ data.prevRxPackets = data.rxPackets;
+ data.prevTxPackets = data.txPackets;
+
+ if ( ( previousState == Interface::NOT_EXISTING ||
+ previousState == Interface::NOT_AVAILABLE ||
+ previousState == Interface::UNKNOWN_STATE ) &&
+ currentState & Interface::AVAILABLE )
+ {
+ emit available( previousState );
+ }
+ else if ( ( previousState == Interface::NOT_EXISTING ||
+ previousState & Interface::AVAILABLE ||
+ previousState == Interface::UNKNOWN_STATE ) &&
+ currentState == Interface::NOT_AVAILABLE )
+ {
+ emit notAvailable( previousState );
+ }
+ else if ( ( previousState == Interface::NOT_AVAILABLE ||
+ previousState & Interface::AVAILABLE ||
+ previousState == Interface::UNKNOWN_STATE ) &&
+ currentState == Interface::NOT_EXISTING )
+ {
+ emit notExisting( previousState );
+ }
+
+ // make sure the icon fits the current state
+ if ( previousState != currentState )
+ {
+ emit statusChanged( currentState );
+ interface->setState( currentState );
+ }
+}
+
+#include "interfacemonitor.moc"
diff --git a/src/knemod/interfacemonitor.h b/src/knemod/interfacemonitor.h
new file mode 100644
index 0000000..eacc1ea
--- /dev/null
+++ b/src/knemod/interfacemonitor.h
@@ -0,0 +1,72 @@
+/* This file is part of KNemo
+ Copyright (C) 2004, 2006 Percy Leonhardt <[email protected]>
+
+ KNemo is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of
+ the License, or (at your option) any later version.
+
+ KNemo 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 Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef INTERFACEMONITOR_H
+#define INTERFACEMONITOR_H
+
+#include <qobject.h>
+
+#include "data.h"
+
+class Interface;
+
+/**
+ * This class monitors the interface for possible state changes and
+ * for incoming and outgong traffic. If the state changed or traffic
+ * was transmitted it sends an according signal.
+ *
+ * @short Monitor changes of the interface
+ * @author Percy Leonhardt <[email protected]>
+ */
+
+class InterfaceMonitor : public QObject
+{
+ Q_OBJECT
+public:
+ /**
+ * Default Constructor
+ */
+ InterfaceMonitor(QObject* parent = 0L, const char* name = 0L);
+
+ /**
+ * Default Destructor
+ */
+ virtual ~InterfaceMonitor();
+
+ /**
+ * Tell the monitor to check the status of the interface
+ */
+ void checkStatus( Interface* interface );
+
+signals:
+ // the interface is now connected
+ void available( int );
+ // the interface is now disconnected
+ void notAvailable( int );
+ // the interface no longer exists
+ void notExisting( int );
+ // there was incoming and/or outgoing traffic
+ void statusChanged( int );
+ // the amount of incoming traffic (for statistics)
+ void incomingData( unsigned long );
+ // the amount of outgoing traffic (for statistics)
+ void outgoingData( unsigned long );
+};
+
+#endif // INTERFACEMONITOR_H
diff --git a/src/knemod/interfacestatistics.cpp b/src/knemod/interfacestatistics.cpp
new file mode 100644
index 0000000..a73d04b
--- /dev/null
+++ b/src/knemod/interfacestatistics.cpp
@@ -0,0 +1,384 @@
+/* This file is part of KNemo
+ Copyright (C) 2005, 2006 Percy Leonhardt <[email protected]>
+
+ KNemo is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of
+ the License, or (at your option) any later version.
+
+ KNemo 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 Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <qdom.h>
+#include <qfile.h>
+#include <qtimer.h>
+#include <qstring.h>
+#include <qdatetime.h>
+
+#include <kdebug.h>
+
+#include "interface.h"
+#include "interfacestatistics.h"
+
+InterfaceStatistics::InterfaceStatistics( Interface* interface )
+ : QObject(),
+ mInterface( interface )
+{
+ mDayStatistics.setAutoDelete( true );
+ mMonthStatistics.setAutoDelete( true );
+ mYearStatistics.setAutoDelete( true );
+ initStatistics();
+
+ mSaveTimer = new QTimer();
+ connect( mSaveTimer, SIGNAL( timeout() ), this, SLOT( saveStatistics() ) );
+ mSaveTimer->start( mInterface->getGeneralData().saveInterval * 1000 );
+}
+
+InterfaceStatistics::~InterfaceStatistics()
+{
+ mSaveTimer->stop();
+ delete mSaveTimer;
+
+ mDayStatistics.clear();
+ mMonthStatistics.clear();
+ mYearStatistics.clear();
+}
+
+void InterfaceStatistics::loadStatistics()
+{
+ QDomDocument doc( "statistics" );
+ QString dir = mInterface->getGeneralData().statisticsDir;
+ QFile file( dir + "/statistics_" + mInterface->getName() );
+
+ if ( !file.open( IO_ReadOnly ) )
+ return;
+ if ( !doc.setContent( &file ) )
+ {
+ file.close();
+ return;
+ }
+ file.close();
+
+ mDayStatistics.clear();
+ mMonthStatistics.clear();
+ mYearStatistics.clear();
+
+ QDomElement root = doc.documentElement();
+ QDomNode n = root.namedItem( "days" );
+ if ( !n.isNull() )
+ {
+ QDomNode dayNode = n.firstChild();
+ while ( !dayNode.isNull() )
+ {
+ QDomElement day = dayNode.toElement();
+ if ( !day.isNull() )
+ {
+ StatisticEntry* entry = new StatisticEntry();
+ entry->day = day.attribute( "day" ).toInt();
+ entry->month = day.attribute( "month" ).toInt();
+ entry->year = day.attribute( "year" ).toInt();
+ entry->rxBytes = (Q_UINT64) day.attribute( "rxBytes" ).toDouble();
+ entry->txBytes = (Q_UINT64) day.attribute( "txBytes" ).toDouble();
+ mDayStatistics.append( entry );
+ }
+ dayNode = dayNode.nextSibling();
+ }
+ mDayStatistics.sort();
+ }
+
+ n = root.namedItem( "months" );
+ if ( !n.isNull() )
+ {
+ QDomNode monthNode = n.firstChild();
+ while ( !monthNode.isNull() )
+ {
+ QDomElement month = monthNode.toElement();
+ if ( !month.isNull() )
+ {
+ StatisticEntry* entry = new StatisticEntry();
+ entry->day = 0;
+ entry->month = month.attribute( "month" ).toInt();
+ entry->year = month.attribute( "year" ).toInt();
+ entry->rxBytes = (Q_UINT64) month.attribute( "rxBytes" ).toDouble();
+ entry->txBytes = (Q_UINT64) month.attribute( "txBytes" ).toDouble();
+ mMonthStatistics.append( entry );
+ }
+ monthNode = monthNode.nextSibling();
+ }
+ mMonthStatistics.sort();
+ }
+
+ n = root.namedItem( "years" );
+ if ( !n.isNull() )
+ {
+ QDomNode yearNode = n.firstChild();
+ while ( !yearNode.isNull() )
+ {
+ QDomElement year = yearNode.toElement();
+ if ( !year.isNull() )
+ {
+ StatisticEntry* entry = new StatisticEntry();
+ entry->day = 0;
+ entry->month = 0;
+ entry->year = year.attribute( "year" ).toInt();
+ entry->rxBytes = (Q_UINT64) year.attribute( "rxBytes" ).toDouble();
+ entry->txBytes = (Q_UINT64) year.attribute( "txBytes" ).toDouble();
+ mYearStatistics.append( entry );
+ }
+ yearNode = yearNode.nextSibling();
+ }
+ mYearStatistics.sort();
+ }
+ initStatistics();
+}
+
+void InterfaceStatistics::saveStatistics()
+{
+ QDomDocument doc( "statistics" );
+ QDomElement root = doc.createElement( "statistics" );
+ doc.appendChild( root );
+
+ QDomElement days = doc.createElement( "days" );
+ StatisticEntry* iterator = mDayStatistics.first();
+ while ( iterator )
+ {
+ QDomElement day = doc.createElement( "day" );
+ day.setAttribute( "day", iterator->day );
+ day.setAttribute( "month", iterator->month );
+ day.setAttribute( "year", iterator->year );
+ day.setAttribute( "rxBytes", (double) iterator->rxBytes );
+ day.setAttribute( "txBytes", (double) iterator->txBytes );
+ days.appendChild( day );
+ iterator = mDayStatistics.next();
+ }
+ root.appendChild( days );
+
+ QDomElement months = doc.createElement( "months" );
+ iterator = mMonthStatistics.first();
+ while ( iterator )
+ {
+ QDomElement month = doc.createElement( "month" );
+ month.setAttribute( "month", iterator->month );
+ month.setAttribute( "year", iterator->year );
+ month.setAttribute( "rxBytes", (double) iterator->rxBytes );
+ month.setAttribute( "txBytes", (double) iterator->txBytes );
+ months.appendChild( month );
+ iterator = mMonthStatistics.next();
+ }
+ root.appendChild( months );
+
+ QDomElement years = doc.createElement( "years" );
+ iterator = mYearStatistics.first();
+ while ( iterator )
+ {
+ QDomElement year = doc.createElement( "year" );
+ year.setAttribute( "year", iterator->year );
+ year.setAttribute( "rxBytes", (double) iterator->rxBytes );
+ year.setAttribute( "txBytes", (double) iterator->txBytes );
+ years.appendChild( year );
+ iterator = mYearStatistics.next();
+ }
+ root.appendChild( years );
+
+ QString dir = mInterface->getGeneralData().statisticsDir;
+ QFile file( dir + "/statistics_" + mInterface->getName() );
+ if ( !file.open( IO_WriteOnly ) )
+ return;
+
+ QTextStream stream( &file );
+ stream << doc.toString();
+ file.close();
+}
+
+void InterfaceStatistics::configChanged()
+{
+ // restart the timer with the new value
+ mSaveTimer->changeInterval( mInterface->getGeneralData().saveInterval * 1000 );
+}
+
+const StatisticEntry* InterfaceStatistics::getCurrentDay() const
+{
+ return mCurrentDay;
+}
+
+const StatisticEntry* InterfaceStatistics::getCurrentMonth() const
+{
+ return mCurrentMonth;
+}
+
+const StatisticEntry* InterfaceStatistics::getCurrentYear() const
+{
+ return mCurrentYear;
+}
+
+const StatisticsPtrList<StatisticEntry>& InterfaceStatistics::getDayStatistics() const
+{
+ return mDayStatistics;
+}
+
+const StatisticsPtrList<StatisticEntry>& InterfaceStatistics::getMonthStatistics() const
+{
+ return mMonthStatistics;
+}
+
+const StatisticsPtrList<StatisticEntry>& InterfaceStatistics::getYearStatistics() const
+{
+ return mYearStatistics;
+}
+
+void InterfaceStatistics::addIncomingData( unsigned long data )
+{
+ checkCurrentEntry();
+
+ mCurrentDay->rxBytes += data;
+ mCurrentMonth->rxBytes += data;
+ mCurrentYear->rxBytes += data;
+
+ emit currentEntryChanged();
+}
+
+void InterfaceStatistics::addOutgoingData( unsigned long data )
+{
+ checkCurrentEntry();
+
+ mCurrentDay->txBytes += data;
+ mCurrentMonth->txBytes += data;
+ mCurrentYear->txBytes += data;
+
+ emit currentEntryChanged();
+}
+
+void InterfaceStatistics::clearDayStatistics()
+{
+ mDayStatistics.clear();
+ updateCurrentDay();
+}
+
+void InterfaceStatistics::clearMonthStatistics()
+{
+ mMonthStatistics.clear();
+ updateCurrentMonth();
+}
+
+void InterfaceStatistics::clearYearStatistics()
+{
+ mYearStatistics.clear();
+ updateCurrentYear();
+}
+
+void InterfaceStatistics::checkCurrentEntry()
+{
+ if ( mCurrentDay->day != QDate::currentDate().day() ||
+ mCurrentDay->month != QDate::currentDate().month() ||
+ mCurrentDay->year != QDate::currentDate().year() )
+ {
+ // current day has changed
+ updateCurrentDay();
+
+ if ( mCurrentMonth->month != QDate::currentDate().month() ||
+ mCurrentMonth->year != QDate::currentDate().year() )
+ {
+ // current month has also changed
+ updateCurrentMonth();
+ }
+
+ if ( mCurrentYear->year != QDate::currentDate().year() )
+ {
+ // current year has also changed
+ updateCurrentYear();
+ }
+ }
+}
+
+void InterfaceStatistics::initStatistics()
+{
+ updateCurrentDay();
+ updateCurrentMonth();
+ updateCurrentYear();
+
+ emit currentEntryChanged();
+}
+
+void InterfaceStatistics::updateCurrentDay()
+{
+ mCurrentDay = mDayStatistics.first();
+ while ( mCurrentDay )
+ {
+ if ( mCurrentDay->day == QDate::currentDate().day() &&
+ mCurrentDay->month == QDate::currentDate().month() &&
+ mCurrentDay->year == QDate::currentDate().year() )
+ {
+ // found current day in list
+ return;
+ }
+ mCurrentDay = mDayStatistics.next();
+ }
+
+ // the current day is not in the list
+ mCurrentDay = new StatisticEntry();
+ mCurrentDay->day = QDate::currentDate().day();
+ mCurrentDay->month = QDate::currentDate().month();
+ mCurrentDay->year = QDate::currentDate().year();
+ mCurrentDay->rxBytes = 0;
+ mCurrentDay->txBytes = 0;
+ mDayStatistics.append( mCurrentDay ); // TODO: insert at correct position
+ emit dayStatisticsChanged();
+}
+
+void InterfaceStatistics::updateCurrentMonth()
+{
+ mCurrentMonth = mMonthStatistics.first();
+ while ( mCurrentMonth )
+ {
+ if ( mCurrentMonth->month == QDate::currentDate().month() &&
+ mCurrentMonth->year == QDate::currentDate().year() )
+ {
+ // found current month in list
+ return;
+ }
+ mCurrentMonth = mMonthStatistics.next();
+ }
+
+ // the current month is not in the list
+ mCurrentMonth = new StatisticEntry();
+ mCurrentMonth->day = 0;
+ mCurrentMonth->month = QDate::currentDate().month();
+ mCurrentMonth->year = QDate::currentDate().year();
+ mCurrentMonth->rxBytes = 0;
+ mCurrentMonth->txBytes = 0;
+ mMonthStatistics.append( mCurrentMonth ); // TODO: insert at correct position
+ emit monthStatisticsChanged();
+}
+
+void InterfaceStatistics::updateCurrentYear()
+{
+ mCurrentYear = mYearStatistics.first();
+ while ( mCurrentYear )
+ {
+ if ( mCurrentYear->year == QDate::currentDate().year() )
+ {
+ // found current year in list
+ return;
+ }
+ mCurrentYear = mYearStatistics.next();
+ }
+
+ // the current year is not in the list
+ mCurrentYear = new StatisticEntry();
+ mCurrentYear->day = 0;
+ mCurrentYear->month = 0;
+ mCurrentYear->year = QDate::currentDate().year();
+ mCurrentYear->rxBytes = 0;
+ mCurrentYear->txBytes = 0;
+ mYearStatistics.append( mCurrentYear ); // TODO: insert at correct position
+ emit yearStatisticsChanged();
+}
+
diff --git a/src/knemod/interfacestatistics.h b/src/knemod/interfacestatistics.h
new file mode 100644
index 0000000..a4e3246
--- /dev/null
+++ b/src/knemod/interfacestatistics.h
@@ -0,0 +1,191 @@
+/* This file is part of KNemo
+ Copyright (C) 2005, 2006 Percy Leonhardt <[email protected]>
+
+ KNemo is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of
+ the License, or (at your option) any later version.
+
+ KNemo 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 Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef INTERFACESTATISTICS_H
+#define INTERFACESTATISTICS_H
+
+#include <qobject.h>
+#include <qptrlist.h>
+
+#include "global.h"
+
+class QTimer;
+class Interface;
+
+template<class type>
+class StatisticsPtrList : public QPtrList<type>
+{
+protected:
+ virtual int compareItems ( QPtrCollection::Item item1, QPtrCollection::Item item2 )
+ {
+ StatisticEntry* entry1 = static_cast<StatisticEntry*>( item1 );
+ StatisticEntry* entry2 = static_cast<StatisticEntry*>( item2 );
+
+ if ( entry1->year > entry2->year )
+ {
+ return 1;
+ }
+ else if ( entry2->year > entry1->year )
+ {
+ return -1;
+ } // ...here we know that years are the same...
+ else if ( entry1->month > entry2->month )
+ {
+ return 1;
+ }
+ else if ( entry2->month > entry1->month )
+ {
+ return -1;
+ } // ...here we know that months are the same...
+ else if ( entry1->day > entry2->day )
+ {
+ return 1;
+ }
+ else if ( entry2->day > entry1->day )
+ {
+ return -1;
+ } // ...here we know that dates are equal.
+
+ return 0;
+ };
+};
+
+/**
+ * This class is able to collect transfered data for an interface,
+ * store it in a file and deliver it on request.
+ *
+ * @short Statistics of transfered data for an interface
+ * @author Percy Leonhardt <[email protected]>
+ */
+
+class InterfaceStatistics : public QObject
+{
+ Q_OBJECT
+public:
+ /**
+ * Default Constructor
+ */
+ InterfaceStatistics( Interface* interface );
+
+ /**
+ * Default Destructor
+ */
+ virtual ~InterfaceStatistics();
+
+ /**
+ * Load the statistics from a xml file
+ */
+ void loadStatistics();
+
+ /**
+ * Called from Interface::configChanged() when the user
+ * changed the settings.
+ */
+ void configChanged();
+
+ const StatisticEntry* getCurrentDay() const;
+ const StatisticEntry* getCurrentMonth() const;
+ const StatisticEntry* getCurrentYear() const;
+ const StatisticsPtrList<StatisticEntry>& getDayStatistics() const;
+ const StatisticsPtrList<StatisticEntry>& getMonthStatistics() const;
+ const StatisticsPtrList<StatisticEntry>& getYearStatistics() const;
+
+signals:
+ /**
+ * The current entry has changed. There is only one signal
+ * for day, month and year because if the day changes,
+ * month and year also change.
+ */
+ void currentEntryChanged();
+ /**
+ * The list has changed i.e. there is a new day entry or the list was cleared
+ */
+ void dayStatisticsChanged();
+ /**
+ * The list has changed i.e. there is a new month entry or the list was cleared
+ */
+ void monthStatisticsChanged();
+ /**
+ * The list has changed i.e. there is a new year entry or the list was cleared
+ */
+ void yearStatisticsChanged();
+
+public slots:
+ /**
+ * Save the statistics to a xml file
+ * (slot so it can be triggered by a timer signal)
+ */
+ void saveStatistics();
+ /**
+ * Add incoming data to the current day, month and year
+ */
+ void addIncomingData( unsigned long data );
+ /**
+ * Add outgoing data to the current day, month and year
+ */
+ void addOutgoingData( unsigned long data );
+ /**
+ * Clear all entries of the day statistics
+ */
+ void clearDayStatistics();
+ /**
+ * Clear all entries of the month statistics
+ */
+ void clearMonthStatistics();
+ /**
+ * Clear all entries of the year statistics
+ */
+ void clearYearStatistics();
+
+private:
+ /**
+ * Make sure the current entry corresponds with the current date
+ */
+ void checkCurrentEntry();
+ /**
+ * Fill the statistics with a current entry
+ */
+ void initStatistics();
+ /**
+ * Check if the current day is in the day statistics. If found set
+ * mCurrentDay to the found entry else create a new one.
+ */
+ void updateCurrentDay();
+ /**
+ * Check if the current month is in the month statistics. If found set
+ * mCurrentMonth to the found entry else create a new one.
+ */
+ void updateCurrentMonth();
+ /**
+ * Check if the current year is in the year statistics. If found set
+ * mCurrentYear to the found entry else create a new one.
+ */
+ void updateCurrentYear();
+
+ QTimer* mSaveTimer;
+ Interface* mInterface;
+ StatisticEntry* mCurrentDay;
+ StatisticEntry* mCurrentMonth;
+ StatisticEntry* mCurrentYear;
+ StatisticsPtrList<StatisticEntry> mDayStatistics;
+ StatisticsPtrList<StatisticEntry> mMonthStatistics;
+ StatisticsPtrList<StatisticEntry> mYearStatistics;
+};
+
+#endif // INTERFACESTATISTICS_H
diff --git a/src/knemod/interfacestatisticsdialog.cpp b/src/knemod/interfacestatisticsdialog.cpp
new file mode 100644
index 0000000..55ee49a
--- /dev/null
+++ b/src/knemod/interfacestatisticsdialog.cpp
@@ -0,0 +1,139 @@
+/* This file is part of KNemo
+ Copyright (C) 2006 Percy Leonhardt <[email protected]>
+
+ KNemo is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of
+ the License, or (at your option) any later version.
+
+ KNemo 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 Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <qtable.h>
+#include <qdatetime.h>
+#include <qpushbutton.h>
+
+#include <klocale.h>
+#include <kio/global.h>
+#include <kiconloader.h>
+#include <kcalendarsystem.h>
+
+#include "data.h"
+#include "interface.h"
+#include "interfacestatistics.h"
+#include "interfacestatisticsdialog.h"
+
+/*
+ * I assume that the last entry in each table is also the current. This will fail
+ * if we walk back in time, so better not play with the system date...
+ */
+
+InterfaceStatisticsDialog::InterfaceStatisticsDialog( Interface* interface, QWidget* parent, const char* name )
+ : InterfaceStatisticsDlg( parent, name ),
+ mInterface( interface )
+{
+ setIcon( SmallIcon( "knemo" ) );
+ setCaption( interface->getName() + " " + i18n( "Statistics" ) );
+
+ connect( buttonClearDaily, SIGNAL( clicked() ), SIGNAL( clearDailyStatisticsClicked() ) );
+ connect( buttonClearMonthly, SIGNAL( clicked() ), SIGNAL( clearMonthlyStatisticsClicked() ) );
+ connect( buttonClearYearly, SIGNAL( clicked() ), SIGNAL( clearYearlyStatisticsClicked() ) );
+}
+
+InterfaceStatisticsDialog::~InterfaceStatisticsDialog()
+{
+}
+
+void InterfaceStatisticsDialog::updateDays()
+{
+ QPtrList<StatisticEntry> dayStatistics = mInterface->getStatistics()->getDayStatistics();
+ StatisticEntry* iterator = dayStatistics.first();
+ tableDaily->setNumRows( dayStatistics.count() );
+ int row = 0;
+ while ( iterator )
+ {
+ QDate date( iterator->year, iterator->month, iterator->day );
+ tableDaily->verticalHeader()->setLabel( row, KGlobal::locale()->formatDate( date, true ) );
+ tableDaily->setText( row, 0, KIO::convertSize( iterator->txBytes ) );
+ tableDaily->setText( row, 1, KIO::convertSize( iterator->rxBytes ) );
+ tableDaily->setText( row, 2, KIO::convertSize( iterator->rxBytes + iterator->txBytes ) );
+ row++;
+ iterator = dayStatistics.next();
+ }
+
+ tableDaily->setCurrentCell( row - 1, 2 );
+ tableDaily->ensureCellVisible( row - 1, 2 );
+}
+
+void InterfaceStatisticsDialog::updateMonths()
+{
+ QPtrList<StatisticEntry> monthStatistics = mInterface->getStatistics()->getMonthStatistics();
+ StatisticEntry* iterator = monthStatistics.first();
+ tableMonthly->setNumRows( monthStatistics.count() );
+ int row = 0;
+ while ( iterator )
+ {
+ const KCalendarSystem* calendar = KGlobal::locale()->calendar();
+ QString monthName = calendar->monthName( iterator->month, iterator->year ) + " " + QString::number( iterator->year );
+ tableMonthly->verticalHeader()->setLabel( row, monthName );
+ tableMonthly->setText( row, 0, KIO::convertSize( iterator->txBytes ) );
+ tableMonthly->setText( row, 1, KIO::convertSize( iterator->rxBytes ) );
+ tableMonthly->setText( row, 2, KIO::convertSize( iterator->rxBytes + iterator->txBytes ) );
+ row++;
+ iterator = monthStatistics.next();
+ }
+
+ tableMonthly->setCurrentCell( row - 1, 2 );
+ tableMonthly->ensureCellVisible( row - 1, 2 );
+}
+
+void InterfaceStatisticsDialog::updateYears()
+{
+ QPtrList<StatisticEntry> yearStatistics = mInterface->getStatistics()->getYearStatistics();
+ StatisticEntry* iterator = yearStatistics.first();
+ tableYearly->setNumRows( yearStatistics.count() );
+ int row = 0;
+ while ( iterator )
+ {
+ tableYearly->verticalHeader()->setLabel( row, QString::number( iterator->year ) );
+ tableYearly->setText( row, 0, KIO::convertSize( iterator->txBytes ) );
+ tableYearly->setText( row, 1, KIO::convertSize( iterator->rxBytes ) );
+ tableYearly->setText( row, 2, KIO::convertSize( iterator->rxBytes + iterator->txBytes ) );
+ row++;
+ iterator = yearStatistics.next();
+ }
+
+ tableYearly->setCurrentCell( row - 1, 2 );
+ tableYearly->ensureCellVisible( row - 1, 2 );
+}
+
+void InterfaceStatisticsDialog::updateCurrentEntry()
+{
+ int lastRow = tableDaily->numRows() - 1;
+ const StatisticEntry* currentEntry = mInterface->getStatistics()->getCurrentDay();
+ tableDaily->setText( lastRow, 0, KIO::convertSize( currentEntry->txBytes ) );
+ tableDaily->setText( lastRow, 1, KIO::convertSize( currentEntry->rxBytes ) );
+ tableDaily->setText( lastRow, 2, KIO::convertSize( currentEntry->rxBytes + currentEntry->txBytes ) );
+
+ lastRow = tableMonthly->numRows() - 1;
+ currentEntry = mInterface->getStatistics()->getCurrentMonth();
+ tableMonthly->setText( lastRow, 0, KIO::convertSize( currentEntry->txBytes ) );
+ tableMonthly->setText( lastRow, 1, KIO::convertSize( currentEntry->rxBytes ) );
+ tableMonthly->setText( lastRow, 2, KIO::convertSize( currentEntry->rxBytes + currentEntry->txBytes ) );
+
+ lastRow = tableYearly->numRows() - 1;
+ currentEntry = mInterface->getStatistics()->getCurrentYear();
+ tableYearly->setText( lastRow, 0, KIO::convertSize( currentEntry->txBytes ) );
+ tableYearly->setText( lastRow, 1, KIO::convertSize( currentEntry->rxBytes ) );
+ tableYearly->setText( lastRow, 2, KIO::convertSize( currentEntry->rxBytes + currentEntry->txBytes ) );
+}
+
+#include "interfacestatisticsdialog.moc"
diff --git a/src/knemod/interfacestatisticsdialog.h b/src/knemod/interfacestatisticsdialog.h
new file mode 100644
index 0000000..ce5e0e3
--- /dev/null
+++ b/src/knemod/interfacestatisticsdialog.h
@@ -0,0 +1,68 @@
+/* This file is part of KNemo
+ Copyright (C) 2006 Percy Leonhardt <[email protected]>
+
+ KNemo is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of
+ the License, or (at your option) any later version.
+
+ KNemo 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 Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef INTERFACESTATISTICSDIALOG_H
+#define INTERFACESTATISTICSDIALOG_H
+
+#include <qwidget.h>
+
+#include "interfacestatisticsdlg.h"
+
+class QTimer;
+class Interface;
+
+/**
+ * This class shows the statistics dialog. It contains the tables for the
+ * different statistics.
+ *
+ * @short Statistics dialog
+ * @author Percy Leonhardt <[email protected]>
+ */
+
+class InterfaceStatisticsDialog : public InterfaceStatisticsDlg
+{
+ Q_OBJECT
+public:
+ /**
+ * Default Constructor
+ */
+ InterfaceStatisticsDialog( Interface* interface,
+ QWidget* parent = 0L, const char* name = 0L );
+
+ /**
+ * Default Destructor
+ */
+ virtual ~InterfaceStatisticsDialog();
+
+signals:
+ void clearDailyStatisticsClicked();
+ void clearMonthlyStatisticsClicked();
+ void clearYearlyStatisticsClicked();
+
+public slots:
+ void updateDays();
+ void updateMonths();
+ void updateYears();
+ void updateCurrentEntry();
+
+private:
+ Interface* mInterface;
+};
+
+#endif // INTERFACESTATISTICSDIALOG_H
diff --git a/src/knemod/interfacestatisticsdlg.ui b/src/knemod/interfacestatisticsdlg.ui
new file mode 100644
index 0000000..b028832
--- /dev/null
+++ b/src/knemod/interfacestatisticsdlg.ui
@@ -0,0 +1,230 @@
+<!DOCTYPE UI><UI version="3.2" stdsetdef="1">
+<class>InterfaceStatisticsDlg</class>
+<widget class="QDialog">
+ <property name="name">
+ <cstring>InterfaceStatisticsDlg</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>490</width>
+ <height>502</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Statistics</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QPushButton" row="1" column="1">
+ <property name="name">
+ <cstring>buttonClose</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Close</string>
+ </property>
+ <property name="default">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QTabWidget" row="0" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>tabWidget</cstring>
+ </property>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>daily</cstring>
+ </property>
+ <attribute name="title">
+ <string>Daily</string>
+ </attribute>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QTable">
+ <column>
+ <property name="text">
+ <string>Sent</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Received</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Total</string>
+ </property>
+ </column>
+ <property name="name">
+ <cstring>tableDaily</cstring>
+ </property>
+ <property name="numRows">
+ <number>1</number>
+ </property>
+ <property name="numCols">
+ <number>3</number>
+ </property>
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>buttonClearDaily</cstring>
+ </property>
+ <property name="text">
+ <string>Clear daily statistics</string>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>monthy</cstring>
+ </property>
+ <attribute name="title">
+ <string>Monthly</string>
+ </attribute>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QTable">
+ <column>
+ <property name="text">
+ <string>Sent</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Received</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Total</string>
+ </property>
+ </column>
+ <property name="name">
+ <cstring>tableMonthly</cstring>
+ </property>
+ <property name="numRows">
+ <number>1</number>
+ </property>
+ <property name="numCols">
+ <number>3</number>
+ </property>
+ </widget>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>buttonClearMonthly</cstring>
+ </property>
+ <property name="text">
+ <string>Clear monthly statistics</string>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>yearly</cstring>
+ </property>
+ <attribute name="title">
+ <string>Yearly</string>
+ </attribute>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QTable">
+ <column>
+ <property name="text">
+ <string>Sent</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Received</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Total</string>
+ </property>
+ </column>
+ <property name="name">
+ <cstring>tableYearly</cstring>
+ </property>
+ <property name="numRows">
+ <number>1</number>
+ </property>
+ <property name="numCols">
+ <number>3</number>
+ </property>
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>buttonClearYearly</cstring>
+ </property>
+ <property name="text">
+ <string>Clear yearly statistics</string>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ </widget>
+ <spacer row="1" column="0">
+ <property name="name">
+ <cstring>spacer28</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>211</width>
+ <height>31</height>
+ </size>
+ </property>
+ </spacer>
+ <spacer row="1" column="2">
+ <property name="name">
+ <cstring>spacer29</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>201</width>
+ <height>31</height>
+ </size>
+ </property>
+ </spacer>
+ </grid>
+</widget>
+<connections>
+ <connection>
+ <sender>buttonClose</sender>
+ <signal>clicked()</signal>
+ <receiver>InterfaceStatisticsDlg</receiver>
+ <slot>close()</slot>
+ </connection>
+</connections>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/src/knemod/interfacestatusdialog.cpp b/src/knemod/interfacestatusdialog.cpp
new file mode 100644
index 0000000..87260af
--- /dev/null
+++ b/src/knemod/interfacestatusdialog.cpp
@@ -0,0 +1,308 @@
+/* This file is part of KNemo
+ Copyright (C) 2004, 2006 Percy Leonhardt <[email protected]>
+
+ KNemo is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of
+ the License, or (at your option) any later version.
+
+ KNemo 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 Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <qtimer.h>
+#include <qlabel.h>
+#include <qstring.h>
+#include <qgroupbox.h>
+#include <qdatetime.h>
+#include <qtabwidget.h>
+
+#include <kdebug.h>
+#include <kconfig.h>
+#include <klocale.h>
+#include <kglobal.h>
+#include <kiconloader.h>
+#include <kactivelabel.h>
+#include <kio/global.h>
+
+#include "data.h"
+#include "interface.h"
+#include "interfacestatistics.h"
+#include "interfacestatusdialog.h"
+
+InterfaceStatusDialog::InterfaceStatusDialog( Interface* interface, QWidget* parent, const char* name )
+ : InterfaceStatusDlg( parent, name ),
+ mPosInitialized( false ),
+ mInterface( interface )
+{
+ setIcon( SmallIcon( "knemo" ) );
+ setCaption( interface->getName() + " " + i18n( "Interface Status" ) );
+ updateDialog();
+ if ( interface->getData().available )
+ {
+ enableNetworkGroups( 0 );
+ }
+ else
+ {
+ disableNetworkGroups( 0 );
+ }
+ if ( !interface->getData().wirelessDevice )
+ {
+ QWidget* wirelessTab = tabWidget->page( 2 );
+ tabWidget->removePage( wirelessTab );
+ delete wirelessTab;
+ }
+
+ if ( !interface->getSettings().activateStatistics )
+ {
+ setStatisticsGroupEnabled( false );
+ }
+
+ // Restore window size and position.
+ KConfig* config = new KConfig( "knemorc", false );
+ if ( config->hasGroup( "Interface_" + mInterface->getName() ) )
+ {
+ config->setGroup( "Interface_" + mInterface->getName() );
+ if ( config->hasKey( "StatusX" ) && config->hasKey( "StatusY" ) )
+ {
+ mPos.setX( config->readNumEntry( "StatusX" ) );
+ mPos.setY( config->readNumEntry( "StatusY" ) );
+ mPosInitialized = true;
+ }
+ if ( config->hasKey( "StatusWidth" ) && config->hasKey( "StatusHeight" ) )
+ resize( config->readNumEntry( "StatusWidth" ),
+ config->readNumEntry( "StatusHeight" ) );
+ }
+ delete config;
+
+ statisticsChanged();
+
+ mTimer = new QTimer();
+ connect( mTimer, SIGNAL( timeout() ), this, SLOT( updateDialog() ) );
+ mTimer->start( 1000 );
+}
+
+InterfaceStatusDialog::~InterfaceStatusDialog()
+{
+ mTimer->stop();
+ delete mTimer;
+
+ // Store window size and position.
+ KConfig* config = new KConfig( "knemorc", false );
+ if ( config->hasGroup( "Interface_" + mInterface->getName() ) )
+ {
+ config->setGroup( "Interface_" + mInterface->getName() );
+ config->writeEntry( "StatusX", x() );
+ config->writeEntry( "StatusY", y() );
+ config->writeEntry( "StatusWidth", width() );
+ config->writeEntry( "StatusHeight", height() );
+ config->sync();
+ }
+ delete config;
+}
+
+void InterfaceStatusDialog::hide()
+{
+ mPos = pos();
+ mPosInitialized = true;
+ QDialog::hide();
+}
+
+void InterfaceStatusDialog::show()
+{
+ QDialog::show();
+ /**
+ * mPosInitialized should always be true, except when
+ * starting KNemo for the very first time.
+ */
+ if ( mPosInitialized )
+ move( mPos );
+}
+
+void InterfaceStatusDialog::setStatisticsGroupEnabled( bool enabled )
+{
+ groupBoxStatistics->setEnabled( enabled );
+}
+
+void InterfaceStatusDialog::updateDialog()
+{
+ InterfaceData& data = mInterface->getData();
+ InterfaceSettings& settings = mInterface->getSettings();
+
+ // connection tab
+ textLabelInterface->setText( mInterface->getName() );
+ textLabelAlias->setText( settings.alias );
+ if ( data.available )
+ {
+ textLabelStatus->setText( i18n( "Connection established." ) );
+ int upsecs = mInterface->getStartTime().secsTo( QDateTime::currentDateTime() );
+ int updays = upsecs / 86400; // don't use QDateTime::daysTo() because
+ // we only want complete days
+
+ QString uptime;
+ if ( updays == 1 )
+ uptime = "1 day, ";
+ else if ( updays > 1 )
+ uptime = QString( "%1 days, " ).arg( updays );
+
+ upsecs -= 86400 * updays; // we only want the seconds of today
+ int hrs = upsecs / 3600;
+ int mins = ( upsecs - hrs * 3600 ) / 60;
+ int secs = upsecs - hrs * 3600 - mins * 60;
+ QString time;
+ time.sprintf( "%02d:%02d:%02d", hrs, mins, secs );
+ uptime += time;
+ textLabelUptime->setText( uptime );
+ }
+ else if ( data.existing )
+ {
+ textLabelStatus->setText( i18n( "Not connected." ) );
+ textLabelUptime->setText( "00:00:00" );
+ }
+ else
+ {
+ textLabelStatus->setText( i18n( "Not existing." ) );
+ textLabelUptime->setText( "00:00:00" );
+ }
+
+ if ( data.available )
+ {
+ // ip tab
+ textLabelIP->setText( data.ipAddress );
+ textLabelSubnet->setText( data.subnetMask );
+ if ( mInterface->getType() == Interface::ETHERNET )
+ {
+ variableLabel1->setText( i18n( "Broadcast Address:" ) );
+ variableText1->setText( data.broadcastAddress );
+ variableLabel2->setText( i18n( "Default Gateway:" ) );
+ variableText2->setText( data.defaultGateway );
+ variableLabel3->setText( i18n( "HW-Address:" ) );
+ variableText3->setText( data.hwAddress );
+ }
+ else if ( mInterface->getType() == Interface::PPP )
+ {
+ variableLabel1->setText( i18n( "PtP-Address:" ) );
+ variableText1->setText( data.ptpAddress );
+ variableLabel2->setText( QString::null );
+ variableText2->setText( QString::null );
+ variableLabel3->setText( QString::null );
+ variableText3->setText( QString::null );
+ }
+ else
+ {
+ // shouldn't happen
+ variableLabel1->setText( QString::null );
+ variableText1->setText( QString::null );
+ variableLabel2->setText( QString::null );
+ variableText2->setText( QString::null );
+ variableLabel3->setText( QString::null );
+ variableText3->setText( QString::null );
+ }
+
+ // traffic tab
+ textLabelPacketsSend->setText( QString::number( data.txPackets ) );
+ textLabelPacketsReceived->setText( QString::number( data.rxPackets ) );
+ textLabelBytesSend->setText( data.txString );
+ textLabelBytesReceived->setText( data.rxString );
+ unsigned long bytesPerSecond = data.outgoingBytes / mInterface->getGeneralData().pollInterval;
+ textLabelSpeedSend->setText( KIO::convertSize( bytesPerSecond ) + i18n( "/s" ) );
+ bytesPerSecond = data.incomingBytes / mInterface->getGeneralData().pollInterval;
+ textLabelSpeedReceived->setText( KIO::convertSize( bytesPerSecond ) + i18n( "/s" ) );
+
+ if ( data.wirelessDevice )
+ {
+ WirelessData& wdata = mInterface->getWirelessData();
+
+ // wireless tab
+ textLabelESSID->setText( wdata.essid );
+ textLabelAccessPoint->setText( wdata.accessPoint );
+ textLabelNickName->setText( wdata.nickName );
+ textLabelMode->setText( wdata.mode );
+ textLabelFreqChannel->setText( wdata.frequency + " [" + wdata.channel + "]" );
+ textLabelBitRate->setText( wdata.bitRate );
+ textLabelLinkQuality->setText( wdata.linkQuality + "%" );
+ if ( wdata.encryption == true )
+ {
+ textLabelEncryption->setText( i18n( "active" ) );
+ }
+ else
+ {
+ textLabelEncryption->setText( i18n( "off" ) );
+ }
+ }
+ }
+}
+
+void InterfaceStatusDialog::enableNetworkGroups( int )
+{
+ groupBoxIP->setEnabled( true );
+ groupBoxCurrentConnection->setEnabled( true );
+}
+
+void InterfaceStatusDialog::disableNetworkGroups( int )
+{
+ groupBoxIP->setEnabled( false );
+ groupBoxCurrentConnection->setEnabled( false );
+
+ // clear IP group
+ textLabelIP->setText( QString::null );
+ textLabelSubnet->setText( QString::null );
+ variableText1->setText( QString::null );
+ variableText2->setText( QString::null );
+ variableText3->setText( QString::null );
+
+ // clear current connection group
+ textLabelPacketsSend->setText( QString::null );
+ textLabelPacketsReceived->setText( QString::null );
+ textLabelBytesSend->setText( QString::null );
+ textLabelBytesReceived->setText( QString::null );
+ textLabelSpeedSend->setText( QString::null );
+ textLabelSpeedReceived->setText( QString::null );
+
+ // clear wireless tab
+ if ( mInterface->getData().wirelessDevice )
+ {
+ textLabelESSID->setText( QString::null );
+ textLabelAccessPoint->setText( QString::null );
+ textLabelNickName->setText( QString::null );
+ textLabelMode->setText( QString::null );
+ textLabelFreqChannel->setText( QString::null );
+ textLabelBitRate->setText( QString::null );
+ textLabelLinkQuality->setText( QString::null );
+ textLabelEncryption->setText( QString::null );
+ }
+}
+
+void InterfaceStatusDialog::statisticsChanged()
+{
+ InterfaceStatistics* statistics = mInterface->getStatistics();
+
+ if ( statistics == 0 )
+ {
+ return;
+ }
+
+ const StatisticEntry* entry = statistics->getCurrentDay();
+ textLabelTodaySent->setText( KIO::convertSize( entry->txBytes ) );
+ textLabelTodayReceived->setText( KIO::convertSize( entry->rxBytes ) );
+ textLabelTodayTotal->setText( KIO::convertSize( entry->txBytes + entry->rxBytes ) );
+
+ entry = statistics->getCurrentMonth();
+ textLabelMonthSent->setText( KIO::convertSize( entry->txBytes ) );
+ textLabelMonthReceived->setText( KIO::convertSize( entry->rxBytes ) );
+ textLabelMonthTotal->setText( KIO::convertSize( entry->txBytes + entry->rxBytes ) );
+
+ entry = statistics->getCurrentYear();
+ textLabelYearSent->setText( KIO::convertSize( entry->txBytes ) );
+ textLabelYearReceived->setText( KIO::convertSize( entry->rxBytes ) );
+ textLabelYearTotal->setText( KIO::convertSize( entry->txBytes + entry->rxBytes ) );
+}
+
+#include "interfacestatusdialog.moc"
diff --git a/src/knemod/interfacestatusdialog.h b/src/knemod/interfacestatusdialog.h
new file mode 100644
index 0000000..3b15362
--- /dev/null
+++ b/src/knemod/interfacestatusdialog.h
@@ -0,0 +1,89 @@
+/* This file is part of KNemo
+ Copyright (C) 2004, 2006 Percy Leonhardt <[email protected]>
+
+ KNemo is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of
+ the License, or (at your option) any later version.
+
+ KNemo 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 Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef INTERFACESTATUSDIALOG_H
+#define INTERFACESTATUSDIALOG_H
+
+#include <qwidget.h>
+
+#include "interfacestatusdlg.h"
+
+class QTimer;
+class Interface;
+
+/**
+ * This class serves as the main window for KNemo. It handles the
+ * menus, toolbars, and status bars.
+ *
+ * @short Main window class
+ * @author Percy Leonhardt <[email protected]>
+ */
+
+class InterfaceStatusDialog : public InterfaceStatusDlg
+{
+ Q_OBJECT
+public:
+ /**
+ * Default Constructor
+ */
+ InterfaceStatusDialog( Interface* interface,
+ QWidget* parent = 0L, const char* name = 0L );
+
+ /**
+ * Default Destructor
+ */
+ virtual ~InterfaceStatusDialog();
+
+ /**
+ * Implemented to store position.
+ */
+ void hide();
+ void show();
+
+ /**
+ * Enable or disable the statistics group when the user turned statistics on or off.
+ */
+ void setStatisticsGroupEnabled( bool enabled );
+
+public slots:
+ /**
+ * Enable the network groups when the interface is connected
+ */
+ void enableNetworkGroups( int );
+ /**
+ * Disable the network groups when the interface is not connected
+ */
+ void disableNetworkGroups( int );
+ /**
+ * Update the statistics tab when data changed
+ */
+ void statisticsChanged();
+
+private slots:
+ void updateDialog();
+
+private:
+ QPoint mPos;
+ bool mPosInitialized;
+
+ QTimer* mTimer;
+ Interface* mInterface;
+};
+
+#endif // INTERFACESTATUSDIALOG_H
diff --git a/src/knemod/interfacestatusdlg.ui b/src/knemod/interfacestatusdlg.ui
new file mode 100644
index 0000000..f707ef3
--- /dev/null
+++ b/src/knemod/interfacestatusdlg.ui
@@ -0,0 +1,759 @@
+<!DOCTYPE UI><UI version="3.2" stdsetdef="1">
+<class>InterfaceStatusDlg</class>
+<widget class="QDialog">
+ <property name="name">
+ <cstring>InterfaceStatusDlg</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>292</width>
+ <height>328</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Interface Status</string>
+ </property>
+ <property name="sizeGripEnabled">
+ <bool>true</bool>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QTabWidget">
+ <property name="name">
+ <cstring>tabWidget</cstring>
+ </property>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>connection</cstring>
+ </property>
+ <attribute name="title">
+ <string>Connection</string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <spacer row="5" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>spacer4</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>81</width>
+ <height>30</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QGroupBox" row="4" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>groupBoxIP</cstring>
+ </property>
+ <property name="title">
+ <string>IP</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="0" column="1">
+ <property name="name">
+ <cstring>textLabelIP</cstring>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="1">
+ <property name="name">
+ <cstring>textLabelSubnet</cstring>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ </widget>
+ <widget class="QLabel" row="2" column="1">
+ <property name="name">
+ <cstring>variableText1</cstring>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ </widget>
+ <widget class="QLabel" row="3" column="1">
+ <property name="name">
+ <cstring>variableText2</cstring>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ </widget>
+ <widget class="QLabel" row="4" column="1">
+ <property name="name">
+ <cstring>variableText3</cstring>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel4_2</cstring>
+ </property>
+ <property name="text">
+ <string>IP-Address:</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>textLabel5_2</cstring>
+ </property>
+ <property name="text">
+ <string>Subnet Mask:</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="2" column="0">
+ <property name="name">
+ <cstring>variableLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>Broadcast Address:</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="3" column="0">
+ <property name="name">
+ <cstring>variableLabel2</cstring>
+ </property>
+ <property name="text">
+ <string>Default Gateway:</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="4" column="0">
+ <property name="name">
+ <cstring>variableLabel3</cstring>
+ </property>
+ <property name="text">
+ <string>HW-Address:</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QLabel" row="1" column="1">
+ <property name="name">
+ <cstring>textLabelAlias</cstring>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="1">
+ <property name="name">
+ <cstring>textLabelInterface</cstring>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ </widget>
+ <widget class="QLabel" row="2" column="1">
+ <property name="name">
+ <cstring>textLabelStatus</cstring>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ </widget>
+ <widget class="QLabel" row="3" column="1">
+ <property name="name">
+ <cstring>textLabelUptime</cstring>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel24</cstring>
+ </property>
+ <property name="text">
+ <string>Interface:</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>textLabel14</cstring>
+ </property>
+ <property name="text">
+ <string>Alias:</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="2" column="0">
+ <property name="name">
+ <cstring>textLabel2</cstring>
+ </property>
+ <property name="text">
+ <string>Status:</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="3" column="0">
+ <property name="name">
+ <cstring>textLabel3</cstring>
+ </property>
+ <property name="text">
+ <string>Uptime:</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>traffic</cstring>
+ </property>
+ <attribute name="title">
+ <string>Traffic</string>
+ </attribute>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>groupBoxCurrentConnection</cstring>
+ </property>
+ <property name="title">
+ <string>Current connection</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="0" column="2">
+ <property name="name">
+ <cstring>textLabel8</cstring>
+ </property>
+ <property name="text">
+ <string>Received</string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="1">
+ <property name="name">
+ <cstring>textLabel7</cstring>
+ </property>
+ <property name="text">
+ <string>Sent</string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="1">
+ <property name="name">
+ <cstring>textLabelPacketsSend</cstring>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="2">
+ <property name="name">
+ <cstring>textLabelPacketsReceived</cstring>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>textLabel9</cstring>
+ </property>
+ <property name="text">
+ <string>Packets:</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="2" column="0">
+ <property name="name">
+ <cstring>textLabel10</cstring>
+ </property>
+ <property name="text">
+ <string>Bytes:</string>
+ </property>
+ <property name="alignment">
+ <set>AlignTop</set>
+ </property>
+ </widget>
+ <widget class="QLabel" row="3" column="0">
+ <property name="name">
+ <cstring>textLabel10_2</cstring>
+ </property>
+ <property name="text">
+ <string>Speed:</string>
+ </property>
+ <property name="alignment">
+ <set>AlignTop</set>
+ </property>
+ </widget>
+ <widget class="QLabel" row="2" column="1">
+ <property name="name">
+ <cstring>textLabelBytesSend</cstring>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ </widget>
+ <widget class="QLabel" row="2" column="2">
+ <property name="name">
+ <cstring>textLabelBytesReceived</cstring>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ </widget>
+ <widget class="QLabel" row="3" column="1">
+ <property name="name">
+ <cstring>textLabelSpeedSend</cstring>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ </widget>
+ <widget class="QLabel" row="3" column="2">
+ <property name="name">
+ <cstring>textLabelSpeedReceived</cstring>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>groupBoxStatistics</cstring>
+ </property>
+ <property name="title">
+ <string>Statistics</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>textLabel9_2_2</cstring>
+ </property>
+ <property name="text">
+ <string>Today:</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="3" column="0">
+ <property name="name">
+ <cstring>textLabel10_2_2_2</cstring>
+ </property>
+ <property name="text">
+ <string>This year:</string>
+ </property>
+ <property name="alignment">
+ <set>AlignTop</set>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="2">
+ <property name="name">
+ <cstring>textLabel8_2_3</cstring>
+ </property>
+ <property name="text">
+ <string>Received</string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="3">
+ <property name="name">
+ <cstring>textLabel8_2_2_2</cstring>
+ </property>
+ <property name="text">
+ <string>Total</string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ </widget>
+ <widget class="QLabel" row="2" column="0">
+ <property name="name">
+ <cstring>textLabel10_3_2</cstring>
+ </property>
+ <property name="text">
+ <string>This month:</string>
+ </property>
+ <property name="alignment">
+ <set>AlignTop</set>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="2">
+ <property name="name">
+ <cstring>textLabelTodayReceived</cstring>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ </widget>
+ <widget class="QLabel" row="2" column="2">
+ <property name="name">
+ <cstring>textLabelMonthReceived</cstring>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ </widget>
+ <widget class="QLabel" row="3" column="2">
+ <property name="name">
+ <cstring>textLabelYearReceived</cstring>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="3">
+ <property name="name">
+ <cstring>textLabelTodayTotal</cstring>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ </widget>
+ <widget class="QLabel" row="2" column="3">
+ <property name="name">
+ <cstring>textLabelMonthTotal</cstring>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ </widget>
+ <widget class="QLabel" row="3" column="3">
+ <property name="name">
+ <cstring>textLabelYearTotal</cstring>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="1">
+ <property name="name">
+ <cstring>textLabel7_2_2</cstring>
+ </property>
+ <property name="text">
+ <string>Sent</string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ </widget>
+ <widget class="QLabel" row="2" column="1">
+ <property name="name">
+ <cstring>textLabelMonthSent</cstring>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ </widget>
+ <widget class="QLabel" row="3" column="1">
+ <property name="name">
+ <cstring>textLabelYearSent</cstring>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="1">
+ <property name="name">
+ <cstring>textLabelTodaySent</cstring>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer4_3</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>81</width>
+ <height>16</height>
+ </size>
+ </property>
+ </spacer>
+ </vbox>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>wireless</cstring>
+ </property>
+ <attribute name="title">
+ <string>Wireless</string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel3_2</cstring>
+ </property>
+ <property name="text">
+ <string>Connected to:</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="1">
+ <property name="name">
+ <cstring>textLabelESSID</cstring>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>textLabel3_2_2_2</cstring>
+ </property>
+ <property name="text">
+ <string>Access point:</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="1">
+ <property name="name">
+ <cstring>textLabelAccessPoint</cstring>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ </widget>
+ <widget class="QLabel" row="5" column="0">
+ <property name="name">
+ <cstring>textLabel3_2_4</cstring>
+ </property>
+ <property name="text">
+ <string>Bit Rate:</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="4" column="0">
+ <property name="name">
+ <cstring>textLabelFC</cstring>
+ </property>
+ <property name="text">
+ <string>Frequency [Channel]:</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="3" column="0">
+ <property name="name">
+ <cstring>textLabel3_2_2</cstring>
+ </property>
+ <property name="text">
+ <string>Mode:</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="5" column="1">
+ <property name="name">
+ <cstring>textLabelBitRate</cstring>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ </widget>
+ <widget class="QLabel" row="4" column="1">
+ <property name="name">
+ <cstring>textLabelFreqChannel</cstring>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ </widget>
+ <widget class="QLabel" row="3" column="1">
+ <property name="name">
+ <cstring>textLabelMode</cstring>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ </widget>
+ <widget class="QLabel" row="2" column="1">
+ <property name="name">
+ <cstring>textLabelNickName</cstring>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ </widget>
+ <widget class="QLabel" row="2" column="0">
+ <property name="name">
+ <cstring>textLabel3_2_5</cstring>
+ </property>
+ <property name="text">
+ <string>Nickname:</string>
+ </property>
+ </widget>
+ <spacer row="8" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>spacer4_4</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>81</width>
+ <height>50</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLabel" row="6" column="0">
+ <property name="name">
+ <cstring>textLabel3_2_6</cstring>
+ </property>
+ <property name="text">
+ <string>Link Quality:</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="7" column="0">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>Encryption:</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="6" column="1">
+ <property name="name">
+ <cstring>textLabelLinkQuality</cstring>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ </widget>
+ <widget class="QLabel" row="7" column="1">
+ <property name="name">
+ <cstring>textLabelEncryption</cstring>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout2</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <spacer>
+ <property name="name">
+ <cstring>spacer2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>0</width>
+ <height>21</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>buttonClose</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Close</string>
+ </property>
+ <property name="default">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer3</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>0</width>
+ <height>21</height>
+ </size>
+ </property>
+ </spacer>
+ </hbox>
+ </widget>
+ </vbox>
+</widget>
+<connections>
+ <connection>
+ <sender>buttonClose</sender>
+ <signal>clicked()</signal>
+ <receiver>InterfaceStatusDlg</receiver>
+ <slot>accept()</slot>
+ </connection>
+</connections>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/src/knemod/interfacetooltip.cpp b/src/knemod/interfacetooltip.cpp
new file mode 100644
index 0000000..77d6505
--- /dev/null
+++ b/src/knemod/interfacetooltip.cpp
@@ -0,0 +1,204 @@
+/* This file is part of KNemo
+ Copyright (C) 2004 Percy Leonhardt <[email protected]>
+
+ KNemo is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of
+ the License, or (at your option) any later version.
+
+ KNemo 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 Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <qrect.h>
+#include <qstring.h>
+
+#include <kdebug.h>
+#include <klocale.h>
+#include <kio/global.h>
+
+#include "data.h"
+#include "interface.h"
+#include "interfacetooltip.h"
+
+InterfaceToolTip::InterfaceToolTip( Interface* interface,
+ QWidget* parent )
+ : QToolTip( parent ),
+ mInterface( interface )
+{
+ setupToolTipArray();
+}
+
+InterfaceToolTip::~InterfaceToolTip()
+{
+}
+
+void InterfaceToolTip::maybeTip( const QPoint& )
+{
+ QRect rect( parentWidget()->rect() );
+ if ( !rect.isValid() )
+ return;
+
+ QString tooltip;
+ setupText( tooltip );
+ tip( rect, tooltip );
+}
+
+void InterfaceToolTip::setupText( QString& text )
+{
+ int toolTipContent = mInterface->getGeneralData().toolTipContent;
+ InterfaceData& data = mInterface->getData();
+
+ text += "<table cellspacing=0 cellpadding=0 border=0>";
+ if ( ( toolTipContent & ALIAS ) &&
+ mInterface->getSettings().alias != QString::null )
+ text += "<tr><th colspan=2 align=center>" + mInterface->getSettings().alias + "</th></tr>";
+ if ( toolTipContent & INTERFACE )
+ text += "<tr><td>" + mToolTips[0].first + "</td><td>" + mInterface->getName() + "</td></tr>";
+ if ( data.available )
+ {
+ if ( toolTipContent & STATUS )
+ text += "<tr><td>" + mToolTips[2].first + "</td><td>" + i18n( "Connection established." ) + "</td></tr>";
+ if ( toolTipContent & UPTIME )
+ {
+ int upsecs = mInterface->getStartTime().secsTo( QDateTime::currentDateTime() );
+ int updays = upsecs / 86400; // don't use QDateTime::daysTo() because
+ // we only want complete days
+
+ QString uptime;
+ if ( updays == 1 )
+ uptime = "1 day, ";
+ else if ( updays > 1 )
+ uptime = QString( "%1 days, " ).arg( updays );
+
+ upsecs -= 86400 * updays; // we only want the seconds of today
+ int hrs = upsecs / 3600;
+ int mins = ( upsecs - hrs * 3600 ) / 60;
+ int secs = upsecs - hrs * 3600 - mins * 60;
+ QString time;
+ time.sprintf( "%02d:%02d:%02d", hrs, mins, secs );
+ uptime += time;
+ text += "<tr><td>" + mToolTips[3].first + "</td><td>" + uptime + "</td></tr>";
+ }
+ }
+ else if ( data.existing )
+ {
+ if ( toolTipContent & STATUS )
+ text += "<tr><td>" + mToolTips[2].first + "</td><td>" + i18n( "Not connected." ) + "</td></tr>";
+ }
+ else
+ {
+ if ( toolTipContent & STATUS )
+ text += "<tr><td>" + mToolTips[2].first + "</td><td>" + i18n( "Not existing." ) + "</td></tr>";
+ }
+
+ if ( data.available )
+ {
+ if ( toolTipContent & IP_ADDRESS )
+ text += "<tr><td>" + mToolTips[4].first + "</td><td>" + data.ipAddress + "</td></tr>";
+ if ( toolTipContent & SUBNET_MASK )
+ text += "<tr><td>" + mToolTips[5].first + "</td><td>" + data.subnetMask + "</td></tr>";
+ if ( mInterface->getType() == Interface::ETHERNET )
+ {
+ if ( toolTipContent & BCAST_ADDRESS )
+ text += "<tr><td>" + mToolTips[18].first + "</td><td>" + data.broadcastAddress + "</td></tr>";
+ if ( toolTipContent & GATEWAY )
+ text += "<tr><td>" + mToolTips[19].first + "</td><td>" + data.defaultGateway + "</td></tr>";
+ if ( toolTipContent & HW_ADDRESS )
+ text += "<tr><td>" + mToolTips[6].first + "</td><td>" + data.hwAddress + "</td></tr>";
+ }
+ if ( mInterface->getType() == Interface::PPP )
+ {
+ if ( toolTipContent & PTP_ADDRESS )
+ text += "<tr><td>" + mToolTips[7].first + "</td><td>" + data.ptpAddress + "</td></tr>";
+ }
+ if ( toolTipContent & RX_PACKETS )
+ text += "<tr><td>" + mToolTips[8].first + "</td><td>" + QString::number( data.rxPackets ) + "</td></tr>";
+ if ( toolTipContent & TX_PACKETS )
+ text += "<tr><td>" + mToolTips[9].first + "</td><td>" + QString::number( data.txPackets ) + "</td></tr>";
+ if ( toolTipContent & RX_BYTES )
+ text += "<tr><td>" + mToolTips[10].first + "</td><td>" + data.rxString + "</td></tr>";
+ if ( toolTipContent & TX_BYTES )
+ text += "<tr><td>" + mToolTips[11].first + "</td><td>" + data.txString + "</td></tr>";
+ if ( toolTipContent & DOWNLOAD_SPEED )
+ {
+ unsigned long bytesPerSecond = data.incomingBytes / mInterface->getGeneralData().pollInterval;
+ text += "<tr><td>" + mToolTips[20].first + "</td><td>" + KIO::convertSize( bytesPerSecond ) + i18n( "/s" ) + "</td></tr>";
+ }
+ if ( toolTipContent & UPLOAD_SPEED )
+ {
+ unsigned long bytesPerSecond = data.outgoingBytes / mInterface->getGeneralData().pollInterval;
+ text += "<tr><td>" + mToolTips[21].first + "</td><td>" + KIO::convertSize( bytesPerSecond ) + i18n( "/s" ) + "</td></tr>";
+ }
+ }
+
+ if ( data.available && data.wirelessDevice )
+ {
+ WirelessData& wdata = mInterface->getWirelessData();
+ if ( toolTipContent & ESSID )
+ text += "<tr><td>" + mToolTips[12].first + "</td><td>" + wdata.essid + "</td></tr>";
+ if ( toolTipContent & MODE )
+ text += "<tr><td>" + mToolTips[13].first + "</td><td>" + wdata.mode + "</td></tr>";
+ if ( toolTipContent & FREQUENCY )
+ text += "<tr><td>" + mToolTips[14].first + "</td><td>" + wdata.frequency + "</td></tr>";
+ if ( toolTipContent & BIT_RATE )
+ text += "<tr><td>" + mToolTips[15].first + "</td><td>" + wdata.bitRate + "</td></tr>";
+ if ( toolTipContent & ACCESS_POINT )
+ text += "<tr><td>" + mToolTips[16].first + "</td><td>" + wdata.accessPoint + "</td></tr>";
+ if ( toolTipContent & LINK_QUALITY )
+ text += "<tr><td>" + mToolTips[17].first + "</td><td>" + wdata.linkQuality + "</td></tr>";
+ if ( toolTipContent & NICK_NAME )
+ text += "<tr><td>" + mToolTips[22].first + "</td><td>" + wdata.nickName + "</td></tr>";
+ if ( toolTipContent & ENCRYPTION )
+ {
+ if ( wdata.encryption == true )
+ {
+ text += "<tr><td>" + mToolTips[23].first + "</td><td>" + i18n( "active" ) + "</td></tr>";
+ }
+ else
+ {
+ text += "<tr><td>" + mToolTips[23].first + "</td><td>" + i18n( "off" ) + "</td></tr>";
+ }
+ }
+ }
+ text += "</table>";
+}
+
+void InterfaceToolTip::setupToolTipArray()
+{
+ // Cannot make this data static as the i18n macro doesn't seem
+ // to work when called to early i.e. before setting the catalogue.
+ mToolTips[0] = QPair<QString, int>( i18n( "Interface" ), INTERFACE );
+ mToolTips[1] = QPair<QString, int>( i18n( "Alias" ), ALIAS );
+ mToolTips[2] = QPair<QString, int>( i18n( "Status" ), STATUS );
+ mToolTips[3] = QPair<QString, int>( i18n( "Uptime" ), UPTIME );
+ mToolTips[4] = QPair<QString, int>( i18n( "IP-Address" ), IP_ADDRESS );
+ mToolTips[5] = QPair<QString, int>( i18n( "Subnet Mask" ), SUBNET_MASK );
+ mToolTips[6] = QPair<QString, int>( i18n( "HW-Address" ), HW_ADDRESS );
+ mToolTips[7] = QPair<QString, int>( i18n( "PtP-Address" ), PTP_ADDRESS );
+ mToolTips[8] = QPair<QString, int>( i18n( "Packets Received" ), RX_PACKETS );
+ mToolTips[9] = QPair<QString, int>( i18n( "Packets Sent" ), TX_PACKETS );
+ mToolTips[10] = QPair<QString, int>( i18n( "Bytes Received" ), RX_BYTES );
+ mToolTips[11] = QPair<QString, int>( i18n( "Bytes Sent" ), TX_BYTES );
+ mToolTips[12] = QPair<QString, int>( i18n( "ESSID" ), ESSID );
+ mToolTips[13] = QPair<QString, int>( i18n( "Mode" ), MODE );
+ mToolTips[14] = QPair<QString, int>( i18n( "Frequency" ), FREQUENCY );
+ mToolTips[15] = QPair<QString, int>( i18n( "Bit Rate" ), BIT_RATE );
+ mToolTips[16] = QPair<QString, int>( i18n( "Access Point" ), ACCESS_POINT );
+ mToolTips[17] = QPair<QString, int>( i18n( "Link Quality" ), LINK_QUALITY );
+ mToolTips[18] = QPair<QString, int>( i18n( "Broadcast Address" ), BCAST_ADDRESS );
+ mToolTips[19] = QPair<QString, int>( i18n( "Default Gateway" ), LINK_QUALITY );
+ mToolTips[20] = QPair<QString, int>( i18n( "Download Speed" ), DOWNLOAD_SPEED );
+ mToolTips[21] = QPair<QString, int>( i18n( "Upload Speed" ), UPLOAD_SPEED );
+ mToolTips[22] = QPair<QString, int>( i18n( "Nickname" ), NICK_NAME );
+ mToolTips[23] = QPair<QString, int>( i18n( "Encryption" ), ENCRYPTION );
+ mToolTips[24] = QPair<QString, int>();
+}
+
diff --git a/src/knemod/interfacetooltip.h b/src/knemod/interfacetooltip.h
new file mode 100644
index 0000000..7c4dbd9
--- /dev/null
+++ b/src/knemod/interfacetooltip.h
@@ -0,0 +1,72 @@
+/* This file is part of KNemo
+ Copyright (C) 2004 Percy Leonhardt <[email protected]>
+
+ KNemo is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of
+ the License, or (at your option) any later version.
+
+ KNemo 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 Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef INTERFACETOOLTIP_H
+#define INTERFACETOOLTIP_H
+
+#include <qpair.h>
+#include <qtooltip.h>
+
+class Interface;
+
+/**
+ * This call is responsible for displaying the tooltip of an
+ * interface icon. It is derived from QToolTip and overwrites
+ * the function maybeTip(const QPoint & p) to update the tooltip
+ * text just before it is going to be displayed.
+ *
+ * @short Display tooltip according to user settings
+ * @author Percy Leonhardt <[email protected]>
+ */
+
+class InterfaceToolTip : public QToolTip
+{
+public:
+ /**
+ * Default Constructor
+ */
+ InterfaceToolTip( Interface* interface, QWidget* parent = 0L );
+
+ /**
+ * Default Destructor
+ */
+ virtual ~InterfaceToolTip();
+
+ /**
+ * From the Qt documentation:
+ * It is called when there is a possibility that a tool tip should
+ * be shown and must decide whether there is a tool tip for the point p
+ * in the widget that this QToolTip object relates to. If so, maybeTip()
+ * must call tip() with the rectangle the tip applies to, the tip's text
+ * and optionally the QToolTipGroup details and the geometry in screen
+ * coordinates.
+ */
+ void maybeTip( const QPoint& );
+
+private:
+ void setupText( QString& text );
+ void setupToolTipArray();
+
+ // the interface this tooltip belongs to
+ Interface* mInterface;
+ // the tooltip text for each information
+ QPair<QString, int> mToolTips[25];
+};
+
+#endif // INTERFACETOOLTIP_H
diff --git a/src/knemod/interfacetray.cpp b/src/knemod/interfacetray.cpp
new file mode 100644
index 0000000..5e2e154
--- /dev/null
+++ b/src/knemod/interfacetray.cpp
@@ -0,0 +1,121 @@
+/* This file is part of KNemo
+ Copyright (C) 2004, 2005 Percy Leonhardt <[email protected]>
+
+ KNemo is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of
+ the License, or (at your option) any later version.
+
+ KNemo 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 Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <qwidget.h>
+
+#include <kdebug.h>
+#include <kglobal.h>
+#include <klocale.h>
+#include <kbugreport.h>
+#include <kaboutdata.h>
+#include <kpopupmenu.h>
+#include <kiconloader.h>
+#include <kapplication.h>
+#include <kaboutapplication.h>
+#include <kactioncollection.h>
+
+#include "interfacetray.h"
+
+static const char description[] =
+ I18N_NOOP( "KNemo - the KDE Network Monitor" );
+
+static const char version[] = "0.4.8";
+
+InterfaceTray::InterfaceTray( const QString& ifname,
+ QWidget* parent, const char* name )
+ : KSystemTray( parent, name )
+{
+ actionCollection()->clear(); // remove the quit entry
+
+ KPopupMenu* popup = contextMenu();
+ int id = popup->idAt( 0 );
+ popup->changeTitle( id, SmallIcon( "knemo" ),
+ "KNemo - " + ifname );
+ popup->insertItem( SmallIcon( "knemo" ),
+ i18n( "&About KNemo" ), this,
+ SLOT( showAboutDialog() ) );
+ popup->insertItem( i18n( "&Report Bug..." ), this,
+ SLOT( showReportBugDialog() ) );
+ popup->insertSeparator();
+ popup->insertItem( SmallIcon( "configure" ),
+ i18n( "&Configure KNemo..." ), this,
+ SIGNAL( configSelected() ) );
+ popup->insertItem( SmallIcon( "ksysguard" ),
+ i18n( "&Open Traffic Plotter" ), this,
+ SLOT( showGraph() ) );
+}
+
+InterfaceTray::~InterfaceTray()
+{
+}
+
+void InterfaceTray::mousePressEvent( QMouseEvent* e )
+{
+ if ( !rect().contains( e->pos() ) )
+ return;
+
+ switch( e->button() )
+ {
+ case LeftButton:
+ emit leftClicked();
+ break;
+ case MidButton:
+ emit graphSelected( true );
+ break;
+ case RightButton:
+ KSystemTray::mousePressEvent( e );
+ break;
+ default:
+ break;
+ }
+}
+
+void InterfaceTray::showAboutDialog()
+{
+ KAboutData data ( "knemo", I18N_NOOP( "KNemo" ), version,
+ description, KAboutData::License_GPL,
+ "(c) 2004, 2005, 2006 Percy Leonhardt\n\nSignal plotter taken from KSysGuard\n(c) 1999 - 2002, Chris Schlaeger",
+ 0,
+ "http://extragear.kde.org/apps/knemo/"
+ );
+ data.addAuthor( "Percy Leonhardt", I18N_NOOP( "Author" ),
+ data.addCredit( "Michael Olbrich", I18N_NOOP( "Threshold support" ),
+ data.addCredit( "Chris Schlaeger", I18N_NOOP( "Signal plotter" ),
+
+ KAboutApplication about( &data );
+ about.setProgramLogo( DesktopIcon( "knemo" ) );
+ about.exec();
+}
+
+void InterfaceTray::showReportBugDialog()
+{
+ KAboutData data ( "knemo", I18N_NOOP( "KNemo" ), version );
+ KBugReport bugReport( 0, true, &data );
+ bugReport.exec();
+}
+
+void InterfaceTray::showGraph()
+{
+ emit graphSelected( false );
+}
+
+#include "interfacetray.moc"
diff --git a/src/knemod/interfacetray.h b/src/knemod/interfacetray.h
new file mode 100644
index 0000000..b783c45
--- /dev/null
+++ b/src/knemod/interfacetray.h
@@ -0,0 +1,81 @@
+/* This file is part of KNemo
+ Copyright (C) 2004 Percy Leonhardt <[email protected]>
+
+ KNemo is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of
+ the License, or (at your option) any later version.
+
+ KNemo 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 Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef INTERFACETRAY_H
+#define INTERFACETRAY_H
+
+#include <ksystemtray.h>
+
+class QWidget;
+
+/**
+ * This class is the graphical representation of and interface
+ * in the system tray. It has a customized context menu and will
+ * emit a signal when the user left clicks the icon.
+ *
+ * @short Graphical representation of the tray icon
+ * @author Percy Leonhardt <[email protected]>
+ */
+
+class InterfaceTray : public KSystemTray
+{
+ Q_OBJECT
+public:
+ /**
+ * Default Constructor
+ */
+ InterfaceTray( const QString& ifname,
+ QWidget* parent = 0L, const char* name = 0L );
+
+ /**
+ * Default Destructor
+ */
+ virtual ~InterfaceTray();
+
+signals:
+ void leftClicked();
+ void graphSelected( bool );
+ void configSelected();
+ void startCommandSelected();
+ void stopCommandSelected();
+
+protected:
+ void mousePressEvent( QMouseEvent* e );
+
+protected slots:
+ /**
+ * Will display the about dialog if the user selected
+ * the corresponding entry in the context menu.
+ */
+ void showAboutDialog();
+
+ /**
+ * Will display the report bug dialog that allows the user
+ * to send a bug report by mail.
+ */
+ void showReportBugDialog();
+
+ /**
+ * Opens the traffic plotter or brings it to the front if it
+ * is hidden.
+ */
+ void showGraph();
+};
+
+#endif // INTERFACETRAY_H
diff --git a/src/knemod/knemod.desktop b/src/knemod/knemod.desktop
new file mode 100644
index 0000000..d4f41e6
--- /dev/null
+++ b/src/knemod/knemod.desktop
@@ -0,0 +1,41 @@
+[Desktop Entry]
+Encoding=UTF-8
+Type=Service
+ServiceTypes=KDEDModule
+X-KDE-ModuleType=Library
+X-KDE-Library=knemod
+X-KDE-FactoryName=knemod
+X-KDE-Kded-autoload=true
+X-KDE-Kded-load-on-demand=false
+Name=KNemo
+Name[de]=Netzwerküberwachung KNemo
+Name[sv]=Knemo
+Name[xx]=xxKNemoxx
+Comment=KDE Network Monitor
+Comment[bg]=Монитор на мрежата
+Comment[br]=Eveshaer ar rouedad evit KDE
+Comment[cs]=KDE monitor sítě
+Comment[da]=KDE's netværksovervågning
+Comment[de]=KDE-Netzwerkmonitor
+Comment[el]=Επίβλεψη δικτύου του KDE
+Comment[es]=Monitor de red de KDE
+Comment[et]=KDE võrgumonitor
+Comment[ga]=Monatóir Líonra KDE
+Comment[gl]=Un Monitor de Rede para KDE
+Comment[it]=Monitor di rete di KDE
+Comment[ja]=KDE ネットワークモニタ
+Comment[ka]=KDE-ის ქსელის მონიტორი
+Comment[lt]=Tinklo įrenginių stebėjimo KDE programa
+Comment[nl]=KDE networkmonitor
+Comment[pa]=KDE ਨੈਟਵਰਕ ਨਿਗਰਾਨ
+Comment[pl]=Monitor sieci dla KDE
+Comment[pt]=Monitor da Rede do KDE
+Comment[pt_BR]=Monitor de Rede do KDE
+Comment[ru]=Сетевой монитор KDE
+Comment[sr]=Надгледање мреже за KDE
+Comment[sr@Latn]=Nadgledanje mreže za KDE
+Comment[sv]=KDE-nätverksövervakning
+Comment[tr]=KDE Ağ İzleyici
+Comment[uk]=Монітор мережі для KDE
+Comment[xx]=xxKDE Network Monitorxx
+Comment[zh_CN]=KDE 网络监视器
diff --git a/src/knemod/knemodaemon.cpp b/src/knemod/knemodaemon.cpp
new file mode 100644
index 0000000..e5a7f88
--- /dev/null
+++ b/src/knemod/knemodaemon.cpp
@@ -0,0 +1,344 @@
+/* This file is part of KNemo
+ Copyright (C) 2004, 2006 Percy Leonhardt <[email protected]>
+
+ KNemo is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of
+ the License, or (at your option) any later version.
+
+ KNemo 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 Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <qtimer.h>
+#include <qstrlist.h>
+
+#include <kdebug.h>
+#include <kglobal.h>
+#include <klocale.h>
+#include <kconfig.h>
+#include <kprocess.h>
+#include <kinstance.h>
+#include <kmessagebox.h>
+#include <kstandarddirs.h>
+
+#include "knemodaemon.h"
+#include "interface.h"
+#include "backendbase.h"
+#include "daemonregistry.h"
+
+QString KNemoDaemon::sSelectedInterface = QString::null;
+
+extern "C" {
+ KDE_EXPORT KDEDModule *create_knemod(const QCString &name) {
+ return new KNemoDaemon(name);
+ }
+}
+
+KNemoDaemon::KNemoDaemon( const QCString& name )
+ : KDEDModule( name ),
+ mColorVLines( 0x04FB1D ),
+ mColorHLines( 0x04FB1D ),
+ mColorIncoming( 0x1889FF ),
+ mColorOutgoing( 0xFF7F08 ),
+ mColorBackground( 0x313031 ),
+ mInstance( new KInstance( "knemo" ) ),
+ mNotifyInstance( new KNotifyClient::Instance( mInstance ) )
+{
+ KGlobal::locale()->insertCatalogue( "knemod" );
+ readConfig();
+
+ // select the backend from the config file
+ KConfig* config = new KConfig( "knemorc", true );
+ config->setGroup( "General" );
+ mBackendName = config->readEntry( "Backend", "Nettools" );
+ delete config;
+
+ bool foundBackend = false;
+ int i;
+ for ( i = 0; DaemonRegistry[i].name != QString::null; i++ )
+ {
+ if ( DaemonRegistry[i].name == mBackendName )
+ {
+ foundBackend = true;
+ break;
+ }
+ }
+
+ if ( !foundBackend )
+ {
+ i = 0; // use the first backend (Nettools)
+ }
+ mBackend = ( *DaemonRegistry[i].function )( mInterfaceDict );
+
+ mInterfaceDict.setAutoDelete( true );
+
+ mPollTimer = new QTimer();
+ connect( mPollTimer, SIGNAL( timeout() ), this, SLOT( updateInterfaces() ) );
+ mPollTimer->start( mGeneralData.pollInterval * 1000 );
+}
+
+KNemoDaemon::~KNemoDaemon()
+{
+ mPollTimer->stop();
+ delete mPollTimer;
+ delete mBackend;
+ delete mNotifyInstance;
+ delete mInstance;
+
+ QDictIterator<Interface> it( mInterfaceDict );
+ for ( ; it.current(); )
+ {
+ mInterfaceDict.remove( it.currentKey() );
+ // 'remove' already advanced the iterator to the next item
+ }
+}
+
+void KNemoDaemon::readConfig()
+{
+ KConfig* config = new KConfig( "knemorc", true );
+
+ config->setGroup( "General" );
+ mGeneralData.pollInterval = config->readNumEntry( "PollInterval", 1 );
+ mGeneralData.saveInterval = config->readNumEntry( "SaveInterval", 60 );
+ mGeneralData.statisticsDir = config->readEntry( "StatisticsDir", KGlobal::dirs()->saveLocation( "data", "knemo/" ) );
+ mGeneralData.toolTipContent = config->readNumEntry( "ToolTipContent", 2 );
+ QStrList list;
+ int numEntries = config->readListEntry( "Interfaces", list );
+
+ if ( numEntries == 0 )
+ return;
+
+ char* interface;
+ for ( interface = list.first(); interface; interface = list.next() )
+ {
+ Interface* iface = new Interface( interface, mGeneralData, mPlotterSettings );
+ QString group( "Interface_" );
+ group += interface;
+ if ( config->hasGroup( group ) )
+ {
+ config->setGroup( group );
+ InterfaceSettings& settings = iface->getSettings();
+ settings.alias = config->readEntry( "Alias" );
+ settings.iconSet = config->readNumEntry( "IconSet", 0 );
+ settings.customCommands = config->readBoolEntry( "CustomCommands" );
+ settings.hideWhenNotAvailable = config->readBoolEntry( "HideWhenNotAvailable" );
+ settings.hideWhenNotExisting = config->readBoolEntry( "HideWhenNotExisting" );
+ settings.activateStatistics = config->readBoolEntry( "ActivateStatistics" );
+ settings.trafficThreshold = config->readNumEntry( "TrafficThreshold", 0 );
+ if ( settings.customCommands )
+ {
+ int numCommands = config->readNumEntry( "NumCommands" );
+ for ( int i = 0; i < numCommands; i++ )
+ {
+ QString entry;
+ InterfaceCommand cmd;
+ entry = QString( "RunAsRoot%1" ).arg( i + 1 );
+ cmd.runAsRoot = config->readBoolEntry( entry );
+ entry = QString( "Command%1" ).arg( i + 1 );
+ cmd.command = config->readEntry( entry );
+ entry = QString( "MenuText%1" ).arg( i + 1 );
+ cmd.menuText = config->readEntry( entry );
+ settings.commands.append( cmd );
+ }
+ }
+ iface->configChanged(); // important to activate the statistics
+ }
+ mInterfaceDict.insert( interface, iface );
+ }
+
+ // load the settings for the plotter
+ config->setGroup( "PlotterSettings" );
+ mPlotterSettings.pixel = config->readNumEntry( "Pixel", 1 );
+ mPlotterSettings.count = config->readNumEntry( "Count", 5 );
+ mPlotterSettings.distance = config->readNumEntry( "Distance", 30 );
+ mPlotterSettings.fontSize = config->readNumEntry( "FontSize", 8 );
+ mPlotterSettings.minimumValue = config->readNumEntry( "MinimumValue", 0 );
+ mPlotterSettings.maximumValue = config->readNumEntry( "MaximumValue", 1 );
+ mPlotterSettings.labels = config->readBoolEntry( "Labels", true );
+ mPlotterSettings.topBar = config->readBoolEntry( "TopBar", false );
+ mPlotterSettings.showIncoming = config->readBoolEntry( "ShowIncoming", true );
+ mPlotterSettings.showOutgoing = config->readBoolEntry( "ShowOutgoing", true );
+ mPlotterSettings.verticalLines = config->readBoolEntry( "VerticalLines", true );
+ mPlotterSettings.horizontalLines = config->readBoolEntry( "HorizontalLines", true );
+ mPlotterSettings.automaticDetection = config->readBoolEntry( "AutomaticDetection", true );
+ mPlotterSettings.verticalLinesScroll = config->readBoolEntry( "VerticalLinesScroll", true );
+ mPlotterSettings.colorVLines = config->readColorEntry( "ColorVLines", &mColorVLines );
+ mPlotterSettings.colorHLines = config->readColorEntry( "ColorHLines", &mColorHLines );
+ mPlotterSettings.colorIncoming = config->readColorEntry( "ColorIncoming", &mColorIncoming );
+ mPlotterSettings.colorOutgoing = config->readColorEntry( "ColorOutgoing", &mColorOutgoing );
+ mPlotterSettings.colorBackground = config->readColorEntry( "ColorBackground", &mColorBackground );
+
+ delete config;
+}
+
+void KNemoDaemon::reparseConfiguration()
+{
+ // Read the settings from the config file.
+ QDict<InterfaceSettings> settingsDict;
+ KConfig* config = new KConfig( "knemorc", false );
+
+ config->setGroup( "General" );
+ mGeneralData.pollInterval = config->readNumEntry( "PollInterval", 1 );
+ mGeneralData.saveInterval = config->readNumEntry( "SaveInterval", 60 );
+ mGeneralData.statisticsDir = config->readEntry( "StatisticsDir", KGlobal::dirs()->saveLocation( "data", "knemo/" ) );
+ mGeneralData.toolTipContent = config->readNumEntry( "ToolTipContent", 2 );
+
+ // restart the timer with the new interval
+ mPollTimer->changeInterval( mGeneralData.pollInterval * 1000 );
+
+ // select the backend from the config file
+ QString backend = config->readEntry( "Backend", "Nettools" );
+
+ if ( mBackendName != backend )
+ {
+ bool foundBackend = false;
+ mBackendName = backend;
+ int i;
+ for ( i = 0; DaemonRegistry[i].name != QString::null; i++ )
+ {
+ if ( DaemonRegistry[i].name == backend )
+ {
+ foundBackend = true;
+ break;
+ }
+ }
+
+ if ( foundBackend )
+ {
+ delete mBackend;
+ mBackend = ( *DaemonRegistry[i].function )( mInterfaceDict );
+ }
+ }
+
+ QStrList list;
+ int numEntries = config->readListEntry( "Interfaces", list );
+
+ if ( numEntries == 0 )
+ return;
+
+ char* interface;
+ for ( interface = list.first(); interface; interface = list.next() )
+ {
+ QString group( "Interface_" );
+ group += interface;
+ InterfaceSettings* settings = new InterfaceSettings();
+ if ( config->hasGroup( group ) )
+ {
+ config->setGroup( group );
+ settings->alias = config->readEntry( "Alias" );
+ settings->iconSet = config->readNumEntry( "IconSet", 0 );
+ settings->customCommands = config->readBoolEntry( "CustomCommands" );
+ settings->hideWhenNotAvailable = config->readBoolEntry( "HideWhenNotAvailable" );
+ settings->hideWhenNotExisting = config->readBoolEntry( "HideWhenNotExisting" );
+ settings->activateStatistics = config->readBoolEntry( "ActivateStatistics" );
+ settings->trafficThreshold = config->readNumEntry( "TrafficThreshold", 0 );
+ if ( settings->customCommands )
+ {
+ int numCommands = config->readNumEntry( "NumCommands" );
+ for ( int i = 0; i < numCommands; i++ )
+ {
+ QString entry;
+ InterfaceCommand cmd;
+ entry = QString( "RunAsRoot%1" ).arg( i + 1 );
+ cmd.runAsRoot = config->readBoolEntry( entry );
+ entry = QString( "Command%1" ).arg( i + 1 );
+ cmd.command = config->readEntry( entry );
+ entry = QString( "MenuText%1" ).arg( i + 1 );
+ cmd.menuText = config->readEntry( entry );
+ settings->commands.append( cmd );
+ }
+ }
+ }
+ settingsDict.insert( interface, settings );
+ }
+
+ // load the settings for the plotter
+ config->setGroup( "PlotterSettings" );
+ mPlotterSettings.pixel = config->readNumEntry( "Pixel", 1 );
+ mPlotterSettings.count = config->readNumEntry( "Count", 5 );
+ mPlotterSettings.distance = config->readNumEntry( "Distance", 30 );
+ mPlotterSettings.fontSize = config->readNumEntry( "FontSize", 8 );
+ mPlotterSettings.minimumValue = config->readNumEntry( "MinimumValue", 0 );
+ mPlotterSettings.maximumValue = config->readNumEntry( "MaximumValue", 1 );
+ mPlotterSettings.labels = config->readBoolEntry( "Labels", true );
+ mPlotterSettings.topBar = config->readBoolEntry( "TopBar", false );
+ mPlotterSettings.showIncoming = config->readBoolEntry( "ShowIncoming", true );
+ mPlotterSettings.showOutgoing = config->readBoolEntry( "ShowOutgoing", true );
+ mPlotterSettings.verticalLines = config->readBoolEntry( "VerticalLines", true );
+ mPlotterSettings.horizontalLines = config->readBoolEntry( "HorizontalLines", true );
+ mPlotterSettings.automaticDetection = config->readBoolEntry( "AutomaticDetection", true );
+ mPlotterSettings.verticalLinesScroll = config->readBoolEntry( "VerticalLinesScroll", true );
+ mPlotterSettings.colorVLines = config->readColorEntry( "ColorVLines", &mColorVLines );
+ mPlotterSettings.colorHLines = config->readColorEntry( "ColorHLines", &mColorHLines );
+ mPlotterSettings.colorIncoming = config->readColorEntry( "ColorIncoming", &mColorIncoming );
+ mPlotterSettings.colorOutgoing = config->readColorEntry( "ColorOutgoing", &mColorOutgoing );
+ mPlotterSettings.colorBackground = config->readColorEntry( "ColorBackground", &mColorBackground );
+
+ // Remove all interfaces that the user deleted from
+ // the internal list.
+ QDictIterator<Interface> it( mInterfaceDict );
+ for ( ; it.current(); )
+ {
+ if ( settingsDict.find( it.currentKey() ) == 0 )
+ {
+ config->deleteGroup( "Interface_" + it.currentKey() );
+ mInterfaceDict.remove( it.currentKey() );
+ // 'remove' already advanced the iterator to the next item
+ }
+ else
+ ++it;
+ }
+ config->sync();
+ delete config;
+
+ // Update all other interfaces and add new ones.
+ QDictIterator<InterfaceSettings> setIt( settingsDict );
+ for ( ; setIt.current(); ++setIt )
+ {
+ Interface* iface;
+ if ( mInterfaceDict.find( setIt.currentKey() ) == 0 )
+ {
+ iface = new Interface( setIt.currentKey(), mGeneralData, mPlotterSettings );
+ mInterfaceDict.insert( setIt.currentKey(), iface );
+ }
+ else
+ iface = mInterfaceDict[setIt.currentKey()];
+
+ InterfaceSettings& settings = iface->getSettings();
+ settings.alias = setIt.current()->alias;
+ settings.iconSet = setIt.current()->iconSet;
+ settings.customCommands = setIt.current()->customCommands;
+ settings.hideWhenNotAvailable = setIt.current()->hideWhenNotAvailable;
+ settings.hideWhenNotExisting = setIt.current()->hideWhenNotExisting;
+ settings.activateStatistics = setIt.current()->activateStatistics;
+ settings.trafficThreshold = setIt.current()->trafficThreshold;
+ settings.commands = setIt.current()->commands;
+ iface->configChanged();
+ }
+}
+
+QString KNemoDaemon::getSelectedInterface()
+{
+ // Reset the variable to avoid preselecting an interface when
+ // the user opens the control center module from the control
+ // center afterwards.
+ QString tmp = sSelectedInterface;
+ sSelectedInterface = QString::null;
+
+ return tmp;
+}
+
+void KNemoDaemon::updateInterfaces()
+{
+ mBackend->update();
+}
+
+#include "knemodaemon.moc"
diff --git a/src/knemod/knemodaemon.h b/src/knemod/knemodaemon.h
new file mode 100644
index 0000000..d62c288
--- /dev/null
+++ b/src/knemod/knemodaemon.h
@@ -0,0 +1,120 @@
+/* This file is part of KNemo
+ Copyright (C) 2004, 2006 Percy Leonhardt <[email protected]>
+
+ KNemo is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of
+ the License, or (at your option) any later version.
+
+ KNemo 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 Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KNEMODAEMON_H
+#define KNEMODAEMON_H
+
+#include <qdict.h>
+#include <qcolor.h>
+#include <qcstring.h>
+#include <qdatetime.h>
+
+#include <kdedmodule.h>
+#include <knotifyclient.h>
+
+#include "data.h"
+#include "global.h"
+
+class QTimer;
+class KInstance;
+class Interface;
+class BackendBase;
+class KNotifyClient::Instance;
+
+/**
+ * This class is the main entry point of KNemo. It reads the configuration,
+ * creates the logical interfaces and starts an interface updater. It also
+ * takes care of configuration changes by the user.
+ *
+ * @short KNemos main entry point
+ * @author Percy Leonhardt <[email protected]>
+ */
+class KNemoDaemon : public KDEDModule
+{
+ K_DCOP
+ Q_OBJECT
+public:
+ /**
+ * Default Constructor
+ */
+ KNemoDaemon( const QCString& name );
+
+ /**
+ * Default Destructor
+ */
+ virtual ~KNemoDaemon();
+
+ // tell the control center module which interface the user selected
+ static QString sSelectedInterface;
+
+k_dcop:
+ /*
+ * Called from the control center module when the user changed
+ * the settings. It updates the internal list of interfaces
+ * that should be monitored.
+ */
+ virtual void reparseConfiguration();
+
+ /* When the user selects 'Configure KNemo...' from the context
+ * menus this functions gets called from the control center
+ * module. This way the module knows for which interface the
+ * user opened the dialog and can preselect the appropriate
+ * interface in the list.
+ */
+ virtual QString getSelectedInterface();
+
+private:
+ /*
+ * Read the configuration on startup
+ */
+ void readConfig();
+
+private slots:
+ /**
+ * trigger the backend to update the interface informations
+ */
+ void updateInterfaces();
+
+private:
+ QColor mColorVLines;
+ QColor mColorHLines;
+ QColor mColorIncoming;
+ QColor mColorOutgoing;
+ QColor mColorBackground;
+
+ // every time this timer expires we will
+ // gather new informations from the backend
+ QTimer* mPollTimer;
+ // our own instance
+ KInstance* mInstance;
+ // needed so that KNotifyClient::event will work
+ KNotifyClient::Instance* mNotifyInstance;
+ // application wide settings are stored here
+ GeneralData mGeneralData;
+ // settings for the traffic plotter are stored here
+ PlotterSettings mPlotterSettings;
+ // the name of backend we currently use
+ QString mBackendName;
+ // the backend used to update the interface informations
+ BackendBase* mBackend;
+ // a list of all interfaces the user wants to monitor
+ QDict<Interface> mInterfaceDict;
+};
+
+#endif // KNEMODAEMON_H
diff --git a/src/knemod/pics/Makefile.am b/src/knemod/pics/Makefile.am
new file mode 100644
index 0000000..d085bb3
--- /dev/null
+++ b/src/knemod/pics/Makefile.am
@@ -0,0 +1,2 @@
+# Install the icons into the global KDE directories
+KDE_ICON = AUTO
diff --git a/src/knemod/pics/cr16-app-knemo.png b/src/knemod/pics/cr16-app-knemo.png
new file mode 100644
index 0000000..1989704
--- /dev/null
+++ b/src/knemod/pics/cr16-app-knemo.png
Binary files differ
diff --git a/src/knemod/pics/cr22-action-network_connected.png b/src/knemod/pics/cr22-action-network_connected.png
new file mode 100644
index 0000000..86a0872
--- /dev/null
+++ b/src/knemod/pics/cr22-action-network_connected.png
Binary files differ
diff --git a/src/knemod/pics/cr22-action-network_connected_lan.png b/src/knemod/pics/cr22-action-network_connected_lan.png
new file mode 100644
index 0000000..a72c89f
--- /dev/null
+++ b/src/knemod/pics/cr22-action-network_connected_lan.png
Binary files differ
diff --git a/src/knemod/pics/cr22-action-network_connected_ppp.png b/src/knemod/pics/cr22-action-network_connected_ppp.png
new file mode 100644
index 0000000..6abcd43
--- /dev/null
+++ b/src/knemod/pics/cr22-action-network_connected_ppp.png
Binary files differ
diff --git a/src/knemod/pics/cr22-action-network_connected_wlan.png b/src/knemod/pics/cr22-action-network_connected_wlan.png
new file mode 100644
index 0000000..b7395aa
--- /dev/null
+++ b/src/knemod/pics/cr22-action-network_connected_wlan.png
Binary files differ
diff --git a/src/knemod/pics/cr22-action-network_disconnected.png b/src/knemod/pics/cr22-action-network_disconnected.png
new file mode 100644
index 0000000..d6ff91a
--- /dev/null
+++ b/src/knemod/pics/cr22-action-network_disconnected.png
Binary files differ
diff --git a/src/knemod/pics/cr22-action-network_disconnected_lan.png b/src/knemod/pics/cr22-action-network_disconnected_lan.png
new file mode 100644
index 0000000..5aad370
--- /dev/null
+++ b/src/knemod/pics/cr22-action-network_disconnected_lan.png
Binary files differ
diff --git a/src/knemod/pics/cr22-action-network_disconnected_ppp.png b/src/knemod/pics/cr22-action-network_disconnected_ppp.png
new file mode 100644
index 0000000..729f1f9
--- /dev/null
+++ b/src/knemod/pics/cr22-action-network_disconnected_ppp.png
Binary files differ
diff --git a/src/knemod/pics/cr22-action-network_disconnected_wlan.png b/src/knemod/pics/cr22-action-network_disconnected_wlan.png
new file mode 100644
index 0000000..b1da123
--- /dev/null
+++ b/src/knemod/pics/cr22-action-network_disconnected_wlan.png
Binary files differ
diff --git a/src/knemod/pics/cr22-action-network_incoming.png b/src/knemod/pics/cr22-action-network_incoming.png
new file mode 100644
index 0000000..ea4b71d
--- /dev/null
+++ b/src/knemod/pics/cr22-action-network_incoming.png
Binary files differ
diff --git a/src/knemod/pics/cr22-action-network_incoming_lan.png b/src/knemod/pics/cr22-action-network_incoming_lan.png
new file mode 100644
index 0000000..222d38d
--- /dev/null
+++ b/src/knemod/pics/cr22-action-network_incoming_lan.png
Binary files differ
diff --git a/src/knemod/pics/cr22-action-network_incoming_ppp.png b/src/knemod/pics/cr22-action-network_incoming_ppp.png
new file mode 100644
index 0000000..51d144d
--- /dev/null
+++ b/src/knemod/pics/cr22-action-network_incoming_ppp.png
Binary files differ
diff --git a/src/knemod/pics/cr22-action-network_incoming_wlan.png b/src/knemod/pics/cr22-action-network_incoming_wlan.png
new file mode 100644
index 0000000..b471965
--- /dev/null
+++ b/src/knemod/pics/cr22-action-network_incoming_wlan.png
Binary files differ
diff --git a/src/knemod/pics/cr22-action-network_outgoing.png b/src/knemod/pics/cr22-action-network_outgoing.png
new file mode 100644
index 0000000..e813f93
--- /dev/null
+++ b/src/knemod/pics/cr22-action-network_outgoing.png
Binary files differ
diff --git a/src/knemod/pics/cr22-action-network_outgoing_lan.png b/src/knemod/pics/cr22-action-network_outgoing_lan.png
new file mode 100644
index 0000000..fa3b0c5
--- /dev/null
+++ b/src/knemod/pics/cr22-action-network_outgoing_lan.png
Binary files differ
diff --git a/src/knemod/pics/cr22-action-network_outgoing_ppp.png b/src/knemod/pics/cr22-action-network_outgoing_ppp.png
new file mode 100644
index 0000000..751b788
--- /dev/null
+++ b/src/knemod/pics/cr22-action-network_outgoing_ppp.png
Binary files differ
diff --git a/src/knemod/pics/cr22-action-network_outgoing_wlan.png b/src/knemod/pics/cr22-action-network_outgoing_wlan.png
new file mode 100644
index 0000000..7cd6ef5
--- /dev/null
+++ b/src/knemod/pics/cr22-action-network_outgoing_wlan.png
Binary files differ
diff --git a/src/knemod/pics/cr22-action-network_traffic.png b/src/knemod/pics/cr22-action-network_traffic.png
new file mode 100644
index 0000000..0d2a4b2
--- /dev/null
+++ b/src/knemod/pics/cr22-action-network_traffic.png
Binary files differ
diff --git a/src/knemod/pics/cr22-action-network_traffic_lan.png b/src/knemod/pics/cr22-action-network_traffic_lan.png
new file mode 100644
index 0000000..f41a05a
--- /dev/null
+++ b/src/knemod/pics/cr22-action-network_traffic_lan.png
Binary files differ
diff --git a/src/knemod/pics/cr22-action-network_traffic_ppp.png b/src/knemod/pics/cr22-action-network_traffic_ppp.png
new file mode 100644
index 0000000..0dce305
--- /dev/null
+++ b/src/knemod/pics/cr22-action-network_traffic_ppp.png
Binary files differ
diff --git a/src/knemod/pics/cr22-action-network_traffic_wlan.png b/src/knemod/pics/cr22-action-network_traffic_wlan.png
new file mode 100644
index 0000000..634b2d3
--- /dev/null
+++ b/src/knemod/pics/cr22-action-network_traffic_wlan.png
Binary files differ
diff --git a/src/knemod/pics/cr32-app-knemo.png b/src/knemod/pics/cr32-app-knemo.png
new file mode 100644
index 0000000..ac2d6dd
--- /dev/null
+++ b/src/knemod/pics/cr32-app-knemo.png
Binary files differ
diff --git a/src/knemod/signalplotter.cpp b/src/knemod/signalplotter.cpp
new file mode 100644
index 0000000..4945a2d
--- /dev/null
+++ b/src/knemod/signalplotter.cpp
@@ -0,0 +1,706 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 1999 - 2002 Chris Schlaeger <[email protected]>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of version 2 of the GNU General Public
+ License as published by the Free Software Foundation
+
+ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ KSysGuard is currently maintained by Chris Schlaeger <[email protected]>.
+ Please do not commit any changes without consulting me first. Thanks!
+
+ $Id: SignalPlotter.cc,v 1.7 2004/01/04 13:43:48 waba Exp $
+*/
+
+#include <math.h>
+#include <string.h>
+
+#include <qpainter.h>
+#include <qpixmap.h>
+
+#include <kdebug.h>
+#include <kconfig.h>
+
+#include "signalplotter.h"
+
+static inline int min( int a, int b )
+{
+ return ( a < b ? a : b );
+}
+
+SignalPlotter::SignalPlotter( QWidget *parent, const char *name )
+ : QDialog( parent, name ),
+ mPosInitialized( false ),
+ mName( name )
+{
+ // Auto deletion does not work for pointer to arrays.
+ mBeamData.setAutoDelete( false );
+
+ setBackgroundMode( NoBackground );
+
+ mSamples = 0;
+ mMinValue = mMaxValue = 0.0;
+ mUseAutoRange = true;
+
+ mGraphStyle = GRAPH_POLYGON;
+
+ // Anything smaller than this does not make sense.
+ setMinimumSize( 16, 16 );
+ setSizePolicy( QSizePolicy( QSizePolicy::Expanding,
+ QSizePolicy::Expanding, false ) );
+
+ mShowVerticalLines = true;
+ mVerticalLinesColor = QColor( 0x04FB1D );
+ mVerticalLinesDistance = 30;
+ mVerticalLinesScroll = true;
+ mVerticalLinesOffset = 0;
+ mHorizontalScale = 1;
+
+ mShowHorizontalLines = true;
+ mHorizontalLinesColor = QColor( 0x04FB1D );
+ mHorizontalLinesCount = 5;
+
+ mShowLabels = true;
+ mShowTopBar = false;
+ mFontSize = 8;
+
+ mBackgroundColor = QColor( 0x313031 );
+
+ // Restore window size and position.
+ KConfig* config = new KConfig( "knemorc", false );
+ if ( config->hasGroup( "Interface_" + mName ) )
+ {
+ config->setGroup( "Interface_" + mName );
+ if ( config->hasKey( "PlotterX" ) && config->hasKey( "PlotterY" ) )
+ {
+ mPos.setX( config->readNumEntry( "PlotterX" ) );
+ mPos.setY( config->readNumEntry( "PlotterY" ) );
+ mPosInitialized = true;
+ }
+ if ( config->hasKey( "PlotterWidth" ) && config->hasKey( "PlotterHeight" ) )
+ resize( config->readNumEntry( "PlotterWidth" ),
+ config->readNumEntry( "PlotterHeight" ) );
+ }
+ delete config;
+}
+
+SignalPlotter::~SignalPlotter()
+{
+ for ( double* p = mBeamData.first(); p; p = mBeamData.next() )
+ delete [] p;
+
+ // Store window size and position.
+ KConfig* config = new KConfig( "knemorc", false );
+ if ( config->hasGroup( "Interface_" + mName ) )
+ {
+ config->setGroup( "Interface_" + mName );
+ config->writeEntry( "PlotterX", x() );
+ config->writeEntry( "PlotterY", y() );
+ config->writeEntry( "PlotterWidth", width() );
+ config->writeEntry( "PlotterHeight", height() );
+ config->sync();
+ }
+ delete config;
+}
+
+void SignalPlotter::hide()
+{
+ mPos = pos();
+ mPosInitialized = true;
+ QDialog::hide();
+}
+
+void SignalPlotter::show()
+{
+ QDialog::show();
+ /**
+ * mPosInitialized should always be true, except when
+ * starting KNemo for the very first time.
+ */
+ if ( mPosInitialized )
+ move( mPos );
+}
+
+bool SignalPlotter::addBeam( const QColor &color )
+{
+ double* d = new double[ mSamples ];
+ memset( d, 0, sizeof(double) * mSamples );
+ mBeamData.append( d );
+ mBeamColor.append( color );
+
+ return true;
+}
+
+void SignalPlotter::addSample( const QValueList<double>& sampleBuf )
+{
+ if ( mBeamData.count() != sampleBuf.count() )
+ return;
+
+ double* d;
+ if ( mUseAutoRange ) {
+ double sum = 0;
+ for ( d = mBeamData.first(); d; d = mBeamData.next() ) {
+ sum += d[ 0 ];
+ if ( sum < mMinValue )
+ mMinValue = sum;
+ if ( sum > mMaxValue )
+ mMaxValue = sum;
+ }
+ }
+
+ /* If the vertical lines are scrolling, increment the offset
+ * so they move with the data. The vOffset / hScale confusion
+ * is because v refers to Vertical Lines, and h to the horizontal
+ * distance between the vertical lines. */
+ if ( mVerticalLinesScroll ) {
+ mVerticalLinesOffset = ( mVerticalLinesOffset + mHorizontalScale)
+ % mVerticalLinesDistance;
+ }
+
+ // Shift data buffers one sample down and insert new samples.
+ QValueList<double>::ConstIterator s;
+ for ( d = mBeamData.first(), s = sampleBuf.begin(); d; d = mBeamData.next(), ++s ) {
+ memmove( d, d + 1, ( mSamples - 1 ) * sizeof( double ) );
+ d[ mSamples - 1 ] = *s;
+ }
+
+ update();
+}
+
+void SignalPlotter::changeRange( int beam, double min, double max )
+{
+ // Only the first beam affects range calculation.
+ if ( beam > 1 )
+ return;
+
+ mMinValue = min;
+ mMaxValue = max;
+}
+
+QValueList<QColor> &SignalPlotter::beamColors()
+{
+ return mBeamColor;
+}
+
+void SignalPlotter::removeBeam( uint pos )
+{
+ mBeamColor.remove( mBeamColor.at( pos ) );
+ mBeamData.remove( pos );
+}
+
+void SignalPlotter::setTitle( const QString &title )
+{
+ mTitle = title;
+}
+
+QString SignalPlotter::title() const
+{
+ return mTitle;
+}
+
+void SignalPlotter::setUseAutoRange( bool value )
+{
+ mUseAutoRange = value;
+}
+
+bool SignalPlotter::useAutoRange() const
+{
+ return mUseAutoRange;
+}
+
+void SignalPlotter::setMinValue( double min )
+{
+ mMinValue = min;
+}
+
+double SignalPlotter::minValue() const
+{
+ return ( mUseAutoRange ? 0 : mMinValue );
+}
+
+void SignalPlotter::setMaxValue( double max )
+{
+ mMaxValue = max;
+}
+
+double SignalPlotter::maxValue() const
+{
+ return ( mUseAutoRange ? 0 : mMaxValue );
+}
+
+void SignalPlotter::setGraphStyle( uint style )
+{
+ mGraphStyle = style;
+}
+
+uint SignalPlotter::graphStyle() const
+{
+ return mGraphStyle;
+}
+
+void SignalPlotter::setHorizontalScale( uint scale )
+{
+ if (scale == mHorizontalScale)
+ return;
+
+ mHorizontalScale = scale;
+ if (isVisible())
+ updateDataBuffers();
+}
+
+uint SignalPlotter::horizontalScale() const
+{
+ return mHorizontalScale;
+}
+
+void SignalPlotter::setShowVerticalLines( bool value )
+{
+ mShowVerticalLines = value;
+}
+
+bool SignalPlotter::showVerticalLines() const
+{
+ return mShowVerticalLines;
+}
+
+void SignalPlotter::setVerticalLinesColor( const QColor &color )
+{
+ mVerticalLinesColor = color;
+}
+
+QColor SignalPlotter::verticalLinesColor() const
+{
+ return mVerticalLinesColor;
+}
+
+void SignalPlotter::setVerticalLinesDistance( int distance )
+{
+ mVerticalLinesDistance = distance;
+}
+
+int SignalPlotter::verticalLinesDistance() const
+{
+ return mVerticalLinesDistance;
+}
+
+void SignalPlotter::setVerticalLinesScroll( bool value )
+{
+ mVerticalLinesScroll = value;
+}
+
+bool SignalPlotter::verticalLinesScroll() const
+{
+ return mVerticalLinesScroll;
+}
+
+void SignalPlotter::setShowHorizontalLines( bool value )
+{
+ mShowHorizontalLines = value;
+}
+
+bool SignalPlotter::showHorizontalLines() const
+{
+ return mShowHorizontalLines;
+}
+
+void SignalPlotter::setHorizontalLinesColor( const QColor &color )
+{
+ mHorizontalLinesColor = color;
+}
+
+QColor SignalPlotter::horizontalLinesColor() const
+{
+ return mHorizontalLinesColor;
+}
+
+void SignalPlotter::setHorizontalLinesCount( int count )
+{
+ mHorizontalLinesCount = count;
+}
+
+int SignalPlotter::horizontalLinesCount() const
+{
+ return mHorizontalLinesCount;
+}
+
+void SignalPlotter::setShowLabels( bool value )
+{
+ mShowLabels = value;
+}
+
+bool SignalPlotter::showLabels() const
+{
+ return mShowLabels;
+}
+
+void SignalPlotter::setShowTopBar( bool value )
+{
+ mShowTopBar = value;
+}
+
+bool SignalPlotter::showTopBar() const
+{
+ return mShowTopBar;
+}
+
+void SignalPlotter::setFontSize( int size )
+{
+ mFontSize = size;
+}
+
+int SignalPlotter::fontSize() const
+{
+ return mFontSize;
+}
+
+void SignalPlotter::setBackgroundColor( const QColor &color )
+{
+ mBackgroundColor = color;
+}
+
+QColor SignalPlotter::backgroundColor() const
+{
+ return mBackgroundColor;
+}
+
+void SignalPlotter::resizeEvent( QResizeEvent* )
+{
+ Q_ASSERT( width() > 2 );
+
+ updateDataBuffers();
+}
+
+void SignalPlotter::updateDataBuffers()
+{
+ /* Since the data buffers for the beams are equal in size to the
+ * width of the widget minus 2 we have to enlarge or shrink the
+ * buffers accordingly when a resize occures. To have a nicer
+ * display we try to keep as much data as possible. Data that is
+ * lost due to shrinking the buffers cannot be recovered on
+ * enlarging though. */
+
+ /* Determine new number of samples first.
+ * +0.5 to ensure rounding up
+ * +2 for extra data points so there is
+ * 1) no wasted space and
+ * 2) no loss of precision when drawing the first data point. */
+ uint newSampleNum = static_cast<uint>( ( ( width() - 2 ) /
+ mHorizontalScale ) + 2.5 );
+
+ // overlap between the old and the new buffers.
+ int overlap = min( mSamples, newSampleNum );
+
+ for ( uint i = 0; i < mBeamData.count(); ++i ) {
+ double* nd = new double[ newSampleNum ];
+
+ // initialize new part of the new buffer
+ if ( newSampleNum > (uint)overlap )
+ memset( nd, 0, sizeof( double ) * ( newSampleNum - overlap ) );
+
+ // copy overlap from old buffer to new buffer
+ memcpy( nd + ( newSampleNum - overlap ), mBeamData.at( i ) +
+ ( mSamples - overlap ), overlap * sizeof( double ) );
+
+ mBeamData.remove( i );
+ mBeamData.insert( i, nd );
+ }
+
+ mSamples = newSampleNum;
+}
+
+void SignalPlotter::paintEvent( QPaintEvent* )
+{
+ uint w = width();
+ uint h = height();
+
+ /* Do not do repaints when the widget is not yet setup properly. */
+ if ( w <= 2 )
+ return;
+
+ QPixmap pm( w, h );
+ QPainter p;
+ p.begin( &pm, this );
+
+ pm.fill( mBackgroundColor );
+ /* Draw white line along the bottom and the right side of the
+ * widget to create a 3D like look. */
+ p.setPen( QColor( colorGroup().light() ) );
+ p.drawLine( 0, h - 1, w - 1, h - 1 );
+ p.drawLine( w - 1, 0, w - 1, h - 1 );
+
+ p.setClipRect( 1, 1, w - 2, h - 2 );
+ double range = mMaxValue - mMinValue;
+
+ /* If the range is too small we will force it to 1.0 since it
+ * looks a lot nicer. */
+ if ( range < 0.000001 )
+ range = 1.0;
+
+ double minValue = mMinValue;
+ if ( mUseAutoRange ) {
+ if ( mMinValue != 0.0 ) {
+ double dim = pow( 10, floor( log10( fabs( mMinValue ) ) ) ) / 2;
+ if ( mMinValue < 0.0 )
+ minValue = dim * floor( mMinValue / dim );
+ else
+ minValue = dim * ceil( mMinValue / dim );
+ range = mMaxValue - minValue;
+ if ( range < 0.000001 )
+ range = 1.0;
+ }
+ // Massage the range so that the grid shows some nice values.
+ double step = range / mHorizontalLinesCount;
+ double dim = pow( 10, floor( log10( step ) ) ) / 2;
+ range = dim * ceil( step / dim ) * mHorizontalLinesCount;
+ }
+ double maxValue = minValue + range;
+
+ int top = 0;
+ if ( mShowTopBar && h > ( mFontSize + 2 + mHorizontalLinesCount * 10 ) ) {
+ /* Draw horizontal bar with current sensor values at top of display. */
+ p.setPen( mHorizontalLinesColor );
+ int x0 = w / 2;
+ p.setFont( QFont( p.font().family(), mFontSize ) );
+ top = p.fontMetrics().height();
+ h -= top;
+ int h0 = top - 2;
+
+ // JJ 2005-07-18: show numerical in/out values in the top bar --->
+ double *d1 = mBeamData.first();
+ double UploadSpeed = 0;
+ if(d1)
+ UploadSpeed = d1[ w - 3 ]; // read value from graph data
+
+ double *d2 = mBeamData.next();
+ double DownloadSpeed = 0;
+ if(d2)
+ DownloadSpeed = d2[ w - 3 ]; // read value from graph data
+
+ // The left side of the top bar is now divided into three sections:
+ // - name of interface (original title)
+ // - download speed (numerically, from the value shown by the bar on the right)
+ // - upload speed (numerically, from the value shown by the bar on the right)
+
+ // title
+ p.drawText(0, 0, x0/3, top - 2, Qt::AlignCenter, mTitle );
+
+ QValueList<QColor>::Iterator col_speeds;
+ col_speeds = mBeamColor.begin();
+ QColor UploadColor = *(col_speeds++);
+ QColor DownloadColor = *(col_speeds);
+
+ // download speed
+ QString DownloadSpeedText;
+ DownloadSpeedText.sprintf("in: %0.2f KB/s", DownloadSpeed);
+ p.setPen( DownloadColor );
+ p.drawText(x0/3, 0, x0/3, top - 2, Qt::AlignCenter, DownloadSpeedText );
+
+ // upload speed
+ QString UploadSpeedText;
+ UploadSpeedText.sprintf("out: %0.2f KB/s", UploadSpeed);
+ p.setPen( UploadColor );
+ p.drawText(2*x0/3, 0, x0/3, top - 2, Qt::AlignCenter, UploadSpeedText );
+
+ // restore correct pen color for the separator lines
+ p.setPen( mHorizontalLinesColor );
+ // <--- JJ 2005-07-18
+
+ p.drawLine( x0 - 1, 1, x0 - 1, h0 );
+ p.drawLine( 0, top - 1, w - 2, top - 1 );
+
+ double bias = -minValue;
+ double scaleFac = ( w - x0 - 2 ) / range;
+ QValueList<QColor>::Iterator col;
+ col = mBeamColor.begin();
+ for ( double* d = mBeamData.first(); d; d = mBeamData.next(), ++col ) {
+ int start = x0 + (int)( bias * scaleFac );
+ int end = x0 + (int)( ( bias += d[ w - 3 ] ) * scaleFac );
+ /* If the rect is wider than 2 pixels we draw only the last
+ * pixels with the bright color. The rest is painted with
+ * a 50% darker color. */
+ if ( end - start > 1 ) {
+ p.setPen( (*col).dark( 150 ) );
+ p.setBrush( (*col).dark( 150 ) );
+ p.drawRect( start, 1, end - start, h0 );
+ p.setPen( *col );
+ p.drawLine( end, 1, end, h0 );
+ } else if ( start - end > 1 ) {
+ p.setPen( (*col).dark( 150 ) );
+ p.setBrush( (*col).dark( 150 ) );
+ p.drawRect( end, 1, start - end, h0 );
+ p.setPen( *col );
+ p.drawLine( end, 1, end, h0 );
+ } else {
+ p.setPen( *col );
+ p.drawLine( start, 1, start, h0 );
+ }
+ }
+ }
+
+ /* Draw scope-like grid vertical lines */
+ if ( mShowVerticalLines && w > 60 ) {
+ p.setPen( mVerticalLinesColor );
+ for ( uint x = mVerticalLinesOffset; x < ( w - 2 ); x += mVerticalLinesDistance )
+ p.drawLine( w - x, top, w - x, h + top - 2 );
+ }
+
+ /* In autoRange mode we determine the range and plot the values in
+ * one go. This is more efficiently than running through the
+ * buffers twice but we do react on recently discarded samples as
+ * well as new samples one plot too late. So the range is not
+ * correct if the recently discarded samples are larger or smaller
+ * than the current extreme values. But we can probably live with
+ * this. */
+ if ( mUseAutoRange )
+ mMinValue = mMaxValue = 0.0;
+
+ /* Plot stacked values */
+ double scaleFac = ( h - 2 ) / range;
+ if ( mGraphStyle == GRAPH_ORIGINAL ) {
+ int xPos = 0;
+ for ( int i = 0; i < mSamples; i++, xPos += mHorizontalScale ) {
+ double bias = -minValue;
+ QValueList<QColor>::Iterator col;
+ col = mBeamColor.begin();
+ double sum = 0.0;
+ for ( double* d = mBeamData.first(); d; d = mBeamData.next(), ++col ) {
+ if ( mUseAutoRange ) {
+ sum += d[ i ];
+ if ( sum < mMinValue )
+ mMinValue = sum;
+ if ( sum > mMaxValue )
+ mMaxValue = sum;
+ }
+ int start = top + h - 2 - (int)( bias * scaleFac );
+ int end = top + h - 2 - (int)( ( bias + d[ i ] ) * scaleFac );
+ bias += d[ i ];
+ /* If the line is longer than 2 pixels we draw only the last
+ * 2 pixels with the bright color. The rest is painted with
+ * a 50% darker color. */
+ if ( end - start > 2 ) {
+ p.fillRect( xPos, start, mHorizontalScale, end - start - 1, (*col).dark( 150 ) );
+ p.fillRect( xPos, end - 1, mHorizontalScale, 2, *col );
+ } else if ( start - end > 2 ) {
+ p.fillRect( xPos, start, mHorizontalScale, end - start + 1, (*col).dark( 150 ) );
+ p.fillRect( xPos, end + 1, mHorizontalScale, 2, *col );
+ } else
+ p.fillRect( xPos, start, mHorizontalScale, end - start, *col );
+
+ }
+ }
+ } else if ( mGraphStyle == GRAPH_POLYGON ) {
+ int *prevVals = new int[ mBeamData.count() ];
+ int hack[ 4 ] = { 0, 0, 0, 0 };
+ int x1 = w - ( ( mSamples + 1 ) * mHorizontalScale );
+
+ for ( int i = 0; i < mSamples; i++ ) {
+ QValueList<QColor>::Iterator col;
+ col = mBeamColor.begin();
+ double sum = 0.0;
+ int y = top + h - 2;
+ int oldY = top + h;
+ int oldPrevY = oldY;
+ int height = 0;
+ int j = 0;
+ int jMax = mBeamData.count() - 1;
+ x1 += mHorizontalScale;
+ int x2 = x1 + mHorizontalScale;
+
+ for ( double* d = mBeamData.first(); d; d = mBeamData.next(), ++col, j++ ) {
+ if ( mUseAutoRange ) {
+ sum += d[ i ];
+ if ( sum < mMinValue )
+ mMinValue = sum;
+ if ( sum > mMaxValue )
+ mMaxValue = sum;
+ }
+ height = (int)( ( d[ i ] - minValue ) * scaleFac );
+ y -= height;
+
+ /* If the line is longer than 2 pixels we draw only the last
+ * 2 pixels with the bright color. The rest is painted with
+ * a 50% darker color. */
+ QPen lastPen = QPen( p.pen() );
+ p.setPen( (*col).dark( 150 ) );
+ p.setBrush( (*col).dark( 150 ) );
+ QPointArray pa( 4 );
+ int prevY = ( i == 0 ) ? y : prevVals[ j ];
+ pa.putPoints( 0, 1, x1, prevY );
+ pa.putPoints( 1, 1, x2, y );
+ pa.putPoints( 2, 1, x2, oldY );
+ pa.putPoints( 3, 1, x1, oldPrevY );
+ p.drawPolygon( pa );
+ p.setPen( lastPen );
+ if ( jMax == 0 ) {
+ // draw as normal, no deferred drawing req'd.
+ p.setPen( *col );
+ p.drawLine( x1, prevY, x2, y );
+ } else if ( j == jMax ) {
+ // draw previous values and current values
+ p.drawLine( hack[ 0 ], hack[ 1 ], hack[ 2 ], hack[ 3 ] );
+ p.setPen( *col );
+ p.drawLine( x1, prevY, x2, y );
+ } else if ( j == 0 ) {
+ // save values only
+ hack[ 0 ] = x1;
+ hack[ 1 ] = prevY;
+ hack[ 2 ] = x2;
+ hack[ 3 ] = y;
+ p.setPen( *col );
+ } else {
+ p.drawLine( hack[ 0 ], hack[ 1 ], hack[ 2 ], hack[ 3 ] );
+ hack[ 0 ] = x1;
+ hack[ 1 ] = prevY;
+ hack[ 2 ] = x2;
+ hack[ 3 ] = y;
+ p.setPen( *col );
+ }
+
+ prevVals[ j ] = y;
+ oldY = y;
+ oldPrevY = prevY;
+ }
+ }
+
+ delete[] prevVals;
+ }
+
+ /* Draw horizontal lines and values. Lines are drawn when the
+ * height is greater than 10 times hCount + 1, values are shown
+ * when width is greater than 60 */
+ if ( mShowHorizontalLines && h > ( 10 * ( mHorizontalLinesCount + 1 ) ) ) {
+ p.setPen( mHorizontalLinesColor );
+ p.setFont( QFont( p.font().family(), mFontSize ) );
+ QString val;
+ for ( uint y = 1; y < mHorizontalLinesCount; y++ ) {
+ p.drawLine( 0, top + y * ( h / mHorizontalLinesCount ), w - 2,
+ top + y * ( h / mHorizontalLinesCount ) );
+ if ( mShowLabels && h > ( mFontSize + 1 ) * ( mHorizontalLinesCount + 1 )
+ && w > 60 ) {
+ val = QString( "%1" ).arg( maxValue - y * ( range / mHorizontalLinesCount ) );
+ p.drawText( 6, top + y * ( h / mHorizontalLinesCount ) - 1, val );
+ }
+ }
+
+ if ( mShowLabels && h > ( mFontSize + 1 ) * ( mHorizontalLinesCount + 1 )
+ && w > 60 ) {
+ val = QString( "%1" ).arg( minValue );
+ p.drawText( 6, top + h - 2, val );
+ }
+ }
+
+ p.end();
+ bitBlt( this, 0, 0, &pm );
+}
+
+#include "signalplotter.moc"
diff --git a/src/knemod/signalplotter.h b/src/knemod/signalplotter.h
new file mode 100644
index 0000000..f0dabfb
--- /dev/null
+++ b/src/knemod/signalplotter.h
@@ -0,0 +1,160 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 1999 - 2001 Chris Schlaeger <[email protected]>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of version 2 of the GNU General Public
+ License as published by the Free Software Foundation.
+
+ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ KSysGuard is currently maintained by Chris Schlaeger <[email protected]>.
+ Please do not commit any changes without consulting me first. Thanks!
+
+ $Id: SignalPlotter.h,v 1.5 2004/01/04 13:43:48 waba Exp $
+*/
+
+#ifndef KSG_SIGNALPLOTTER_H
+#define KSG_SIGNALPLOTTER_H
+
+#include <qpoint.h>
+#include <qdialog.h>
+#include <qptrlist.h>
+#include <qstring.h>
+#include <qvaluelist.h>
+
+#define GRAPH_POLYGON 0
+#define GRAPH_ORIGINAL 1
+
+class QColor;
+
+class SignalPlotter : public QDialog
+{
+ Q_OBJECT
+
+ public:
+ SignalPlotter( QWidget *parent = 0, const char *name = 0 );
+ ~SignalPlotter();
+
+ /**
+ * Implemented to store position.
+ */
+ void hide();
+ void show();
+
+ bool addBeam( const QColor &color );
+ void addSample( const QValueList<double> &samples );
+
+ void removeBeam( uint pos );
+
+ void changeRange( int beam, double min, double max );
+
+ QValueList<QColor> &beamColors();
+
+ void setTitle( const QString &title );
+ QString title() const;
+
+ void setUseAutoRange( bool value );
+ bool useAutoRange() const;
+
+ void setMinValue( double min );
+ double minValue() const;
+
+ void setMaxValue( double max );
+ double maxValue() const;
+
+ void setGraphStyle( uint style );
+ uint graphStyle() const;
+
+ void setHorizontalScale( uint scale );
+ uint horizontalScale() const;
+
+ void setShowVerticalLines( bool value );
+ bool showVerticalLines() const;
+
+ void setVerticalLinesColor( const QColor &color );
+ QColor verticalLinesColor() const;
+
+ void setVerticalLinesDistance( int distance );
+ int verticalLinesDistance() const;
+
+ void setVerticalLinesScroll( bool value );
+ bool verticalLinesScroll() const;
+
+ void setShowHorizontalLines( bool value );
+ bool showHorizontalLines() const;
+
+ void setHorizontalLinesColor( const QColor &color );
+ QColor horizontalLinesColor() const;
+
+ void setHorizontalLinesCount( int count );
+ int horizontalLinesCount() const;
+
+ void setShowLabels( bool value );
+ bool showLabels() const;
+
+ void setShowTopBar( bool value );
+ bool showTopBar() const;
+
+ void setFontSize( int size );
+ int fontSize() const;
+
+ void setBackgroundColor( const QColor &color );
+ QColor backgroundColor() const;
+
+ protected:
+ void updateDataBuffers();
+
+ virtual void resizeEvent( QResizeEvent* );
+ virtual void paintEvent( QPaintEvent* );
+
+ private:
+ QPoint mPos;
+ bool mPosInitialized;
+
+ double mMinValue;
+ double mMaxValue;
+ bool mUseAutoRange;
+
+ uint mGraphStyle;
+
+ bool mShowVerticalLines;
+ QColor mVerticalLinesColor;
+ uint mVerticalLinesDistance;
+ bool mVerticalLinesScroll;
+ uint mVerticalLinesOffset;
+ uint mHorizontalScale;
+
+ bool mShowHorizontalLines;
+ QColor mHorizontalLinesColor;
+ uint mHorizontalLinesCount;
+
+ bool mShowLabels;
+ bool mShowTopBar;
+ uint mFontSize;
+
+ QColor mBackgroundColor;
+
+ QPtrList<double> mBeamData;
+ QValueList<QColor> mBeamColor;
+
+ int mSamples;
+
+ /**
+ * The name of the interface.
+ * Needed to store the geometry of the plotter in the right
+ * group of the config file.
+ */
+ QString mName;
+ QString mTitle;
+};
+
+#endif