00001 #include "mainwindowimp.h"
00002 #include "addconnectionimp.h"
00003 #include "interfaceinformationimp.h"
00004 #include "interfacesetupimp.h"
00005 #include "interfaces.h"
00006 #include "module.h"
00007
00008 #include <qpushbutton.h>
00009 #include <qlistbox.h>
00010 #include <qlineedit.h>
00011 #include <qlistview.h>
00012 #include <qheader.h>
00013 #include <qlabel.h>
00014 #include <qpe/qcopenvelope_qws.h>
00015 #include <qtabwidget.h>
00016 #include <qpe/qpeapplication.h>
00017
00018 #include <qmessagebox.h>
00019
00020 #ifdef QWS
00021 #include <qpe/config.h>
00022 #include <qpe/qlibrary.h>
00023 #include <qpe/resource.h>
00024 #include <qpe/qpeapplication.h>
00025 #else
00026 #include <klibloader.h>
00027 #define QLibrary KLibrary
00028 #include <kconfig.h>
00029 #define Config KConfig
00030 #include <kapplication.h>
00031 #include <kstandarddirs.h>
00032 #include <kiconloader.h>
00033 #define showMaximized show
00034 #endif
00035
00036 #if QT_VERSION < 300
00037 #include <qlist.h>
00038 #else
00039 #include <qptrlist.h>
00040 #endif
00041 #include <qdir.h>
00042 #include <qfile.h>
00043 #include <qtextstream.h>
00044 #include <qregexp.h>
00045
00046 #include <net/if.h>
00047 #include <sys/ioctl.h>
00048 #include <sys/socket.h>
00049
00050 #define DEFAULT_SCHEME "/var/lib/pcmcia/scheme"
00051 #define _PROCNETDEV "/proc/net/dev"
00052
00053 MainWindowImp::MainWindowImp(QWidget *parent, const char *name, WFlags) : MainWindow(parent, name, Qt::WStyle_ContextHelp), advancedUserMode(true), scheme(DEFAULT_SCHEME){
00054 connect(addConnectionButton, SIGNAL(clicked()), this, SLOT(addClicked()));
00055 connect(removeConnectionButton, SIGNAL(clicked()), this, SLOT(removeClicked()));
00056 connect(informationConnectionButton, SIGNAL(clicked()), this, SLOT(informationClicked()));
00057 connect(configureConnectionButton, SIGNAL(clicked()), this, SLOT(configureClicked()));
00058
00059 connect(newProfileButton, SIGNAL(clicked()), this, SLOT(addProfile()));
00060 connect(removeProfileButton, SIGNAL(clicked()), this, SLOT(removeProfile()));
00061 connect(setCurrentProfileButton, SIGNAL(clicked()), this, SLOT(changeProfile()));
00062
00063 connect(newProfile, SIGNAL(textChanged(const QString&)), this, SLOT(newProfileChanged(const QString&)));
00064
00065
00066 tabWidget->setTabEnabled( tab, false );
00067
00068
00069
00070 #ifdef QWS
00071 loadModules(QPEApplication::qpeDir() + "plugins/networksettings");
00072 #else
00073 loader = KLibLoader::self();
00074 loadModules(QString("/usr/")+KStandardDirs::kde_default("lib"));
00075 #endif
00076 getAllInterfaces();
00077
00078 Interfaces i;
00079 QStringList list = i.getInterfaceList();
00080 QMap<QString, Interface*>::Iterator it;
00081 for ( QStringList::Iterator ni = list.begin(); ni != list.end(); ++ni ) {
00082
00083
00084
00085
00086 if (m_handledIfaces.contains( *ni) ) {
00087 qDebug("Not up iface handled by module");
00088 continue;
00089 }
00090 bool found = false;
00091 for( it = interfaceNames.begin(); it != interfaceNames.end(); ++it ){
00092 if(it.key() == (*ni))
00093 found = true;
00094 }
00095 if(!found){
00096 if(!(*ni).contains("_")){
00097 Interface *i = new Interface(this, *ni, false);
00098 i->setAttached(false);
00099 i->setHardwareName(tr("Disconnected"));
00100 interfaceNames.insert(i->getInterfaceName(), i);
00101 updateInterface(i);
00102 connect(i, SIGNAL(updateInterface(Interface *)), this, SLOT(updateInterface(Interface *)));
00103 }
00104 }
00105 }
00106
00107
00108 connectionList->header()->hide();
00109
00110 Config cfg("NetworkSetup");
00111 profiles = QStringList::split(" ", cfg.readEntry("Profiles", "All"));
00112 for ( QStringList::Iterator it = profiles.begin();
00113 it != profiles.end(); ++it)
00114 profilesList->insertItem((*it));
00115 currentProfileLabel->setText(cfg.readEntry("CurrentProfile", "All"));
00116 advancedUserMode = cfg.readBoolEntry("AdvancedUserMode", false);
00117 scheme = cfg.readEntry("SchemeFile", DEFAULT_SCHEME);
00118
00119 QFile file(scheme);
00120 if ( file.open(IO_ReadOnly) ) {
00121 QTextStream stream( &file );
00122 while ( !stream.eof() ) {
00123 QString line = stream.readLine();
00124 if(line.contains("SCHEME")){
00125 line = line.mid(7, line.length());
00126 currentProfileLabel->setText(line);
00127 break;
00128 }
00129 }
00130 file.close();
00131 }
00132 makeChannel();
00133 }
00134
00138 MainWindowImp::~MainWindowImp(){
00139
00140 Config cfg("NetworkSetup");
00141 cfg.setGroup("General");
00142 cfg.writeEntry("Profiles", profiles.join(" "));
00143
00144
00145 QMap<Interface*, QListViewItem*>::Iterator iIt;
00146 for( iIt = items.begin(); iIt != items.end(); ++iIt ){
00147 if(iIt.key()->getModuleOwner() == NULL)
00148 delete iIt.key();
00149 }
00150
00151 #ifdef QWS
00152
00153 QMap<Module*, QLibrary*>::Iterator it;
00154 for( it = libraries.begin(); it != libraries.end(); ++it ){
00155 delete it.key();
00156
00157
00158
00159 }
00160 #else
00161
00162 #endif
00163 }
00164
00168 void MainWindowImp::getAllInterfaces(){
00169 int sockfd = socket(PF_INET, SOCK_DGRAM, 0);
00170 if(sockfd == -1)
00171 return;
00172
00173 struct ifreq ifr;
00174 QStringList ifaces;
00175 QFile procFile(QString(_PROCNETDEV));
00176 int result;
00177 Interface *i;
00178
00179 if (! procFile.exists()) {
00180 struct ifreq ifrs[100];
00181 struct ifconf ifc;
00182 ifc.ifc_len = sizeof(ifrs);
00183 ifc.ifc_req = ifrs;
00184 result = ioctl(sockfd, SIOCGIFCONF, &ifc);
00185
00186 for (unsigned int i = 0; i < ifc.ifc_len / sizeof(struct ifreq); i++) {
00187 struct ifreq *pifr = &ifrs[i];
00188
00189 ifaces += pifr->ifr_name;
00190 }
00191 } else {
00192 procFile.open(IO_ReadOnly);
00193 QString line;
00194 QTextStream procTs(&procFile);
00195 int loc = -1;
00196
00197 procTs.readLine();
00198 procTs.readLine();
00199 while((line = procTs.readLine().simplifyWhiteSpace()) != QString::null) {
00200 if((loc = line.find(":")) != -1) {
00201 ifaces += line.left(loc);
00202 }
00203 }
00204 }
00205
00206 for (QStringList::Iterator it = ifaces.begin(); it != ifaces.end(); ++it) {
00207 int flags = 0;
00208 if ( m_handledIfaces.contains( (*it) ) ) {
00209 qDebug(" %s is handled by a module", (*it).latin1() );
00210 continue;
00211 }
00212
00213 i = NULL;
00214
00215 strcpy(ifr.ifr_name, (*it).latin1());
00216
00217 struct ifreq ifcopy;
00218 ifcopy = ifr;
00219 result = ioctl(sockfd, SIOCGIFFLAGS, &ifcopy);
00220 flags = ifcopy.ifr_flags;
00221 i = new Interface(this, ifr.ifr_name, false);
00222 i->setAttached(true);
00223 if ((flags & IFF_UP) == IFF_UP)
00224 i->setStatus(true);
00225 else
00226 i->setStatus(false);
00227
00228 if ((flags & IFF_BROADCAST) == IFF_BROADCAST)
00229 i->setHardwareName("Ethernet");
00230 else if ((flags & IFF_POINTOPOINT) == IFF_POINTOPOINT)
00231 i->setHardwareName("Point to Point");
00232 else if ((flags & IFF_MULTICAST) == IFF_MULTICAST)
00233 i->setHardwareName("Multicast");
00234 else if ((flags & IFF_LOOPBACK) == IFF_LOOPBACK)
00235 i->setHardwareName("Loopback");
00236 else
00237 i->setHardwareName("Unknown");
00238
00239 qWarning("Adding interface %s to interfaceNames\n", ifr.ifr_name);
00240 interfaceNames.insert(i->getInterfaceName(), i);
00241 updateInterface(i);
00242 connect(i, SIGNAL(updateInterface(Interface *)),
00243 this, SLOT(updateInterface(Interface *)));
00244 }
00245
00246 QMap<Module*, QLibrary*>::Iterator it;
00247 QList<Interface> ilist;
00248 for( it = libraries.begin(); it != libraries.end(); ++it ){
00249 if(it.key()){
00250 ilist = it.key()->getInterfaces();
00251 for( i = ilist.first(); i != 0; i = ilist.next() ){
00252 qWarning("Adding interface %s to interfaceNames\n", i->getInterfaceName().latin1() );
00253 interfaceNames.insert(i->getInterfaceName(), i);
00254 updateInterface(i);
00255 connect(i, SIGNAL(updateInterface(Interface *)),
00256 this, SLOT(updateInterface(Interface *)));
00257 }
00258 }
00259 }
00260 }
00261
00267 void MainWindowImp::loadModules(const QString &path){
00268 #ifdef DEBUG
00269 qDebug("MainWindowImp::loadModules: %s", path.latin1());
00270 #endif
00271 QDir d(path);
00272 if(!d.exists())
00273 return;
00274
00275
00276 d.setFilter( QDir::Files | QDir::NoSymLinks );
00277 const QFileInfoList *list = d.entryInfoList();
00278 QFileInfoListIterator it( *list );
00279 QFileInfo *fi;
00280 while ( (fi=it.current()) ) {
00281 #ifdef QWS
00282 if(fi->fileName().contains(".so")){
00283 #else
00284 if(fi->fileName().contains(".so") && fi->fileName().contains("networksettings_")){
00285 #endif
00286 loadPlugin(path + "/" + fi->fileName());
00287 qDebug("loaded plugin: >%s< ",QString(path + "/" + fi->fileName()).latin1());
00288 }
00289 ++it;
00290 }
00291 }
00292
00299 Module* MainWindowImp::loadPlugin(const QString &pluginFileName, const QString &resolveString){
00300 #ifdef DEBUG
00301 qDebug("MainWindowImp::loadPlugin: %s: resolving %s", pluginFileName.latin1(), resolveString.latin1());
00302 #endif
00303 #ifdef QWS
00304 QLibrary *lib = new QLibrary(pluginFileName);
00305 void *functionPointer = lib->resolve(resolveString);
00306 if( !functionPointer ){
00307 #ifdef DEBUG
00308 qDebug("MainWindowImp::loadPlugin: Warning: %s is not a plugin", pluginFileName.latin1());
00309 #endif
00310 delete lib;
00311 return NULL;
00312 }
00313
00314 Module *object = ((Module* (*)()) functionPointer)();
00315 if(object == NULL){
00316 #ifdef DEBUG
00317 qDebug("MainWindowImp: Couldn't create object, but did load library!");
00318 #endif
00319 delete lib;
00320 return NULL;
00321 }
00322
00323 m_handledIfaces += object->handledInterfaceNames();
00324
00325 libraries.insert(object, lib);
00326 return object;
00327
00328 #else
00329 QLibrary *lib = loader->library(pluginFileName);
00330 if( !lib || !lib->hasSymbol(resolveString) ){
00331 qDebug(QString("MainWindowImp::loadPlugin: File: %1 is not a plugin, but though was.").arg(pluginFileName).latin1());
00332 return NULL;
00333 }
00334
00335 Module *object = ((Module* (*)()) lib->symbol(resolveString))();
00336 if(object == NULL){
00337 #ifdef DEBUG
00338 qDebug("MainWindowImp: Couldn't create object, but did load library!");
00339 #endif
00340 return NULL;
00341 }
00342 #ifdef DEBUG
00343 qDebug("MainWindowImp::loadPlugin:: Found object, storing.");
00344 #endif
00345
00346 libraries.insert(object, lib);
00347 return object;
00348 #endif
00349 }
00350
00355 void MainWindowImp::addClicked(){
00356 QMap<Module*, QLibrary*>::Iterator it;
00357 QMap<QString, QString> list;
00358 QMap<QString, Module*> newInterfaceOwners;
00359
00360 for( it = libraries.begin(); it != libraries.end(); ++it ){
00361 if(it.key()){
00362 (it.key())->possibleNewInterfaces(list);
00363 }
00364 }
00365
00366 if(list.count() == 0){
00367 QMessageBox::information(this, "Sorry", "Nothing to add.", QMessageBox::Ok);
00368 return;
00369 }
00370 AddConnectionImp addNewConnection(this, "AddConnectionImp", true);
00371 addNewConnection.addConnections(list);
00372 addNewConnection.showMaximized();
00373 if(QDialog::Accepted == addNewConnection.exec()){
00374 QListViewItem *item = addNewConnection.registeredServicesList->currentItem();
00375 if(!item)
00376 return;
00377
00378 for( it = libraries.begin(); it != libraries.end(); ++it ){
00379 if(it.key()){
00380 Interface *i = (it.key())->addNewInterface(item->text(0));
00381 if(i){
00382 qDebug("iface name %s",i->getInterfaceName().latin1());
00383 interfaceNames.insert(i->getInterfaceName(), i);
00384 updateInterface(i);
00385 }
00386 }
00387 }
00388 }
00389 }
00390
00395 void MainWindowImp::removeClicked(){
00396 QListViewItem *item = connectionList->currentItem();
00397 if(!item) {
00398 QMessageBox::information(this, "Sorry","Please select an interface First.", QMessageBox::Ok);
00399 return;
00400 }
00401
00402 Interface *i = interfaceItems[item];
00403 if(i->getModuleOwner() == NULL){
00404 QMessageBox::information(this, "Can't remove interface.", "Interface is built in.", QMessageBox::Ok);
00405 }
00406 else{
00407 if(!i->getModuleOwner()->remove(i))
00408 QMessageBox::information(this, tr("Error"), tr("Unable to remove."), QMessageBox::Ok);
00409 else{
00410 delete item;
00411
00412 }
00413 }
00414 }
00415
00421 void MainWindowImp::configureClicked(){
00422 QListViewItem *item = connectionList->currentItem();
00423 if(!item){
00424 QMessageBox::information(this, tr("Sorry"),tr("Please select an interface first."), QMessageBox::Ok);
00425 return;
00426 }
00427
00428 QString currentProfileText = currentProfileLabel->text();
00429 if(currentProfileText.upper() == "ALL");
00430 currentProfileText = "";
00431
00432 Interface *i = interfaceItems[item];
00433
00434 if(i->getModuleOwner()){
00435 QWidget *moduleConfigure = i->getModuleOwner()->configure(i);
00436 if(moduleConfigure != NULL){
00437 i->getModuleOwner()->setProfile(currentProfileText);
00438 moduleConfigure->showMaximized();
00439 return;
00440 }
00441 }
00442
00443 InterfaceSetupImpDialog *configure = new InterfaceSetupImpDialog(this, "InterfaceSetupImp", i, true, Qt::WDestructiveClose | Qt::WStyle_ContextHelp );
00444 configure->setProfile(currentProfileText);
00445 configure->showMaximized();
00446 }
00447
00453 void MainWindowImp::informationClicked(){
00454 QListViewItem *item = connectionList->currentItem();
00455 if(!item){
00456 QMessageBox::information(this, "Sorry","Please select an interface First.", QMessageBox::Ok);
00457 return;
00458 }
00459
00460 Interface *i = interfaceItems[item];
00461
00462
00463
00464
00465
00466 if(i->getModuleOwner()){
00467 QWidget *moduleInformation = i->getModuleOwner()->information(i);
00468 if(moduleInformation != NULL){
00469 moduleInformation->showMaximized();
00470 #ifdef DEBUG
00471 qDebug("MainWindowImp::informationClicked:: Module owner has created, we showed.");
00472 #endif
00473 return;
00474 }
00475 }
00476 InterfaceInformationImp *information = new InterfaceInformationImp(this, "InterfaceSetupImp", i, Qt::WType_Modal | Qt::WDestructiveClose | Qt::WStyle_Dialog | Qt::WStyle_ContextHelp);
00477 information->showMaximized();
00478 }
00479
00484 void MainWindowImp::updateInterface(Interface *i){
00485 if(!advancedUserMode){
00486 if(i->getInterfaceName() == "lo")
00487 return;
00488 }
00489
00490 QListViewItem *item = NULL;
00491
00492
00493 if(items.find(i) == items.end()){
00494 item = new QListViewItem(connectionList, "", "", "");
00495
00496 QMap<Module*, QLibrary*>::Iterator it;
00497 for( it = libraries.begin(); it != libraries.end(); ++it ){
00498 if(it.key()->isOwner(i))
00499 i->setModuleOwner(it.key());
00500 }
00501 items.insert(i, item);
00502 interfaceItems.insert(item, i);
00503 }
00504 else
00505 item = items[i];
00506
00507
00508 #ifdef QWS
00509 item->setPixmap(0, (Resource::loadPixmap(i->getStatus() ? "up": "down")));
00510 #else
00511 item->setPixmap(0, (SmallIcon(i->getStatus() ? "up": "down")));
00512 #endif
00513
00514 QString typeName = "lan";
00515 if(i->getInterfaceName() == "lo")
00516 typeName = "lo";
00517 if(i->getInterfaceName().contains("irda"))
00518 typeName = "irda";
00519 if(i->getInterfaceName().contains("wlan"))
00520 typeName = "wlan";
00521 if(i->getInterfaceName().contains("usb"))
00522 typeName = "usb";
00523
00524 if(!i->isAttached())
00525 typeName = "connect_no";
00526
00527 if(i->getModuleOwner() != NULL)
00528 typeName = i->getModuleOwner()->getPixmapName(i);
00529
00530 #ifdef QWS
00531 item->setPixmap(1, (Resource::loadPixmap(QString("networksettings/") + typeName)));
00532 #else
00533 item->setPixmap(1, (SmallIcon(typeName)));
00534 #endif
00535 item->setText(2, i->getHardwareName());
00536 item->setText(3, QString("(%1)").arg(i->getInterfaceName()));
00537 item->setText(4, (i->getStatus()) ? i->getIp() : QString(""));
00538 }
00539
00540 void MainWindowImp::newProfileChanged(const QString& newText){
00541 if(newText.length() > 0)
00542 newProfileButton->setEnabled(true);
00543 else
00544 newProfileButton->setEnabled(false);
00545 }
00546
00552 void MainWindowImp::addProfile(){
00553 QString newProfileName = newProfile->text();
00554 if(profiles.grep(newProfileName).count() > 0){
00555 QMessageBox::information(this, "Can't Add","Profile already exists.", QMessageBox::Ok);
00556 return;
00557 }
00558 profiles.append(newProfileName);
00559 profilesList->insertItem(newProfileName);
00560 }
00561
00566 void MainWindowImp::removeProfile(){
00567 if(profilesList->count() <= 1){
00568 QMessageBox::information(this, "Can't remove.","At least one profile\nis needed.", QMessageBox::Ok);
00569 return;
00570 }
00571 QString profileToRemove = profilesList->currentText();
00572 if(profileToRemove == "All"){
00573 QMessageBox::information(this, "Can't remove.","Can't remove default.", QMessageBox::Ok);
00574 return;
00575 }
00576
00577 if(profileToRemove == currentProfileLabel->text()){
00578 QMessageBox::information(this, "Can't remove.",QString("%1 is the current profile.").arg(profileToRemove), QMessageBox::Ok);
00579 return;
00580
00581 }
00582
00583 if(QMessageBox::information(this, "Question",QString("Remove profile: %1").arg(profileToRemove), QMessageBox::Ok, QMessageBox::Cancel) == QMessageBox::Ok){
00584 profiles = QStringList::split(" ", profiles.join(" ").replace(QRegExp(profileToRemove), ""));
00585 profilesList->clear();
00586 for ( QStringList::Iterator it = profiles.begin(); it != profiles.end(); ++it)
00587 profilesList->insertItem((*it));
00588
00589
00590 Interfaces interfaces;
00591
00592 QMap<Interface*, QListViewItem*>::Iterator it;
00593 for( it = items.begin(); it != items.end(); ++it ){
00594 QString interfaceName = it.key()->getInterfaceName();
00595 qDebug(interfaceName.latin1());
00596 if(interfaces.setInterface(interfaceName + "_" + profileToRemove)){
00597 interfaces.removeInterface();
00598 if(interfaces.setMapping(interfaceName)){
00599 if(profilesList->count() == 1)
00600 interfaces.removeMapping();
00601 else{
00602 interfaces.removeMap("map", interfaceName + "_" + profileToRemove);
00603 }
00604 }
00605 interfaces.write();
00606 break;
00607 }
00608 }
00609 }
00610 }
00611
00616 void MainWindowImp::changeProfile(){
00617 if(profilesList->currentItem() == -1){
00618 QMessageBox::information(this, "Can't Change.","Please select a profile.", QMessageBox::Ok);
00619 return;
00620 }
00621 QString newProfile = profilesList->text(profilesList->currentItem());
00622 if(newProfile != currentProfileLabel->text()){
00623 currentProfileLabel->setText(newProfile);
00624 QFile::remove(scheme);
00625 QFile file(scheme);
00626 if ( file.open(IO_ReadWrite) ) {
00627 QTextStream stream( &file );
00628 stream << QString("SCHEME=%1").arg(newProfile);
00629 file.close();
00630 }
00631
00632 if(QMessageBox::information(this, "Question","Restart all running interfaces?", QMessageBox::Ok, QMessageBox::No) == QMessageBox::Ok){
00633
00634 QMap<Interface*, QListViewItem*>::Iterator it;
00635 for( it = items.begin(); it != items.end(); ++it ){
00636 if(it.key()->getStatus() == true)
00637 it.key()->restart();
00638 }
00639 }
00640 }
00641
00642 }
00643
00644
00645 void MainWindowImp::makeChannel()
00646 {
00647 channel = new QCopChannel( "QPE/Application/networksettings", this );
00648 connect( channel, SIGNAL(received(const QCString&, const QByteArray&)),
00649 this, SLOT(receive(const QCString&, const QByteArray&)) );
00650 }
00651
00652 void MainWindowImp::receive(const QCString &msg, const QByteArray &arg)
00653 {
00654 bool found = false;
00655 qDebug("MainWindowImp::receive QCop msg >"+msg+"<");
00656 if (msg == "raise") {
00657 raise();
00658 return;
00659 }
00660
00661 QString dest = msg.left(msg.find("("));
00662 QCString param = msg.right(msg.length() - msg.find("(") - 1);
00663 param = param.left( param.length() - 1 );
00664 qDebug("dest >%s< param >"+param+"<",dest.latin1());
00665
00666 QMap<Module*, QLibrary*>::Iterator it;
00667 for( it = libraries.begin(); it != libraries.end(); ++it ){
00668 qDebug("plugin >%s<", it.key()->type().latin1() );
00669 if(it.key()->type() == dest){
00670 it.key()->receive( param, arg );
00671 found = true;
00672 }
00673 }
00674
00675
00676 if (found) QPEApplication::setKeepRunning();
00677 else qDebug("Huh what do ya want");
00678 }