Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

network.cpp

Go to the documentation of this file.
00001 /**********************************************************************
00002 ** Copyright (C) 2000-2002 Trolltech AS.  All rights reserved.
00003 **
00004 ** This file is part of the Qtopia Environment.
00005 **
00006 ** This file may be distributed and/or modified under the terms of the
00007 ** GNU General Public License version 2 as published by the Free Software
00008 ** Foundation and appearing in the file LICENSE.GPL included in the
00009 ** packaging of this file.
00010 **
00011 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00012 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00013 **
00014 ** See http://www.trolltech.com/gpl/ for GPL licensing information.
00015 **
00016 ** Contact info@trolltech.com if any conditions of this licensing are
00017 ** not clear to you.
00018 **
00019 **********************************************************************/
00020 
00021 #define QTOPIA_INTERNAL_LANGLIST
00022 #include <qpe/network.h>
00023 #include <qpe/networkinterface.h>
00024 #include <qpe/global.h>
00025 #include <qpe/config.h>
00026 #include <qpe/resource.h>
00027 #include <qpe/qpeapplication.h>
00028 #include <qpe/qcopenvelope_qws.h>
00029 #include <qpe/qlibrary.h>
00030 
00031 #include <qlistbox.h>
00032 #include <qdir.h>
00033 #include <qlayout.h>
00034 #include <qdict.h>
00035 #include <qtranslator.h>
00036 
00037 #include <stdlib.h>
00038 
00039 #ifndef QT_NO_COP
00040 class NetworkEmitter : public QCopChannel {
00041     Q_OBJECT
00042 public:
00043     NetworkEmitter() : QCopChannel("QPE/Network",qApp)
00044     {
00045     }
00046 
00047     void receive(const QCString &msg, const QByteArray&)
00048     {
00049         if ( msg == "choicesChanged()" )
00050             emit changed();
00051     }
00052 
00053 signals:
00054     void changed();
00055 };
00056 
00063 void Network::start(const QString& choice, const QString& password)
00064 {
00065     QCopEnvelope e("QPE/Network", "start(QString,QString)");
00066     e << choice << password;
00067 }
00068 
00075 // copy the proxy settings of the active config over to the Proxies.conf file
00079 void Network::writeProxySettings( Config &cfg )
00080 {
00081     Config proxy( Network::settingsDir() + "/Proxies.conf", Config::File );
00082     proxy.setGroup("Properties");
00083     cfg.setGroup("Proxy");
00084     proxy.writeEntry("type", cfg.readEntry("type") );
00085     proxy.writeEntry("autoconfig", cfg.readEntry("autoconfig") );
00086     proxy.writeEntry("httphost", cfg.readEntry("httphost") );
00087     proxy.writeEntry("httpport", cfg.readEntry("httpport") );
00088     proxy.writeEntry("ftphost", cfg.readEntry("ftphost") );
00089     proxy.writeEntry("ftpport", cfg.readEntry("ftpport") );
00090     proxy.writeEntry("noproxies", cfg.readEntry("noproxies") );
00091     cfg.setGroup("Properties");
00092 }
00093 
00094 
00095 
00101 void Network::stop()
00102 {
00103     QCopEnvelope e("QPE/Network", "stop()");
00104 }
00105 
00106 static NetworkEmitter *emitter = 0;
00107 
00111 void Network::connectChoiceChange(QObject* receiver, const char* slot)
00112 {
00113     if ( !emitter )
00114         emitter = new NetworkEmitter;
00115     QObject::connect(emitter,SIGNAL(changed()),receiver,slot);
00116 }
00117 
00118 #endif  // QT_NO_COP
00119 
00122 QString Network::settingsDir()
00123 {
00124     return Global::applicationFileName("Network", "modules");
00125 }
00126 
00127 #ifndef QT_NO_COP
00128 
00131 QStringList Network::choices(QListBox* lb, const QString& dir)
00132 {
00133     QStringList list;
00134 
00135     if ( lb )
00136         lb->clear();
00137 
00138     QString adir = dir.isEmpty() ? settingsDir() : dir;
00139     QDir settingsdir(adir);
00140     settingsdir.mkdir(adir);
00141 
00142     QStringList files = settingsdir.entryList("*.conf");
00143     for (QStringList::ConstIterator it=files.begin(); it!=files.end(); ++it ) {
00144         QString filename = settingsdir.filePath(*it);
00145         Config cfg(filename, Config::File);
00146         cfg.setGroup("Info");
00147         if ( lb )
00148             lb->insertItem(Resource::loadPixmap("Network/" + cfg.readEntry("Type")),
00149                 cfg.readEntry("Name"));
00150         list.append(filename);
00151     }
00152 
00153     return list;
00154 }
00155 
00156 class NetworkServer : public QCopChannel {
00157     Q_OBJECT
00158 public:
00159     NetworkServer(QObject* parent) : QCopChannel("QPE/Network",parent), wait(0)
00160     {
00161         up = FALSE;
00162         examineNetworks( TRUE );
00163         QCopChannel* card = new QCopChannel("QPE/Card",parent);
00164         connect(card,SIGNAL(received(const QCString&,const QByteArray&)),
00165             this,SLOT(cardMessage(const QCString&,const QByteArray&)));
00166     }
00167 
00168     ~NetworkServer()
00169     {
00170         stop();
00171     }
00172 
00173     bool networkOnline() const
00174     {
00175         return up;
00176     }
00177 
00178 private:
00179     void receive(const QCString &msg, const QByteArray& data)
00180     {
00181         if ( msg == "start(QString,QString)" ) {
00182             QDataStream stream(data,IO_ReadOnly);
00183             QString file,password;
00184             stream >> file >> password;
00185             if ( file.isEmpty() ) {
00186                 QStringList l = Network::choices();
00187                 for (QStringList::ConstIterator i=l.begin(); i!=l.end(); ++i) {
00188                     Config cfg(*i,Config::File);
00189                     cfg.setGroup("Info");
00190                     QString type = cfg.readEntry("Type");
00191                     NetworkInterface* plugin = Network::loadPlugin(type);
00192                     cfg.setGroup("Properties");
00193                     if ( plugin && plugin->isAvailable(cfg) ) {
00194                         file = *i;
00195                         break;
00196                     }
00197                 }
00198                 if ( file.isEmpty() ) {
00199                     QCopEnvelope("QPE/Network", "failed()");
00200                     return;
00201                 }
00202             }
00203             start(file,password);
00204         } else if ( msg == "stop()" ) {
00205             stop();
00206         } else if ( msg == "choicesChanged()" ) {
00207             examineNetworks();
00208         }
00209     }
00210 
00211 private slots:
00212     void cardMessage(const QCString &msg, const QByteArray&)
00213     {
00214         if ( msg == "stabChanged()" )
00215             examineNetworks();
00216     }
00217 
00218 private:
00219     void examineNetworks( bool firstStart = FALSE )
00220     {
00221         QStringList l = Network::choices();
00222         bool wasup = up; up=FALSE;
00223         QStringList pavailable = available;
00224         available.clear();
00225         for (QStringList::ConstIterator it=l.begin(); it!=l.end(); ++it) {
00226             Config cfg(*it,Config::File);
00227             cfg.setGroup("Info");
00228             QString type = cfg.readEntry("Type");
00229             NetworkInterface* plugin = Network::loadPlugin(type);
00230             cfg.setGroup("Properties");
00231             if ( plugin ) {
00232                 if ( plugin->isActive(cfg) ) {
00233                     up = TRUE;
00234                     if ( firstStart )
00235                         plugin->start( cfg );
00236                 }
00237                 if ( plugin->isAvailable(cfg) )
00238                     available.append(*it);
00239             }
00240         }
00241 
00242         // Try to work around unreproducible bug whereby
00243         // the netmon applet shows wrong state.
00244         bool reannounce = wait<0;
00245 
00246         if ( available != pavailable || reannounce ) {
00247             QCopEnvelope e("QPE/Network", "available(QStringList)");
00248             e << available;
00249         }
00250         if ( up != wasup || reannounce ) {
00251             QCopEnvelope("QPE/Network", up ? "up()" : "down()");
00252         }
00253     }
00254 
00255     void start( const QString& file, const QString& password )
00256     {
00257         if ( !current.isEmpty() )
00258             stop();
00259         current = QString::null;
00260         Config cfg(file, Config::File);
00261         cfg.setGroup("Info");
00262         QString type = cfg.readEntry("Type");
00263         NetworkInterface* plugin = Network::loadPlugin(type);
00264         bool started = FALSE;
00265         if ( plugin ) {
00266             cfg.setGroup("Properties");
00267             if ( plugin->start(cfg,password) ) {
00268                 Network::writeProxySettings( cfg );
00269                 current = file;
00270                 wait=0;
00271                 startTimer(400);
00272                 started = TRUE;
00273             }
00274         }
00275         if ( !started ) {
00276             QCopEnvelope("QPE/Network", "failed()");
00277         }
00278     }
00279 
00280     void stop()
00281     {
00282         bool stopped = FALSE;
00283         if ( !current.isEmpty() ) {
00284             Config cfg(current, Config::File);
00285             cfg.setGroup("Info");
00286             QString type = cfg.readEntry("Type");
00287             NetworkInterface* plugin = Network::loadPlugin(type);
00288             if ( plugin ) {
00289                 cfg.setGroup("Properties");
00290                 if ( plugin->stop(cfg) ) {
00291                     current = QString::null;
00292                     wait=0;
00293                     startTimer(400);
00294                     stopped = TRUE;
00295                 }
00296             }
00297         }
00298         if ( !stopped ) {
00299             QCopEnvelope("QPE/Network", "failed()");
00300         }
00301     }
00302 
00303     void timerEvent(QTimerEvent*)
00304     {
00305         examineNetworks();
00306         if ( wait >= 0 ) {
00307             if ( up == !current.isNull() ) {
00308                 // done
00309                 killTimers();
00310                 if ( up ) {
00311                     startTimer(3000); // monitor link
00312                     wait = -1;
00313                 }
00314             } else {
00315                 wait++;
00316                 if ( wait == 600 ) {
00317                     killTimers(); // forget about it after 240 s
00318                     QCopEnvelope("QPE/Network", "failed()");
00319                     up = !current.isNull();
00320                 }
00321             }
00322         } else if ( !up ) {
00323             killTimers();
00324         }
00325     }
00326 
00327 private:
00328     QStringList available;
00329     QString current;
00330     bool up;
00331     int wait;
00332 };
00333 
00334 static NetworkServer* ns=0;
00335 
00339 QString Network::serviceName(const QString& service)
00340 {
00341     Config cfg(service, Config::File);
00342     cfg.setGroup("Info");
00343     return cfg.readEntry("Name");
00344 }
00345 
00349 QString Network::serviceType(const QString& service)
00350 {
00351     Config cfg(service, Config::File);
00352     cfg.setGroup("Info");
00353     return cfg.readEntry("Type");
00354 }
00355 
00359 bool Network::serviceNeedsPassword(const QString& service)
00360 {
00361     Config cfg(service,Config::File);
00362     cfg.setGroup("Info");
00363     QString type = cfg.readEntry("Type");
00364     NetworkInterface* plugin = Network::loadPlugin(type);
00365     cfg.setGroup("Properties");
00366     return plugin ? plugin->needPassword(cfg) : FALSE;
00367 }
00368 
00372 bool Network::networkOnline()
00373 {
00374     return ns && ns->networkOnline();
00375 }
00376 
00380 void Network::createServer(QObject* parent)
00381 {
00382     ns = new NetworkServer(parent);
00383 }
00384 
00388 int Network::addStateWidgets(QWidget* parent)
00389 {
00390     int n=0;
00391     QStringList l = Network::choices();
00392     QVBoxLayout* vb = new QVBoxLayout(parent);
00393     for (QStringList::ConstIterator it=l.begin(); it!=l.end(); ++it) {
00394         Config cfg(*it,Config::File);
00395         cfg.setGroup("Info");
00396         QString type = cfg.readEntry("Type");
00397         NetworkInterface* plugin = Network::loadPlugin(type);
00398         cfg.setGroup("Properties");
00399         if ( plugin ) {
00400             QWidget* w;
00401             if ( (w=plugin->addStateWidget(parent,cfg)) ) {
00402                 n++;
00403                 vb->addWidget(w);
00404             }
00405         }
00406     }
00407     return n;
00408 }
00409 
00410 static QDict<NetworkInterface> *ifaces;
00411 
00415 NetworkInterface* Network::loadPlugin(const QString& type)
00416 {
00417 #ifndef QT_NO_COMPONENT
00418     if ( !ifaces ) ifaces = new QDict<NetworkInterface>;
00419     NetworkInterface *iface = ifaces->find(type);
00420     if ( !iface ) {
00421 #ifdef Q_OS_MACX
00422         QString libfile = QPEApplication::qpeDir() + "plugins/network/lib" + type + ".dylib";
00423 #else
00424         QString libfile = QPEApplication::qpeDir() + "plugins/network/lib" + type + ".so";
00425 #endif
00426         QLibrary lib(libfile);
00427         if ( !lib.queryInterface( IID_Network, (QUnknownInterface**)&iface ) == QS_OK )
00428             return 0;
00429         ifaces->insert(type,iface);
00430         QStringList langs = Global::languageList();
00431         for (QStringList::ConstIterator it = langs.begin(); it!=langs.end(); ++it) {
00432             QString lang = *it;
00433             QTranslator * trans = new QTranslator(qApp);
00434             QString tfn = QPEApplication::qpeDir()+"i18n/"+lang+"/lib"+type+".qm";
00435             if ( trans->load( tfn ))
00436                 qApp->installTranslator( trans );
00437             else
00438                 delete trans;
00439         }
00440     }
00441     return iface;
00442 #else
00443     return 0;
00444 #endif
00445 }
00446 
00447 #include "network.moc"
00448 #endif  // QT_NO_COP

Generated on Sat Nov 5 16:16:37 2005 for OPIE by  doxygen 1.4.2