10 files changed, 651 insertions, 479 deletions
diff --git a/noncore/settings/networksettings2/main.cpp b/noncore/settings/networksettings2/main.cpp index bcef631..1e1270e 100644 --- a/noncore/settings/networksettings2/main.cpp +++ b/noncore/settings/networksettings2/main.cpp @@ -1,96 +1,119 @@ +#include "nsdata.h" +#include "activateprofile.h" #include "networksettings.h" #include <qpe/qpeapplication.h> #include <opie/oapplicationfactory.h> #ifdef GONE OPIE_EXPORT_APP( OApplicationFactory<NetworkSettings> ) #else +// just standard GUI #define ACT_GUI 0 +// used by interfaces to request for allow of up/down #define ACT_REQUEST 1 +// regenerate config files #define ACT_REGEN 2 +// used by interfaces to request user prompt +#define ACT_PROMPT 3 int main( int argc, char * argv[] ) { int rv = 0; int Action = ACT_GUI; // could be overruled by -qws QApplication::Type GuiType = QApplication::GuiClient; #ifdef _WS_QWS_ QPEApplication * TheApp; #else QApplication * TheApp; #endif for ( int i = 1; i < argc; i ++ ) { int rmv; rmv = 0; if( strcmp( argv[i], "--regen" ) == 0 ) { Action = ACT_REGEN; GuiType = QApplication::Tty; rmv = 1; + } else if( strcmp( argv[i], "--prompt" ) == 0 ) { + Action = ACT_PROMPT; + rmv = 1; } if( rmv ) { memmove( argv+i, argv+i+rmv, sizeof( char * ) * (argc-i-rmv) ); i --; argc -= rmv; } } if( strstr( argv[0], "-request" ) ) { // called from system to request something GuiType = QApplication::Tty; Action = ACT_REQUEST; } // Start Qt #ifdef _WS_QWS_ // because QPEApplication does not handle GuiType well if( GuiType == QApplication::Tty ) { // this cast is NOT correct but we do not use // TheApp anymore ... TheApp = (QPEApplication *)new QApplication( argc, argv, GuiType ); } else { TheApp = new QPEApplication( argc, argv, GuiType ); } #else TheApp = new QApplication( argc, argv, GuiType ); #endif // init qt with app widget - if( GuiType != QApplication::Tty ) { - QWidget * W = 0; - W = new NetworkSettings(0); - TheApp->setMainWidget( W ); - W->show(); + + switch( Action ) { + case ACT_REQUEST : + { NetworkSettingsData NS; + NS.canStart( argv[1] ); + } + break; + case ACT_REGEN : + { NetworkSettingsData NS; + // regen returns 0 if OK + rv = (NS.regenerate()) ? 1 : 0; + } + break; + case ACT_PROMPT : + { ActivateProfile AP(argv[1]); + if( AP.exec() == QDialog::Accepted ) { + printf( "%s-c%d-allowed", AP.selectedProfile() ); + } else { + printf( "%s-cNN-disallowed" ); + } + } + break; + case ACT_GUI : + { QWidget * W = new NetworkSettings(0); + TheApp->setMainWidget( W ); + W->show(); #ifdef _WS_QWS_ - W->showMaximized(); + W->showMaximized(); #else - W->resize( W->sizeHint() ); + W->resize( W->sizeHint() ); #endif - rv = TheApp->exec(); - delete W; - } else { - switch( Action ) { - case ACT_REQUEST : - NetworkSettings::canStart( argv[1] ); - break; - case ACT_REGEN : - // regen returns 0 if OK - rv = (NetworkSettings::regenerate()) ? 1 : 0; - break; - } + rv = TheApp->exec(); + delete W; + } + break; } return rv; } #endif // main.cpp diff --git a/noncore/settings/networksettings2/networksettings.cpp b/noncore/settings/networksettings2/networksettings.cpp index ffe130c..f72fa8e 100644 --- a/noncore/settings/networksettings2/networksettings.cpp +++ b/noncore/settings/networksettings2/networksettings.cpp @@ -1,820 +1,414 @@ #include <stdio.h> #include <qpe/qpeapplication.h> #include <qiconset.h> #include <qgroupbox.h> #include <qtimer.h> #include <qlistbox.h> #include <qmessagebox.h> #include <qlabel.h> #include <qiconview.h> -#include <qtextstream.h> -#include <qdir.h> -#include <qfile.h> -#include <qfileinfo.h> #include <qtimer.h> #include <qpe/qpeapplication.h> #include <qtoolbutton.h> #include <asdevice.h> #include "networksettings.h" #include "netnode.h" #include "editconnection.h" -static QString CfgFile; - -NetworkSettingsData::NetworkSettingsData( void ) { - // init global resources structure - new TheNSResources(); - - CfgFile.sprintf( "%s/NETCONFIG", getenv("HOME") ); - - // load settings - Force = 0; - loadSettings(); -} - -// saving is done by caller -NetworkSettingsData::~NetworkSettingsData( void ) { - delete NSResources; -} - -void NetworkSettingsData::loadSettings( void ) { - QString S; - ANetNodeInstance* NNI; - QString Attr, Value; - long idx; - - QFile F( CfgFile ); - QTextStream TS( &F ); - - do { - - if( ! F.open(IO_ReadOnly) ) - break; - - /* load the file -> - - FORMAT : - - [NETNODETYPE] - Entries ... - <EMPTYLINE> - [connection] - Name=Name - Node=Name - <EMPTYLINE> - */ - while( ! TS.atEnd() ) { - S = TS.readLine(); - - if ( S.isEmpty() || S[0] != '[' ) - continue; - - S = S.mid( 1, S.length()-2 ); - - if( ! NSResources ) { - continue; - } - - if( S == "connection" ) { - // load connections -> collections of nodes - NodeCollection * NC = new NodeCollection( TS ); - if ( NC->count() == 0 ) { - if( QMessageBox::warning( - 0, - qApp->translate( "NetworkSettings2", "Invalid connection" ), - qApp->translate( "NetworkSettings2", - "<p>Connection %1 contains unrecognized nodes and cannot be loaded</p>" ).arg(NC->name()), - qApp->translate( "NetworkSettings2", - "Remove node"), - qApp->translate( "NetworkSettings2", - "Exit program") ) == 1 ) { - exit( 0 ); - } - delete NC; - } else - NSResources->addConnection( NC ); - } else { - // load nodes - NNI = NSResources->createNodeInstance( S ); - if( ! NNI ) { - printf( "SKIPPING %s\n", S.latin1() ); - } - - do { - S = TS.readLine(); - if( S.isEmpty() ) { - // empty line - break; - } - // node found ? - if( NNI ) { - idx = S.find( '=' ); - if( idx > 0 ) { - Attr = S.left( idx ); - Value = S.mid( idx+1, S.length() ); - } else { - Value=""; - Attr = S; - } - - Value.stripWhiteSpace(); - Attr.stripWhiteSpace(); - Attr.lower(); - // dequote Attr - Value = deQuote(Value); - - // set the attribute - NNI->setAttribute( Attr, Value ); - } - - } while( 1 ); - if( NNI ) { - // loading from file -> exists - NNI->setNew( FALSE ); - NSResources->addNodeInstance( NNI ); - } - } - } - - } while( 0 ); - -} - -QString NetworkSettingsData::saveSettings( void ) { - QString ErrS = ""; - - if( ! isModified() ) - return ErrS; - - QString S; - QFile F( CfgFile + ".bup" ); - - printf( "Saving settings to %s\n", CfgFile.latin1() ); - if( ! F.open( IO_WriteOnly | IO_Truncate ) ) { - ErrS = qApp->translate( "NetworkSettings", - "<p>Could not save setup to %1 !</p>" ). - arg(CfgFile); - // problem - return ErrS; - } - - QTextStream TS( &F ); - { Name2Connection_t & M = NSResources->connections(); - ANetNodeInstance * NNI; - - // for all connections - for( QDictIterator<NodeCollection> it(M); - it.current(); - ++it ) { - // all nodes in those connections - for( QListIterator<ANetNodeInstance> nit(*(it.current())); - nit.current(); - ++nit ) { - // header - NNI = nit.current(); - TS << '[' <<NNI->netNode()->nodeName() << ']' << endl; - NNI->saveAttributes( TS ); - TS << endl; - } - - TS << "[connection]" << endl; - it.current()->save(TS); - } - } - - QDir D("."); - D.rename( CfgFile + ".bup", CfgFile ); - - // - // proper files AND system files regenerated - // - - setModified( 0 ); - return ErrS; -} - -QString NetworkSettingsData::generateSettings( bool ForceReq ) { - bool ForceIt; - QString S = ""; - - // include own force flag - ForceIt = (Force) ? 1 : ForceReq; - - if( ! ForceIt && ! isModified() ) - return S; - - // regenerate system files - printf( "Generating settings from %s\n", CfgFile.latin1() ); - - { Name2SystemFile_t & SFM = NSResources->systemFiles(); - Name2Connection_t & M = NSResources->connections(); - NodeCollection * NC; - ANetNodeInstance * NNI; - SystemFile * SF; - bool needToRegenerate = ForceIt; - - // - // check if we need to generate at least one of the system files - // - if( ! ForceIt ) { - for( QDictIterator<SystemFile> sfit(SFM); - sfit.current(); - ++sfit ) { - SF = sfit.current(); - - // check if there are nodes that are modified and require - // data for this system file - - // for all connections - for( QDictIterator<NodeCollection> ncit(M); - ncit.current(); - ++ncit ) { - NC = ncit.current(); - - if( NC->isModified() ) { - // does this connection 'touch' this system file ? - for( QListIterator<ANetNodeInstance> cncit(*NC); - cncit.current(); - ++cncit ) { - NNI = cncit.current(); - if( NNI->netNode()->hasDataFor( SF->name() ) && - NNI->isModified() ) { - needToRegenerate = 1; - break; - } - } - } - if( needToRegenerate ) - break; - } - if( needToRegenerate ) - break; - } - } - - // we cannot renumber with a FORCE request since - // we probably are NOT going to save the config - // e.g. when using --regen option - if( ! ForceReq && needToRegenerate ) { - NSResources->renumberConnections(); - setModified(1); - } - - // - // generate files proper to each netnodeinstance - // - { Name2Instance_t & NNIs = NSResources->netNodeInstances(); - ANetNodeInstance * NNI; - - for( QDictIterator<ANetNodeInstance> NNIIt(NNIs); - NNIIt.current(); - ++NNIIt - ){ - // for all nodes find those that are modified - NNI = NNIIt.current(); - - if( ForceIt || NNI->isModified() ) { - if( ! NNI->netNode()->generateProperFilesFor( NNI ) ) { - // problem generating - S = qApp->translate( "NetworkSettings", - "<p>Cannot generate files proper to %1</p>" ). - arg(NNI->netNode()->nodeName()) ; - return S; - } - } - } - } - - // - // generate system files - // - for( QDictIterator<SystemFile> sfit(SFM); - sfit.current(); - ++sfit ) { - SF = sfit.current(); - - // - // regenerate current file - // - printf( "Generating %s\n", SF->name().latin1() ); - SF->open(); - - do { // so we can break; - - if( SF->preSection() ) { - S = qApp->translate( "NetworkSettings", - "<p>Error in preSection for file %1</p>" ). - arg( SF->name() ); - return S; - } - - for( QDictIterator<NodeCollection> ncit(M); - ncit.current(); - ++ncit ) { - NC = ncit.current(); - - // get the netnode that serves as the device for this - // connection - AsDevice * Dev = NC->device(); - - // generate 'entry' for every possible device this profile handles - - for( QListIterator<ANetNodeInstance> cncit(*NC); - cncit.current(); - ++cncit ) { - NNI = cncit.current(); - for( int i = 0; i < Dev->count(); i ++ ) { - if( NNI->netNode()->hasDataFor( SF->name() ) ) { - if( SF->preNodeSection( NNI, i ) ) { - S = qApp->translate( "NetworkSettings", - "<p>Error in preNodeSection for file %1 and node %2</p>" ). - arg( SF->name() ). - arg( NNI->netNode()->nodeName() ); - return S; - } - - if( NNI->netNode()->generateDataForCommonFile(*SF,i,NNI) ) { - S = qApp->translate( "NetworkSettings", - "<p>Error in node part for file %1 and node %2</p>" ). - arg( SF->name() ). - arg( NNI->netNode()->nodeName() ); - return S; - } - - if( SF->postNodeSection( NNI, i ) ) { - S = qApp->translate( "NetworkSettings", - "<p>Error in postNodeSection for file %1 and node %2</p>" ). - arg( SF->name() ). - arg( NNI->netNode()->nodeName() ); - return S; - } - } - } - } - *SF << endl; - } - - if( SF->postSection() ) { - S = qApp->translate( "NetworkSettings", - "<p>Error in postSection for file %1</p>" ). - arg( SF->name() ); - return S; - } - } while( 0 ); - SF->close(); - } - } - Force = 0; - return S; -} - -// -// GUI part -// - NetworkSettings::NetworkSettings( QWidget *parent, const char *name, WFlags fl ) : NetworkSettingsGUI(parent,name,fl), NSD() { UpdateTimer = new QTimer( this ); // set pixmaps Add_TB->setPixmap( NSResources->getPixmap( "add" ) ); Delete_TB->setPixmap( NSResources->getPixmap( "remove" ) ); CheckState_TB->setPixmap( NSResources->getPixmap( "check" ) ); Enable_TB->setPixmap( NSResources->getPixmap( "disabled" ) ); GenConfig_TB->setPixmap( NSResources->getPixmap( "configure" ) ); Connect_TB->setPixmap( NSResources->getPixmap( "connected" ) ); On_TB->setPixmap( NSResources->getPixmap( "off" ) ); // populate main Listbox Profiles_IV->clear(); { Name2Connection_t & M = NSResources->connections(); NodeCollection * NC; QIconViewItem * IVI; // for all connections for( QDictIterator<NodeCollection> it(M); it.current(); ++it ) { NC = it.current(); IVI = new QIconViewItem( Profiles_IV, NC->name(), NC->devicePixmap() ); } } if( Profiles_IV->count() ) { Profiles_IV->setSelected( Profiles_IV->firstItem(), TRUE ); } // if no profiles -> auto popup editing if( NSResources->connections().count() == 0 ) { QTimer::singleShot( 100, this, SLOT(SLOT_AddNode() ) ); } UpdateTimer->start( 5000 ); connect( UpdateTimer, SIGNAL( timeout() ), this, SLOT( SLOT_RefreshStates() ) ); + + /* Add QCopChannel */ + connect( qApp, SIGNAL(appMessage(const QCString&,const QByteArray&)), + this, SLOT(SLOT_QCopMessage(const QCString&,const QByteArray&)) ); } NetworkSettings::~NetworkSettings() { QString S; S = NSD.generateSettings(); if( ! S.isEmpty() ) { QMessageBox::warning( 0, tr( "Generating system configuration" ), S ); } S = NSD.saveSettings(); if( ! S.isEmpty() ) { // problem saving QMessageBox::warning( 0, tr( "Saving setup" ), S ); } } void NetworkSettings::SLOT_RefreshStates( void ) { QIconViewItem * IVI = Profiles_IV->currentItem(); // remeber if( IVI ) { NodeCollection * NC; NSResources->system().probeInterfaces(); // update current selection only NC = NSResources->findConnection( IVI->text() ); if( NC ) { State_t OldS = NC->state(); State_t NewS = NC->state(1); if( OldS != NewS ) { updateProfileState( IVI ); } } } /* -> LATER !! bool is; NodeCollection * NC; for( unsigned int i = 0; i < Profiles_LB->count() ; i ++ ) { NC = NSResources->findConnection( Profiles_LB->text(i) ); if( NC ) { State_t OldS = NC->state(); State_t NewS = NC->state(1); if( OldS != NewS ) { is = Profiles_LB->isSelected(i); Profiles_LB->changeItem( NC->statePixmap(NewS), NC->name(), i ); if( is ) { Profiles_LB->setSelected( i, TRUE ); } } } } if( ci >= 0 ) Profiles_LB->setCurrentItem( ci ); */ } void NetworkSettings::SLOT_AddNode( void ) { SLOT_EditNode( 0 ); } void NetworkSettings::SLOT_DeleteNode( void ) { QIconViewItem * IVI = Profiles_IV->currentItem(); if ( ! IVI ) return; if( QMessageBox::warning( 0, tr( "Removing profile" ), tr( "Remove selected profile ?" ), 1, 0 ) == 1 ) { NSResources->removeConnection( IVI->text() ); delete IVI; setModified( 1 ); NSD.forceGeneration(1); } } void NetworkSettings::SLOT_EditNode( QIconViewItem * IVI ) { QString OldName = ""; EditConnection EC( this ); if( IVI ) { NodeCollection * NC = NSResources->findConnection( IVI->text() ); if( ! NC ) { return; } OldName = NC->name(); EC.setConnection( NC ); } EC.showMaximized(); // disable refresh timer UpdateTimer->stop(); if( EC.exec() == QDialog::Accepted ) { // toplevel item -> store NodeCollection * NC = EC.connection(); if( NC->isModified() ) { setModified( 1 ); if( IVI ) { // new name -> remove item NSResources->removeConnection( OldName ); // must add it here since change will trigger event NSResources->addConnection( NC ); IVI->setText( NC->name() ); IVI->setPixmap( NC->devicePixmap() ); } else { // new item NSResources->addConnection( NC ); NC->setNumber( NC->maxConnectionNumber()+1 ); IVI = new QIconViewItem( Profiles_IV, NC->name(), NC->devicePixmap() ); Profiles_IV->setSelected( IVI, TRUE ); } updateProfileState( IVI ); } } else { // cancelled : reset connection if( IVI ) { NodeCollection * NC = NSResources->findConnection( IVI->text() ); NC->reassign(); } } // reenable UpdateTimer->start( 5000 ); } void NetworkSettings::SLOT_ShowNode( QIconViewItem * IVI ) { if( IVI == 0 ) return; NodeCollection * NC = NSResources->findConnection( IVI->text() ); // is button possible bool EnabledPossible, OnPossible, ConnectPossible; // is button On or Off bool DisabledOn, OnOn, ConnectOn; EnabledPossible = OnPossible = ConnectPossible = 1; DisabledOn = 1; OnOn = ConnectOn = 0; switch( NC->state() ) { case Unknown : // cannot occur here break; case Unchecked : case Unavailable : // cannot do anything but recheck EnabledPossible = OnPossible = ConnectPossible = 0; break; case Disabled : OnPossible = ConnectPossible = 0; break; case Off : DisabledOn = 0; break; case Available : OnOn = 1; DisabledOn = 0; break; case IsUp : OnOn = ConnectOn = 1; DisabledOn = 0; break; } // set button state Enable_TB->setEnabled( EnabledPossible ); On_TB->setEnabled( OnPossible ); Connect_TB->setEnabled( ConnectPossible ); Enable_TB->setOn( DisabledOn ); On_TB->setOn( OnOn ); Connect_TB->setOn( ConnectOn ); if( NC->description().isEmpty() ) { Description_LBL->setText( tr( "No description" ) ); } else { Description_LBL->setText( NC->description() ); } CurProfile_GB->setTitle( IVI->text() ); State_LBL->setText( NC->stateName() ); } void NetworkSettings::SLOT_CheckState( void ) { QIconViewItem * IVI = Profiles_IV->currentItem(); if ( ! IVI ) return; updateProfileState( IVI ); } void NetworkSettings::updateProfileState( QIconViewItem * IVI ) { if( IVI == Profiles_IV->currentItem() ) { SLOT_ShowNode( IVI ); } } void NetworkSettings::SLOT_GenerateConfig( void ) { QString S = NSD.generateSettings( TRUE ); if( ! S.isEmpty() ) { QMessageBox::warning( 0, tr( "Generating system configuration" ), S ); } } void NetworkSettings::SLOT_Enable( void ) { QIconViewItem * IVI = Profiles_IV->currentItem(); QString Msg; if ( ! IVI ) return; NodeCollection * NC = NSResources->findConnection( IVI->text() ); bool rv; switch( NC->state() ) { case Disabled : Msg = tr( "Cannot enable profile" ); rv = NC->setState( Enable ); break; default : Msg = tr( "Cannot disable profile" ); rv = NC->setState( Disable ); break; } if( ! rv ) { QMessageBox::warning( 0, tr( "Activating profile" ), Msg ); return; } updateProfileState( IVI ); } void NetworkSettings::SLOT_On( void ) { QIconViewItem * IVI = Profiles_IV->currentItem(); if ( ! IVI ) return; NodeCollection * NC = NSResources->findConnection( IVI->text() ); bool rv; switch( NC->state() ) { case Off : // activate interface rv = NC->setState( Activate ); break; case Available : // deactivate rv = NC->setState( Deactivate ); break; case IsUp : // bring down and deactivate rv = ( NC->setState( Down ) && NC->setState( Deactivate ) ); break; default : // others no change return; } if( ! rv ) { QMessageBox::warning( 0, tr( "Activating profile" ), tr( "Cannot enable profile" ) ); return; } updateProfileState( IVI ); } void NetworkSettings::SLOT_Connect( void ) { QIconViewItem * IVI = Profiles_IV->currentItem(); if ( ! IVI ) return; NodeCollection * NC = NSResources->findConnection( IVI->text() ); bool rv; switch( NC->state() ) { case IsUp : // down interface rv = NC->setState( Down ); break; case Available : // up interface rv = NC->setState( Up ); break; case Off : // activate and bring up rv = ( NC->setState( Activate ) && NC->setState( Up ) ); break; default : // others no change return; } if( ! rv ) { QMessageBox::warning( 0, tr( "Activating profile" ), tr( "Cannot enable profile" ) ); return; } // we do not update the GUI but wait for the REAL upping of the device } -/* - Called by the system to see if interface can be brought UP - - if allowed, echo Interface-allowed else Interface-disallowed -*/ - -void NetworkSettings::canStart( const char * Interface ) { - // load situation - NetworkSettingsData NSD; - - { Name2Connection_t & M = NSResources->connections(); - NodeCollection * NC; - - // for all connections - for( QDictIterator<NodeCollection> it(M); - it.current(); - ++it ) { - NC = it.current(); - // check if this profile handles the requested interface - if( NC->handlesInterface( Interface ) ) { - switch( NC->state() ) { - case Unchecked : - case Unknown : - case Unavailable : - case Disabled : - // this profile does not allow interface to be UP - // -> try others - break; - case Off : - // try to UP the device - if( ! NC->setState( Activate ) ) { - // cannot bring device Online -> try other alters - break; - } - // FT - case Available : - case IsUp : // also called for 'down' - // device is ready -> done - printf( "%s-c%d-allowed\n", - Interface, NC->number() ); - return; - } - } - } - } - // if we come here no alternatives are possible - printf( "%s-cnn-disallowed\n", Interface ); -} - -/* - Called by the system to regenerate config files -*/ - -bool NetworkSettings::regenerate( void ) { - QString S; - // load situation - NetworkSettingsData NSD; +void NetworkSettings::SLOT_QCopMessage(const QCString &msg, const QByteArray &data) { + QDataStream stream( data, IO_ReadOnly ); - S = NSD.generateSettings( TRUE ); - if( ! S.isEmpty() ) { - fprintf( stdout, "%s\n", S.latin1() ); - return 1; - } - return 0; + if( msg == "raise" ) { + raise(); + return; + } /* if ( msg == "someMessage(int,int,int)" ) { + int a,b,c; + stream >> a >> b >> c; + ... + } */ } diff --git a/noncore/settings/networksettings2/networksettings.h b/noncore/settings/networksettings2/networksettings.h index eb475a3..fadf81b 100644 --- a/noncore/settings/networksettings2/networksettings.h +++ b/noncore/settings/networksettings2/networksettings.h @@ -1,77 +1,49 @@ +#include "nsdata.h" #include "networksettingsGUI.h" #include "resources.h" class ANetNode; class ANetNodeInstance; class QTimer; class QIconViewItem; -class NetworkSettingsData { - -public : - - NetworkSettingsData( void ); - ~NetworkSettingsData( void ); - - void loadSettings( void ); - QString saveSettings( void ); - - QString generateSettings( bool Force = FALSE ); - - bool isModified( void ) - { return IsModified; } - void setModified( bool m ) - { IsModified = m; } - - void forceGeneration( bool m ) - { Force = m; } - -private : - - bool IsModified; - bool Force; - -}; - class NetworkSettings : public NetworkSettingsGUI { Q_OBJECT public : NetworkSettings( QWidget *parent=0, const char *name=0, WFlags fl = 0 ); ~NetworkSettings( void ); static QString appName( void ) { return QString::fromLatin1("networksettings"); } - static void canStart( const char * Interface ); - static bool regenerate( void ); - bool isModified( void ) { return NSD.isModified(); } void setModified( bool m ) { NSD.setModified( m ); } public slots : void SLOT_AddNode( void ); void SLOT_DeleteNode( void ); void SLOT_ShowNode( QIconViewItem * ); void SLOT_EditNode( QIconViewItem * ); void SLOT_CheckState( void ); void SLOT_Enable( void ); void SLOT_On( void ); void SLOT_Connect( void ); void SLOT_GenerateConfig( void ); void SLOT_RefreshStates( void ); + void SLOT_QCopMessage( const QCString&,const QByteArray& ); private : void updateProfileState( QIconViewItem * it ); QTimer * UpdateTimer; NetworkSettingsData NSD; }; diff --git a/noncore/settings/networksettings2/networksettings.pro b/noncore/settings/networksettings2/networksettings.pro index fb1f2cf..fe47971 100644 --- a/noncore/settings/networksettings2/networksettings.pro +++ b/noncore/settings/networksettings2/networksettings.pro @@ -1,16 +1,21 @@ # CONFIG = qt warn_on debug quick-app #CONFIG = qt warn_on release HEADERS = networksettings.h \ + activateprofile.h \ editconnection.h SOURCES = main.cpp \ networksettings.cpp \ + nsdata.cpp \ + activateprofile.cpp \ editconnection.cpp INCLUDEPATH += $(OPIEDIR)/include networksettings2/ DEPENDPATH += $(OPIEDIR)/include networksettings2/ LIBS += -lqpe -L$(OPIEDIR)/plugins/networksettings2 -lnetworksettings2 -lopie -INTERFACES = networksettingsGUI.ui editconnectionGUI.ui +INTERFACES = networksettingsGUI.ui \ + editconnectionGUI.ui \ + activateprofileGUI.ui TARGET = networksettings2 include ( $(OPIEDIR)/include.pro ) diff --git a/noncore/settings/networksettings2/networksettings2/netnode.cpp b/noncore/settings/networksettings2/networksettings2/netnode.cpp index a5b572b..d36a1e5 100644 --- a/noncore/settings/networksettings2/networksettings2/netnode.cpp +++ b/noncore/settings/networksettings2/networksettings2/netnode.cpp @@ -1,278 +1,302 @@ #include <qpe/qpeapplication.h> #include <time.h> #include <qtextstream.h> #include <qpixmap.h> #include "resources.h" #include "netnode.h" #include "asdevice.h" #include "asline.h" #include "asconnection.h" #include "asfullsetup.h" QString & deQuote( QString & X ) { if( X[0] == '"' ) { // remove end and trailing "" and \x -> x QChar R; long idx; idx = X.length()-1; X = X.mid( 1, idx ); idx = 0; while( ( idx = X.find( '\\', idx ) ) >= 0 ) { R = X[idx+1]; X.replace( idx, 2, &R, 1 ); } X = X.left( X.length()-1 ); } return X; } QString quote( QString X ) { if( X.find( QRegExp( "[ \n\"\\\t]" ) ) >= 0 ) { // need to quote this QString OutString = "\""; X.replace( QRegExp("\""), "\\\"" ); X.replace( QRegExp("\\"), "\\\\" ); X.replace( QRegExp(" "), "\\ " ); OutString += X; OutString += "\""; X = OutString; } return X; } // // // // // long ANetNodeInstance::InstanceCounter = -1; void ANetNodeInstance::initialize( void ) { if( InstanceCounter == -1 ) InstanceCounter = time(0); // set name QString N; N.sprintf( "-%ld", InstanceCounter++ ); N.prepend( NodeType->nodeName() ); setNodeName( N ); } void ANetNodeInstance::setAttribute( QString & Attr, QString & Value ){ if( Attr == "name" ) { NodeName = Value; } else { setSpecificAttribute( Attr, Value ); } } void ANetNodeInstance::saveAttributes( QTextStream & TS ) { TS << "name=" << quote( NodeName ) << endl; saveSpecificAttribute( TS ); } ANetNodeInstance * ANetNodeInstance::nextNode( void ) { return connection()->findNext( this ); } // // // // // long NodeCollection::MaxNr = -1; NodeCollection::NodeCollection( void ) : QList<ANetNodeInstance>() { IsModified = 0; Index = -1; Name=""; IsNew = 1; CurrentState = Unchecked; } NodeCollection::NodeCollection( QTextStream & TS ) : QList<ANetNodeInstance>() { long idx; bool InError = 0; QString S, A, N; IsModified = 0; Index = -1; Name=""; IsNew = 0; CurrentState = Unchecked; do { S = TS.readLine(); if( S.isEmpty() ) { if( InError ) { // remove all nodes clear(); } // empty line break; } idx = S.find('='); S.stripWhiteSpace(); A = S.left( idx ); A.lower(); N = S.mid( idx+1, S.length() ); N.stripWhiteSpace(); N = deQuote( N ); if( A == "name" ) { Name = N; } else if( A == "number" ) { setNumber( N.toLong() ); } else if( A == "node" ) { ANetNodeInstance * NNI = NSResources->findNodeInstance( N ); if( NNI && ! InError ) { append( NSResources->findNodeInstance( N ) ); } else { // could not find a node type -> collection invalid InError = 1; } } } while( 1 ); } NodeCollection::~NodeCollection( void ) { } const QString & NodeCollection::description( void ) { ANetNodeInstance * NNI = getToplevel(); return (NNI) ? NNI->runtime()->asFullSetup()->description() : Name; } void NodeCollection::append( ANetNodeInstance * NNI ) { NNI->setConnection( this ); QList<ANetNodeInstance>::append( NNI ); } void NodeCollection::save( QTextStream & TS ) { TS << "name=" << quote( Name ) << endl; TS << "number=" << number() << endl; ANetNodeInstance * NNI; for( QListIterator<ANetNodeInstance> it(*this); it.current(); ++it ) { NNI = it.current(); TS << "node=" << quote( NNI->nodeName() ) << endl; } TS << endl; IsNew = 0; } ANetNodeInstance * NodeCollection::getToplevel( void ) { ANetNodeInstance * NNI = 0; for( QListIterator<ANetNodeInstance> it(*this); it.current(); ++it ) { NNI = it.current(); if( NNI->netNode()->isToplevel() ) break; } return NNI; } ANetNodeInstance * NodeCollection::findByName( const QString & S ) { ANetNodeInstance * NNI = 0; for( QListIterator<ANetNodeInstance> it(*this); it.current(); ++it ) { NNI = it.current(); if( NNI->name() == S ) break; } return NNI; } ANetNodeInstance * NodeCollection::findNext( ANetNodeInstance * NNI ) { ANetNodeInstance * NNNI; if( ! NNI ) getToplevel(); for( QListIterator<ANetNodeInstance> it(*this); it.current(); ++it ) { NNNI = it.current(); if( NNNI == NNI ) { ++it; return it.current(); } } return 0; // no more next } int NodeCollection::compareItems( QCollection::Item I1, QCollection::Item I2 ) { ANetNodeInstance * NNI1, * NNI2; NNI1 = (ANetNodeInstance *)I1; NNI2 = (ANetNodeInstance *)I2; return NNI1->nodeName().compare( NNI2->nodeName() ); } static char * State2PixmapTbl[] = { "NULL", // Unchecked : no pixmap "check", // Unknown "delete", // unavailable "disabled", // disabled "off", // off "disconnected", // available "connected" // up }; QPixmap NodeCollection::devicePixmap( void ) { return NSResources->getPixmap( device()->netNode()->pixmapName()+"-large" ); } QPixmap NodeCollection::statePixmap( State_t S) { return NSResources->getPixmap( State2PixmapTbl[S] ); } QString NodeCollection::stateName( State_t S) { switch( S ) { case Unknown : return qApp->translate( "networksettings2", "Unknown"); case Unavailable : return qApp->translate( "networksettings2", "Unavailable"); case Disabled : return qApp->translate( "networksettings2", "Disabled"); case Off : return qApp->translate( "networksettings2", "Off"); case Available : return qApp->translate( "networksettings2", "Available"); case IsUp : return qApp->translate( "networksettings2", "IsUp"); case Unchecked : /* FT */ default : break; } return QString(""); } void NodeCollection::reassign( void ) { for( QListIterator<ANetNodeInstance> it(*this); it.current(); ++it ) { it.current()->setConnection( this ); } } InterfaceInfo * RuntimeInfo::assignedInterface( void ) { return netNode()->nextNode()->runtime()->assignedInterface(); } AsDevice * RuntimeInfo::device( void ) { return netNode()->nextNode()->runtime()->device(); } + +ANetNodeInstance * FakeNetNode::createInstance( void ) { + return new FakeNetNodeInstance( this ); +} + +void FakeNetNodeInstance::setSpecificAttribute( + QString & A, QString & V ) { + ValAttrPairs.insert( A, new QString(V) ); +} + +void FakeNetNodeInstance::saveSpecificAttribute( QTextStream &TS ) { + for( QDictIterator<QString> it( ValAttrPairs ); + it.current(); + ++ it ) { + TS << it.currentKey().latin1() + << "=" + << quote( *(it.current())) + << endl ; + ++it; + } +} + +// collects all info that no plugin acceps +FakeNetNode * FakeNode = 0; diff --git a/noncore/settings/networksettings2/networksettings2/netnode.h b/noncore/settings/networksettings2/networksettings2/netnode.h index 0ecd64e..56333c5 100644 --- a/noncore/settings/networksettings2/networksettings2/netnode.h +++ b/noncore/settings/networksettings2/networksettings2/netnode.h @@ -1,361 +1,440 @@ #ifndef NETNODE_H #define NETNODE_H #include <qtextstream.h> #include <qlist.h> +#include <qdict.h> #include <qpixmap.h> #include <qobject.h> #include <time.h> // difference feature interfaces class AsDevice; class AsLine; class AsConnection; class AsFullSetup; // needed for plugin creation function #include <qlist.h> class ANetNode; class ANetNodeInstance; class NodeCollection; class QTextStream; class RuntimeInfo; class InterfaceInfo; extern QString & deQuote( QString & X ); extern QString quote( QString X ); #include "systemfile.h" typedef enum State { // if we have not yet detected the state of the device Unchecked = 0, // if we cannot determine the state Unknown = 1, // if connection cannot be established e.g. because // the hardware is not available Unavailable = 2, // if the connection cannot be establishec but NOT // because it is physically impossible but because // it has been disabled for FUNCTIONAL reasons Disabled = 3, // if connection is available to is currently down // i.e. the corresponding hardware is not activated Off = 4, // if connection is available to be used (i.e. the // devices if fully ready to be used Available = 5, // if connection is being used IsUp = 6 } State_t; typedef enum Action { // to make the device unavailable functionally Disable = 0, // to make the device available functionally Enable = 1, // bring the hardware up Activate = 2, // bring the hardware down Deactivate = 3, // bring the connection up Up = 4, // bring the connection down Down = 5 } Action_t; class ANetNode : public QObject{ public: typedef QArray<ANetNode *> NetNodeList; ANetNode(){}; virtual ~ANetNode(){}; // pixmap needed for this NetNode virtual const QString pixmapName() = 0; // name of this NetNode virtual const QString nodeName() = 0; // description for this NetNode virtual const QString nodeDescription() = 0; // create a blank instance of a net node virtual ANetNodeInstance * createInstance( void ) = 0; // return feature this NetNode provides virtual const char * provides( void ) = 0; virtual const char ** needs( void ) = 0; // generate files specific for this node (if any) virtual bool generateProperFilesFor( ANetNodeInstance * NNI ) = 0; // return TRUE if this node has data to be inserted in systemfile // with name S virtual bool hasDataFor( const QString & S ) = 0; // generate data specific for the system file S // called only IF data was needed virtual bool generateDataForCommonFile( SystemFile & SF, long DevNr, ANetNodeInstance * NNI ) = 0; // does this Node provide a Connection bool isToplevel( void ) { return strcmp( provides(), "fullsetup") == 0 ; } // compiled references to 'needed' NetNodes -> needs list void setAlternatives( NetNodeList * Alt ) { Alternatives = Alt; } NetNodeList & alternatives( void ) { return *Alternatives; } protected : NetNodeList * Alternatives; private : }; class ANetNodeInstance : public QObject { public: ANetNodeInstance( ANetNode * NN ) : QObject() { IsModified=0; NodeType = NN; IsNew = TRUE; } virtual ~ANetNodeInstance( void ) { } virtual RuntimeInfo * runtime( void ) = 0; void setConnection( NodeCollection * NC ) { Connection = NC; } NodeCollection * connection( void ) { return Connection; } // create edit widget under parent virtual QWidget * edit( QWidget * parent ) = 0; // is given data acceptable virtual QString acceptable( void ) = 0; // return data was modified void setModified( bool M ) { IsModified = M; } bool isModified( void ) { return IsModified; } // get data from GUI and store in node virtual void commit( void ) = 0; // get next node ANetNodeInstance * nextNode(); // return NetNode this is an instance of ANetNode * netNode( void ) { return NodeType; } // intialize am instance of a net node void initialize( void ); // set the value of an attribute void setAttribute( QString & Attr, QString & Value ) ; void saveAttributes( QTextStream & TS ) ; // return true if node isntance is NEW and not loaded void setNew( bool IsN ) { IsNew = IsN; } bool isNew( void ) { return IsNew; } // return logical name of this instance QString & nodeName( void ) { return NodeName; } void setNodeName( const QString & S ) { NodeName = S; } // return description for this instance QString & description( void ) { return Description; } void setDescription( const QString & S ) { Description = S; } // pixmap for this instance -> from NetNode const QString pixmapName( void ) { return NodeType->pixmapName(); } const char * provides( void ) { return NodeType->provides(); } const char ** needs( void ) { return NodeType->needs(); } // returns node specific data -> only useful for 'buddy' virtual void * data( void ) = 0; protected : virtual void setSpecificAttribute( QString & , QString & ) = 0; virtual void saveSpecificAttribute( QTextStream & ) = 0; ANetNode * NodeType; // connection to which this node belongs to NodeCollection * Connection; QString NodeName; QString Description; bool IsModified; bool IsNew; static long InstanceCounter; }; class RuntimeInfo : public QObject { Q_OBJECT public : RuntimeInfo( ANetNodeInstance * TheNNI ) { NNI = TheNNI; } // downcast AsDevice * asDevice( void ) { return (AsDevice *)this; } AsConnection * asConnection( void ) { return (AsConnection *)this; } AsLine * asLine( void ) { return (AsLine *)this; } AsFullSetup * asFullSetup( void ) { return (AsFullSetup *)this; } // does this node handles this interface e.g.eth0 // recurse deeper if this node cannot answer that question virtual bool handlesInterface( const QString & ) { return 0; } virtual InterfaceInfo * assignedInterface( void ); virtual AsDevice * device( void ); ANetNodeInstance * netNode() { return NNI; } NodeCollection * connection() { return NNI->connection(); } virtual void detectState( NodeCollection * NC ) = 0; virtual bool setState( NodeCollection * NC, Action_t A ) = 0; virtual bool canSetState( State_t Curr, Action_t A ) = 0; signals : // sent by device if state changes void stateChanged( State_t S, ANetNodeInstance * NNI ); protected : // connection this runtime info belongs to ANetNodeInstance * NNI; }; class NodeCollection : public QList<ANetNodeInstance> { public : NodeCollection( void ); NodeCollection( QTextStream & TS ); ~NodeCollection( void ); int number( void ) { return Number; } void setNumber( int i ) { Number = i; if( MaxNr < i ) MaxNr = i; } bool isNew( void ) { return IsNew; } void setNew( bool N ) { IsNew = N ; } bool isModified( void ) { return IsModified; } void setModified( bool N ) { IsModified = N ; } bool handlesInterface( const QString & S ) { return getToplevel()->runtime()->handlesInterface( S ); } InterfaceInfo * assignedInterface( void ) { return getToplevel()->runtime()->assignedInterface(); } AsDevice * device() { return getToplevel()->runtime()->device(); } State_t state( bool Update = 0 ) { if( CurrentState == Unchecked || Update ) { // need to get current state getToplevel()->runtime()->detectState( this ); } return CurrentState; } // get the ixmap for this device QPixmap devicePixmap( void ); QPixmap statePixmap( State_t S ); QPixmap statePixmap( bool Update = 0 ) { return statePixmap( state(Update) ); } QString stateName( State_t ); QString stateName( bool Update = 0 ) { return stateName( state(Update) ); } bool setState( Action_t A ) { return getToplevel()->runtime()->setState( this, A ); } bool canSetState( Action_t A ) { return getToplevel()->runtime()->canSetState( CurrentState, A ); } void save( QTextStream & TS ); void append( ANetNodeInstance * NNI ); // makes sure that all items in the connection point to // that connectoin void reassign( void ); ANetNodeInstance * getToplevel( void ); ANetNodeInstance * findNext( ANetNodeInstance * NNI ); ANetNodeInstance * findByName( const QString & S ); const QString & name() { return Name; } const QString & description( void ); void setName( const QString & N) { Name = N; } State_t currentState( void ) { return CurrentState; } void setCurrentState( State_t S ) { CurrentState = S; } long maxConnectionNumber( void ) { return MaxNr; } static void resetMaxNr( void ) { MaxNr = -1; } private : int compareItems ( QCollection::Item item1, QCollection::Item item2 ); static long MaxNr; long Number; // state of this connection State_t CurrentState; QString Name; // true if this collection was just created (and not // loaded from file bool IsNew; // index in listbox int Index; bool IsModified; }; +// +// special node that is used to remember entries for plugins +// that seem missing. This way we never loose data +// + +class FakeNetNode : public ANetNode { + +public: + + FakeNetNode( ) { }; + virtual ~FakeNetNode(){}; + + const QString pixmapName() + { return QString(""); } + const QString nodeName() + { return QString("Fake node" ); } + const QString nodeDescription() + { return QString("Fake node" ); } + ANetNodeInstance * createInstance( void ); + const char * provides( void ) + { return ""; } + virtual const char ** needs( void ) + { return 0; } + virtual bool generateProperFilesFor( ANetNodeInstance * ) + { return 0; } + virtual bool hasDataFor( const QString & ) + { return 0; } + virtual bool generateDataForCommonFile( + SystemFile & , long , ANetNodeInstance * ) + {return 1; } + +private : + +}; + +class FakeNetNodeInstance : public ANetNodeInstance { + +public: + + FakeNetNodeInstance( ANetNode * NN ) : + ANetNodeInstance( NN ), ValAttrPairs() { } + virtual ~FakeNetNodeInstance( void ) { } + + virtual RuntimeInfo * runtime( void ) + { return 0; } + + // create edit widget under parent + virtual QWidget * edit( QWidget * ) + { return 0; } + // is given data acceptable + virtual QString acceptable( void ) + { return QString(""); } + + // get data from GUI and store in node + virtual void commit( void ) {} + + // get next node + ANetNodeInstance * nextNode() + { return 0; } + // return NetNode this is an instance of + + // intialize am instance of a net node + void initialize( void ){} + + // returns node specific data -> only useful for 'buddy' + virtual void * data( void ) + { return 0; } + +protected : + + virtual void setSpecificAttribute( QString & , QString & ); + virtual void saveSpecificAttribute( QTextStream & ); + + QDict<QString> ValAttrPairs; +}; + +extern FakeNetNode * FakeNode; + #endif diff --git a/noncore/settings/networksettings2/networksettings2/resources.cpp b/noncore/settings/networksettings2/networksettings2/resources.cpp index ff6e457..15e1b64 100644 --- a/noncore/settings/networksettings2/networksettings2/resources.cpp +++ b/noncore/settings/networksettings2/networksettings2/resources.cpp @@ -1,236 +1,231 @@ #include <qpixmap.h> #include <qpe/qlibrary.h> #include <qpe/qpeapplication.h> #include <qdir.h> +#include <opie2/odebug.h> #include <qtopia/resource.h> #include "netnode.h" #include "resources.h" #define PLUGINDIR "plugins/networksettings2" #define ICONDIR "/pics/networksettings2/" // single resources instance TheNSResources * _NSResources = 0; TheNSResources::TheNSResources( void ) : NodeTypeNameMap(), ConnectionsMap() { _NSResources = this; // load available netnodes findAvailableNetNodes(QPEApplication::qpeDir() + PLUGINDIR ); // compile provides and needs lists { const char ** NeedsRun; QDictIterator<NetNode_t> OuterIt( AllNodeTypes ); bool Done; for ( ; OuterIt.current(); ++OuterIt ) { // find needs list ANetNode::NetNodeList * NNLP = new ANetNode::NetNodeList; ANetNode::NetNodeList & NNL = *(NNLP); // must iterate this way to avoid duplication pointers for ( QDictIterator<NetNode_t> InnerIt( AllNodeTypes ); InnerIt.current(); ++InnerIt ) { if( InnerIt.current() == OuterIt.current() ) // avoid recursive continue; const char * Provides = InnerIt.current()->NetNode->provides(); NeedsRun = OuterIt.current()->NetNode->needs(); for( ; *NeedsRun; NeedsRun ++ ) { if( strcmp( Provides, *NeedsRun ) == 0 ) { // inner provides what outer needs NNL.resize( NNL.size() + 1 ); NNL[NNL.size()-1] = InnerIt.current()->NetNode; Done = 1; // break from 2 loops break; } } } OuterIt.current()->NetNode->setAlternatives( NNLP ); } } // define Node types to Description map NodeTypeNameMap.insert( "device", tr( "Network Device" ) ); NodeTypeNameMap.insert( "line", tr( "Character device" ) ); NodeTypeNameMap.insert( "connection", tr( "IP Connection" ) ); NodeTypeNameMap.insert( "fullsetup", tr( "Connection Profile" ) ); NodeTypeDescriptionMap.insert( "device", tr( "<p>Devices that can handle IP packets</p>" ) ); NodeTypeDescriptionMap.insert( "line", tr( "<p>Devices that can handle single bytes</p>" ) ); NodeTypeDescriptionMap.insert( "connection", tr( "<p>Nodes that provide working IP connections</p>" ) ); NodeTypeDescriptionMap.insert( "fullsetup", tr( "<p>Fully configured connection profile</p>" ) ); // define system files addSystemFile( new SystemFile( "interfaces", "./interfaces" ) ); // get access to the system TheSystem = new System(); } TheNSResources::~TheNSResources( void ) { delete TheSystem; } /** * Load all modules that are found in the path * @param path a directory that is scaned for any plugins that can be loaded * and attempts to load them */ void TheNSResources::findAvailableNetNodes(const QString &path){ QDir d(path); if(!d.exists()) return; QString lang = ::getenv("LANG"); // Don't want sym links d.setFilter( QDir::Files | QDir::NoSymLinks ); const QFileInfoList *list = d.entryInfoList(); QFileInfoListIterator it( *list ); QFileInfo *fi; while ( (fi=it.current()) ) { if( fi->fileName().contains(".so")){ /* if loaded install translation */ if( loadNetNode(path + "/" + fi->fileName()) ) { QTranslator *trans = new QTranslator(qApp); QString fn = QPEApplication::qpeDir()+ "/i18n/"+lang+"/"+ fi->fileName().left( fi->fileName().find(".") )+ ".qm"; if( trans->load( fn ) ) qApp->installTranslator( trans ); else delete trans; } } ++it; } } /** * Attempt to load a function and resolve a function. * @param pluginFileName - the name of the file in which to attempt to load * @param resolveString - function pointer to resolve * @return true of loading is successful */ bool TheNSResources::loadNetNode( const QString &pluginFileName, const QString &resolveString){ QLibrary *lib = new QLibrary(pluginFileName); void * res = lib->resolve(resolveString); if( ! res ){ -#ifdef DEBUG - qDebug("loadNetNode: Warning: %s is not a plugin", pluginFileName.latin1()); -#endif delete lib; return 0; } GetNetNodeListFt_t getNetNodeList = (GetNetNodeListFt_t)res; // Try to get an object. QList<ANetNode> PNN; getNetNodeList( PNN ); if( PNN.isEmpty() ) { -#ifdef DEBUG - qDebug("loadNetNode: Couldn't get node list, but did load library!"); -#endif delete lib; return 0; } ANetNode * NNP; for( QListIterator<ANetNode> it(PNN); it.current(); ++it ) { NetNode_t * NN; NNP = it.current(); NN = new NetNode_t; NN->NetNode = NNP; NN->TheLibrary = lib; NN->NodeCountInLib = PNN.count(); // store mapping AllNodeTypes.insert( NN->NetNode->nodeName(), NN ); } return 1; } QPixmap TheNSResources::getPixmap( const QString & QS ) { return Resource::loadPixmap( QString("networksettings2")+QS ); } QString TheNSResources::tr( const char * s ) { return qApp->translate( "resource", s ); } const QString & TheNSResources::netNode2Name( const char * s ) { return NodeTypeNameMap[s]; } const QString & TheNSResources::netNode2Description( const char * s ) { return NodeTypeDescriptionMap[s]; } void TheNSResources::addConnection( NodeCollection * NC ) { ANetNodeInstance * NNI; ConnectionsMap.insert( NC->name(), NC ); // add (new) nodes to NodeList for( QListIterator<ANetNodeInstance> it(*NC); it.current(); ++it ) { NNI = it.current(); if( findNodeInstance( NNI->nodeName() ) == 0 ) { // new item addNodeInstance( NNI ); } } } void TheNSResources::removeConnection( const QString & N ) { NodeCollection * NC = findConnection( N ); if( ! NC ) return; // delete netnodes in this connection ANetNodeInstance * NNI; for( NNI = NC->first(); NNI != 0; NNI = NC->next() ) { removeNodeInstance( NNI->nodeName() ); } ConnectionsMap.remove( N ); } NodeCollection * TheNSResources::findConnection( const QString & S ) { return ConnectionsMap[ S ]; } void TheNSResources::renumberConnections( void ) { Name2Connection_t & M = NSResources->connections(); NodeCollection * NC; // for all connections NodeCollection::resetMaxNr(); for( QDictIterator<NodeCollection> it(M); it.current(); ++it ) { NC = it.current(); NC->setNumber( NC->maxConnectionNumber()+1 ); NC->setModified( 1 ); } } diff --git a/noncore/settings/networksettings2/networksettings2/resources.h b/noncore/settings/networksettings2/networksettings2/resources.h index cfa0b7a..4df3ce3 100644 --- a/noncore/settings/networksettings2/networksettings2/resources.h +++ b/noncore/settings/networksettings2/networksettings2/resources.h @@ -1,105 +1,110 @@ #ifndef __RESOURCES__H #define __RESOURCES__H #include <qstring.h> #include <qdict.h> #include <qmap.h> #include <qlist.h> #include "netnode.h" #include "systemfile.h" #include "system.h" class QLibrary; class QPixmap; class ANetNode; class ANetNodeInstance; typedef void (*GetNetNodeListFt_t)(QList<ANetNode>& PNN ); typedef struct NetNode_S { ANetNode * NetNode; QLibrary * TheLibrary; long NodeCountInLib; } NetNode_t; typedef QDict<NetNode_t> Name2NetNode_t; typedef QDict<ANetNodeInstance > Name2Instance_t; typedef QDict<NodeCollection> Name2Connection_t; typedef QDict<SystemFile> Name2SystemFile_t; class TheNSResources { public : TheNSResources( void ); ~TheNSResources( ); System & system() { return *TheSystem; } QPixmap getPixmap( const QString & Name ); Name2NetNode_t & netNodes( void ) { return AllNodeTypes; } bool netNodeExists( const QString & X ) { return AllNodeTypes.find(X)!=0; } Name2SystemFile_t & systemFiles( void ) { return SystemFiles; } void addSystemFile( SystemFile * SF ) { SystemFiles.insert( SF->name(), SF ); } ANetNodeInstance * createNodeInstance( const QString & S ) { ANetNodeInstance * NNI = 0; NetNode_t * NNT = AllNodeTypes[S]; - if( NNT ) { - NNI = NNT->NetNode->createInstance(); - NNI->initialize(); + ANetNode * NN; + if( ! NNT ) { + NN = FakeNode = + ( FakeNode ) ? FakeNode : new FakeNetNode(); + } else { + NN = NNT->NetNode; } + NNI = NN->createInstance(); + NNI->initialize(); return NNI; } Name2Instance_t & netNodeInstances( void ) { return AllNodes; } void addNodeInstance( ANetNodeInstance * I ) { AllNodes.insert( I->nodeName(), I ); } void removeNodeInstance( const QString & N ) { AllNodes.remove( N );} ANetNodeInstance * findNodeInstance( const QString & S ) { return (AllNodes.find(S)!=0) ? AllNodes[S] : 0; } const QString & netNode2Name( const char * Type ); const QString & netNode2Description( const char * Type ); void renumberConnections( void ); void addConnection( NodeCollection * NC ); void removeConnection( const QString & N ); NodeCollection * findConnection( const QString & N ); Name2Connection_t & connections( void ) { return ConnectionsMap; } private : QString tr( const char * path ); void findAvailableNetNodes( const QString &path ); bool loadNetNode( const QString &pluginFileName, const QString &resolveString = "create_plugin"); QMap< QString, QString> NodeTypeNameMap; QMap< QString, QString> NodeTypeDescriptionMap; Name2Connection_t ConnectionsMap; System * TheSystem; Name2SystemFile_t SystemFiles; // all node type classes Name2NetNode_t AllNodeTypes; // all nodes Name2Instance_t AllNodes; }; extern TheNSResources * _NSResources; #define NSResources _NSResources #endif diff --git a/noncore/settings/networksettings2/nsdata.cpp b/noncore/settings/networksettings2/nsdata.cpp new file mode 100644 index 0000000..9b2ad3a --- a/dev/null +++ b/noncore/settings/networksettings2/nsdata.cpp @@ -0,0 +1,438 @@ +#include <stdlib.h> +#include <qpe/qpeapplication.h> +#include <qtextstream.h> +#include <qdir.h> +#include <qfile.h> +#include <qfileinfo.h> + +#include "nsdata.h" +#include <asdevice.h> +#include <resources.h> + +static QString CfgFile; + +NetworkSettingsData::NetworkSettingsData( void ) { + // init global resources structure + new TheNSResources(); + + CfgFile.sprintf( "%s/NETCONFIG", getenv("HOME") ); + + // load settings + Force = 0; + loadSettings(); +} + +// saving is done by caller +NetworkSettingsData::~NetworkSettingsData( void ) { + delete NSResources; +} + +void NetworkSettingsData::loadSettings( void ) { + QString S; + ANetNodeInstance* NNI; + QString Attr, Value; + long idx; + + QFile F( CfgFile ); + QTextStream TS( &F ); + + do { + + if( ! F.open(IO_ReadOnly) ) + break; + + /* load the file -> + + FORMAT : + + [NETNODETYPE] + Entries ... + <EMPTYLINE> + [connection] + Name=Name + Node=Name + <EMPTYLINE> + */ + while( ! TS.atEnd() ) { + S = TS.readLine(); + + if ( S.isEmpty() || S[0] != '[' ) + continue; + + S = S.mid( 1, S.length()-2 ); + + if( ! NSResources ) { + continue; + } + + if( S == "connection" ) { + // load connections -> collections of nodes + NodeCollection * NC = new NodeCollection( TS ); + NSResources->addConnection( NC ); + } else { + // load nodes + NNI = NSResources->createNodeInstance( S ); + if( ! NNI ) { + printf( "SKIPPING %s\n", S.latin1() ); + } + + do { + S = TS.readLine(); + if( S.isEmpty() ) { + // empty line + break; + } + // node found ? + if( NNI ) { + idx = S.find( '=' ); + if( idx > 0 ) { + Attr = S.left( idx ); + Value = S.mid( idx+1, S.length() ); + } else { + Value=""; + Attr = S; + } + + Value.stripWhiteSpace(); + Attr.stripWhiteSpace(); + Attr.lower(); + // dequote Attr + Value = deQuote(Value); + + // set the attribute + NNI->setAttribute( Attr, Value ); + } + + } while( 1 ); + if( NNI ) { + // loading from file -> exists + NNI->setNew( FALSE ); + NSResources->addNodeInstance( NNI ); + } + } + } + + } while( 0 ); + +} + +QString NetworkSettingsData::saveSettings( void ) { + QString ErrS = ""; + + if( ! isModified() ) + return ErrS; + + QString S; + QFile F( CfgFile + ".bup" ); + + printf( "Saving settings to %s\n", CfgFile.latin1() ); + if( ! F.open( IO_WriteOnly | IO_Truncate ) ) { + ErrS = qApp->translate( "NetworkSettings", + "<p>Could not save setup to %1 !</p>" ). + arg(CfgFile); + // problem + return ErrS; + } + + QTextStream TS( &F ); + { Name2Connection_t & M = NSResources->connections(); + ANetNodeInstance * NNI; + + // for all connections + for( QDictIterator<NodeCollection> it(M); + it.current(); + ++it ) { + // all nodes in those connections + for( QListIterator<ANetNodeInstance> nit(*(it.current())); + nit.current(); + ++nit ) { + // header + NNI = nit.current(); + TS << '[' <<NNI->netNode()->nodeName() << ']' << endl; + NNI->saveAttributes( TS ); + TS << endl; + } + + TS << "[connection]" << endl; + it.current()->save(TS); + } + } + + QDir D("."); + D.rename( CfgFile + ".bup", CfgFile ); + + // + // proper files AND system files regenerated + // + + setModified( 0 ); + return ErrS; +} + +QString NetworkSettingsData::generateSettings( bool ForceReq ) { + bool ForceIt; + QString S = ""; + + // include own force flag + ForceIt = (Force) ? 1 : ForceReq; + + if( ! ForceIt && ! isModified() ) + return S; + + // regenerate system files + printf( "Generating settings from %s\n", CfgFile.latin1() ); + + { Name2SystemFile_t & SFM = NSResources->systemFiles(); + Name2Connection_t & M = NSResources->connections(); + NodeCollection * NC; + ANetNodeInstance * NNI; + SystemFile * SF; + bool needToRegenerate = ForceIt; + + // + // check if we need to generate at least one of the system files + // + if( ! ForceIt ) { + for( QDictIterator<SystemFile> sfit(SFM); + sfit.current(); + ++sfit ) { + SF = sfit.current(); + + // check if there are nodes that are modified and require + // data for this system file + + // for all connections + for( QDictIterator<NodeCollection> ncit(M); + ncit.current(); + ++ncit ) { + NC = ncit.current(); + + if( NC->isModified() ) { + // does this connection 'touch' this system file ? + for( QListIterator<ANetNodeInstance> cncit(*NC); + cncit.current(); + ++cncit ) { + NNI = cncit.current(); + if( NNI->netNode()->hasDataFor( SF->name() ) && + NNI->isModified() ) { + needToRegenerate = 1; + break; + } + } + } + if( needToRegenerate ) + break; + } + if( needToRegenerate ) + break; + } + } + + // we cannot renumber with a FORCE request since + // we probably are NOT going to save the config + // e.g. when using --regen option + if( ! ForceReq && needToRegenerate ) { + NSResources->renumberConnections(); + setModified(1); + } + + // + // generate files proper to each netnodeinstance + // + { Name2Instance_t & NNIs = NSResources->netNodeInstances(); + ANetNodeInstance * NNI; + + for( QDictIterator<ANetNodeInstance> NNIIt(NNIs); + NNIIt.current(); + ++NNIIt + ){ + // for all nodes find those that are modified + NNI = NNIIt.current(); + + if( ForceIt || NNI->isModified() ) { + if( ! NNI->netNode()->generateProperFilesFor( NNI ) ) { + // problem generating + S = qApp->translate( "NetworkSettings", + "<p>Cannot generate files proper to %1</p>" ). + arg(NNI->netNode()->nodeName()) ; + return S; + } + } + } + } + + // + // generate system files + // + for( QDictIterator<SystemFile> sfit(SFM); + sfit.current(); + ++sfit ) { + SF = sfit.current(); + + // + // regenerate current file + // + printf( "Generating %s\n", SF->name().latin1() ); + SF->open(); + + do { // so we can break; + + if( SF->preSection() ) { + S = qApp->translate( "NetworkSettings", + "<p>Error in preSection for file %1</p>" ). + arg( SF->name() ); + return S; + } + + for( QDictIterator<NodeCollection> ncit(M); + ncit.current(); + ++ncit ) { + NC = ncit.current(); + + // get the netnode that serves as the device for this + // connection + AsDevice * Dev = NC->device(); + + // generate 'entry' for every possible device this profile handles + + for( QListIterator<ANetNodeInstance> cncit(*NC); + cncit.current(); + ++cncit ) { + NNI = cncit.current(); + for( int i = 0; i < Dev->count(); i ++ ) { + if( NNI->netNode()->hasDataFor( SF->name() ) ) { + if( SF->preNodeSection( NNI, i ) ) { + S = qApp->translate( "NetworkSettings", + "<p>Error in preNodeSection for file %1 and node %2</p>" ). + arg( SF->name() ). + arg( NNI->netNode()->nodeName() ); + return S; + } + + if( NNI->netNode()->generateDataForCommonFile(*SF,i,NNI) ) { + S = qApp->translate( "NetworkSettings", + "<p>Error in node part for file %1 and node %2</p>" ). + arg( SF->name() ). + arg( NNI->netNode()->nodeName() ); + return S; + } + + if( SF->postNodeSection( NNI, i ) ) { + S = qApp->translate( "NetworkSettings", + "<p>Error in postNodeSection for file %1 and node %2</p>" ). + arg( SF->name() ). + arg( NNI->netNode()->nodeName() ); + return S; + } + } + } + } + *SF << endl; + } + + if( SF->postSection() ) { + S = qApp->translate( "NetworkSettings", + "<p>Error in postSection for file %1</p>" ). + arg( SF->name() ); + return S; + } + } while( 0 ); + SF->close(); + } + } + Force = 0; + return S; +} + +QList<NodeCollection> NetworkSettingsData::collectPossible( const char * Interface ) { + // collect connections that can work on top of this interface + NodeCollection * NC; + QList<NodeCollection> PossibleConnections; + Name2Connection_t & M = NSResources->connections(); + + // for all connections + for( QDictIterator<NodeCollection> it(M); + it.current(); + ++it ) { + NC = it.current(); + // check if this profile handles the requested interface + if( NC->handlesInterface( Interface ) && // if different Intf. + NC->state() != Disabled && // if not enabled + NC->state() != IsUp // if already used + ) { + PossibleConnections.append( NC ); + } + } + return PossibleConnections; +} + + +/* + Called by the system to see if interface can be brought UP + + if allowed, echo Interface-allowed else Interface-disallowed +*/ + +void NetworkSettingsData::canStart( const char * Interface ) { + // load situation + NodeCollection * NC = 0; + QList<NodeCollection> PossibleConnections; + + PossibleConnections = collectPossible( Interface ); + + switch( PossibleConnections.count() ) { + case 0 : // no connections + break; + case 1 : // one connection + NC = PossibleConnections.first(); + break; + default : // need to ask user ? + // are we connected to a server + // system( "su %d networksettings2 --prompt %s\n", + // "", Interface ); + break; + } + + if( NC ) { + switch( NC->state() ) { + case Unchecked : + case Unknown : + case Unavailable : + case Disabled : + // this profile does not allow interface to be UP + // -> try others + break; + case Off : + // try to UP the device + if( ! NC->setState( Activate ) ) { + // cannot bring device Online -> try other alters + break; + } + // FT + case Available : + case IsUp : // also called for 'ifdown' + // device is ready -> done + printf( "%s-c%d-allowed\n", Interface, NC->number() ); + return; + } + } else { + // if we come here no alternatives are possible + printf( "%s-cnn-disallowed\n", Interface ); + } +} + +/* + Called by the system to regenerate config files +*/ + +bool NetworkSettingsData::regenerate( void ) { + QString S; + // load situation + S = generateSettings( TRUE ); + if( ! S.isEmpty() ) { + fprintf( stdout, "%s\n", S.latin1() ); + return 1; + } + return 0; +} + diff --git a/noncore/settings/networksettings2/nsdata.h b/noncore/settings/networksettings2/nsdata.h new file mode 100644 index 0000000..55f8c71 --- a/dev/null +++ b/noncore/settings/networksettings2/nsdata.h @@ -0,0 +1,37 @@ +#ifndef __NSDATA_H +#define __NSDATA_H + +#include "netnode.h" + +class NetworkSettingsData { + +public : + + NetworkSettingsData( void ); + ~NetworkSettingsData( void ); + + void loadSettings( void ); + QString saveSettings( void ); + + QString generateSettings( bool Force = FALSE ); + + bool isModified( void ) + { return IsModified; } + void setModified( bool m ) + { IsModified = m; } + + QList<NodeCollection> collectPossible( const char * Interface ); + void canStart( const char * Interface ); + bool regenerate( void ); + + void forceGeneration( bool m ) + { Force = m; } + +private : + + bool IsModified; + bool Force; + +}; + +#endif |