00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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
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
00243
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
00309 killTimers();
00310 if ( up ) {
00311 startTimer(3000);
00312 wait = -1;
00313 }
00314 } else {
00315 wait++;
00316 if ( wait == 600 ) {
00317 killTimers();
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