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

netnode.cpp

Go to the documentation of this file.
00001 #include <time.h>
00002 #include <qpe/qpeapplication.h>
00003 #include <qpe/resource.h>
00004 
00005 #include <qpainter.h>
00006 #include <qbitmap.h>
00007 #include <qtextstream.h>
00008 #include <qpixmap.h>
00009 
00010 #include "resources.h"
00011 #include "netnode.h"
00012 
00013 static char * ActionName[] = {
00014     "Disable",
00015     "Enable",
00016     "Activate",
00017     "Deactivate",
00018     "Up",
00019     "Down"
00020 };
00021 
00022 static char * StateName[] = { 
00023     "Unchecked", 
00024     "Unknown", 
00025     "Unavailable", 
00026     "Disabled", 
00027     "Off", 
00028     "Available", 
00029     "IsUp"
00030 };
00031 
00032 QString & deQuote( QString & X ) {
00033     if( X[0] == '"' ) {
00034       // remove end and trailing "" and \x -> x
00035       QChar R;
00036       long idx;
00037       idx = X.length()-1;
00038       X = X.mid( 1, idx );
00039 
00040       idx = 0;
00041       while( ( idx = X.find( '\\', idx ) ) >= 0 ) {
00042         R = X.at( idx + 1 );
00043         X.replace( idx, 2, &R, 1 );
00044       }
00045       X = X.left( X.length()-1 );
00046     }
00047     return X;
00048 }
00049 
00050 QString quote( QString X ) {
00051     if( X.find( QRegExp( "[ \n\"\\\t]" ) ) >= 0 ) {
00052       // need to quote this
00053       QString OutString = "\"";
00054 
00055       X.replace( QRegExp("\""), "\\\"" );
00056       X.replace( QRegExp("\\"), "\\\\" );
00057       X.replace( QRegExp(" "), "\\ " );
00058 
00059       OutString += X;
00060       OutString += "\"";
00061       X = OutString;
00062     }
00063     return X;
00064 }
00065 
00066 
00067 //
00068 //
00069 // ANETNODE
00070 //
00071 //
00072 
00073 void ANetNode::saveAttributes( QTextStream & TS ) {
00074     saveSpecificAttribute( TS );
00075 }
00076 
00077 void ANetNode::setAttribute( QString & Attr, QString & Value ){
00078     setSpecificAttribute( Attr, Value );
00079 }
00080 
00081 bool ANetNode::isToplevel( void ) {
00082     const char ** P = provides();
00083     while( *P ) {
00084       if( strcmp( *P, "fullsetup") == 0 )
00085         return 1;
00086       P ++;
00087     }
00088     return 0;
00089 }
00090 
00091 bool ANetNode::openFile( SystemFile & SF, 
00092                          ANetNodeInstance * NNI,
00093                          QStringList & SL ) {
00094     return (NNI ) ? NNI->openFile( SF, SL ) : 0 ;
00095 }
00096 
00097 //
00098 //
00099 // ANETNODEINSTANCE
00100 //
00101 //
00102 
00103 long ANetNodeInstance::InstanceCounter = -1;
00104 
00105 void ANetNodeInstance::initialize( void ) {
00106     if( InstanceCounter == -1 )
00107       InstanceCounter = time(0);
00108     // set name
00109     QString N;
00110     N.sprintf( "-%ld", InstanceCounter++ );
00111     N.prepend( NodeType->name() );
00112     setName( N.latin1() );
00113 }
00114 
00115 void ANetNodeInstance::setAttribute( QString & Attr, QString & Value ){
00116     if( Attr == "__name" ) {
00117       setName( Value.latin1() );
00118     } else {
00119       setSpecificAttribute( Attr, Value );
00120     }
00121 }
00122 
00123 void ANetNodeInstance::saveAttributes( QTextStream & TS ) {
00124     TS << "__name=" << name() << endl;
00125     saveSpecificAttribute( TS );
00126 }
00127 
00128 ANetNodeInstance * ANetNodeInstance::nextNode( void ) {
00129     return networkSetup()->findNext( this );
00130 }
00131 
00132 //
00133 //
00134 // NODECOLLECTION
00135 //
00136 //
00137 
00138 NetworkSetup::NetworkSetup( void ) : QList<ANetNodeInstance>() {
00139     IsModified = 0;
00140     Index = -1;
00141     Name="";
00142     IsNew = 1;
00143     CurrentState = Unchecked;
00144     AssignedInterface = 0;
00145     Number = -1;
00146     Done = 0;
00147 }
00148 
00149 NetworkSetup::NetworkSetup( QTextStream & TS, bool & Dangling ) :
00150       QList<ANetNodeInstance>() {
00151     long idx;
00152     QString S, A, N;
00153 
00154     Number = -1;
00155     Done = 0;
00156     IsModified = 0;
00157     Index = -1;
00158     Name="";
00159     IsNew = 0;
00160     AssignedInterface = 0;
00161     CurrentState = Unchecked;
00162 
00163     Dangling = 0; // by default node collection is ok
00164 
00165     do {
00166       S = TS.readLine();
00167       if( S.isEmpty() ) {
00168         // empty line
00169         break;
00170       }
00171 
00172       idx = S.find('=');
00173       S.stripWhiteSpace();
00174       A = S.left( idx );
00175       A.lower();
00176       N = S.mid( idx+1, S.length() );
00177       N.stripWhiteSpace();
00178       N = deQuote( N );
00179 
00180       if( A == "name" ) {
00181         Name = N;
00182       } else if( A == "number" ) {
00183         setNumber( N.toLong() );
00184       } else if( A == "node" ) {
00185         ANetNodeInstance * NNI = NSResources->findNodeInstance( N );
00186         Log(( "Find node %s : %p\n", N.latin1(), NNI ));
00187         if( NNI ) {
00188           append( NNI );
00189         } else {
00190           // could not find a node type -> collection invalid
00191           Log(( "Node %s missing -> NetworkSetup dangling\n", 
00192                       N.latin1() ));
00193           // create placeholder for this dangling NNI
00194           NNI = new ErrorNNI( N );
00195           Dangling = 1;
00196         }
00197       }
00198     } while( 1 );
00199 
00200     Log(( "Profile number %s : %d nodes\n", 
00201           Name.latin1(), count() ));
00202 }
00203 
00204 NetworkSetup::~NetworkSetup( void ) {
00205 }
00206 
00207 const QString & NetworkSetup::description( void ) {
00208     ANetNodeInstance * NNI = getToplevel();
00209     return (NNI) ? NNI->runtime()->description() : Name;
00210 }
00211 
00212 void NetworkSetup::append( ANetNodeInstance * NNI ) {
00213     NNI->setNetworkSetup( this );
00214     QList<ANetNodeInstance>::append( NNI );
00215 }
00216 
00217 void NetworkSetup::save( QTextStream & TS ) {
00218 
00219     TS << "name=" << quote( Name ) << endl;
00220     TS << "number=" << number() << endl;
00221     ANetNodeInstance * NNI;
00222     for( QListIterator<ANetNodeInstance> it(*this); 
00223          it.current();
00224          ++it ) {
00225       NNI = it.current();
00226       TS << "node=" << NNI->name() << endl;
00227     }
00228     TS << endl;
00229     IsNew = 0;
00230 }
00231 
00232 ANetNodeInstance * NetworkSetup::getToplevel( void ) {
00233     ANetNodeInstance * NNI = 0;
00234     for( QListIterator<ANetNodeInstance> it(*this); 
00235          it.current();
00236          ++it ) {
00237       NNI = it.current();
00238       if( NNI->nodeClass()->isToplevel() ) {
00239         return NNI;
00240       }
00241     }
00242     return 0;
00243 }
00244 
00245 ANetNodeInstance * NetworkSetup::findByName( const QString & S ) {
00246     ANetNodeInstance * NNI = 0;
00247     for( QListIterator<ANetNodeInstance> it(*this); 
00248          it.current();
00249          ++it ) {
00250       NNI = it.current();
00251       if( NNI->name() == S ) {
00252         return NNI;
00253       }
00254     }
00255     return 0;
00256 }
00257 
00258 ANetNodeInstance * NetworkSetup::findNext( ANetNodeInstance * NNI ) {
00259     ANetNodeInstance * NNNI;
00260 
00261     if( ! NNI )
00262       getToplevel();
00263 
00264     for( QListIterator<ANetNodeInstance> it(*this); 
00265          it.current();
00266          ++it ) {
00267       NNNI = it.current();
00268       if( NNNI == NNI ) {
00269         ++it;
00270         return it.current();
00271       }
00272     }
00273     return 0; // no more next
00274 }
00275 
00276 int NetworkSetup::compareItems( QCollection::Item I1, 
00277                                   QCollection::Item I2 ) {
00278     ANetNodeInstance * NNI1, * NNI2;
00279     NNI1 = (ANetNodeInstance *)I1;
00280     NNI2 = (ANetNodeInstance *)I2;
00281     return strcmp( NNI1->name(), NNI2->name() );
00282 }
00283 
00284 static char * State2PixmapTbl[] = {
00285     "NULL", // Unchecked : no pixmap
00286     "check", // Unknown 
00287     "delete", // unavailable 
00288     "disabled", // disabled 
00289     "off", // off 
00290     "disconnected", // available 
00291     "connected" // up 
00292 };
00293 
00294 QPixmap NetworkSetup::devicePixmap( void ) {
00295     QPixmap pm = NSResources->getPixmap(
00296             getToplevel()->nextNode()->pixmapName()+"-large");
00297 
00298     QPixmap Mini = NSResources->getPixmap( 
00299             device()->netNode()->pixmapName() );
00300 
00301     if( pm.isNull() || Mini.isNull() )
00302         return Resource::loadPixmap("Unknown");
00303 
00304     QPainter painter( &pm );
00305     painter.drawPixmap( pm.width()-Mini.width(), 
00306                         pm.height()-Mini.height(), 
00307                         Mini );
00308     pm.setMask( pm.createHeuristicMask( TRUE ) );
00309     return pm;
00310 }
00311 
00312 QPixmap NetworkSetup::statePixmap( State_t S) {
00313     return NSResources->getPixmap( State2PixmapTbl[S] );
00314 }
00315 
00316 QString NetworkSetup::stateName( State_t S) {
00317     switch( S ) {
00318       case Unknown :
00319         return qApp->translate( "networksettings2", "Unknown");
00320       case Unavailable :
00321         return qApp->translate( "networksettings2", "Unavailable");
00322       case Disabled :
00323         return qApp->translate( "networksettings2", "Disabled");
00324       case Off :
00325         return qApp->translate( "networksettings2", "Inactive");
00326       case Available :
00327         return qApp->translate( "networksettings2", "Available");
00328       case IsUp :
00329         return qApp->translate( "networksettings2", "Up");
00330       case Unchecked : /* FT */
00331       default :
00332         break;
00333     }
00334     return QString("");
00335 }
00336 
00337 void NetworkSetup::reassign( void ) {
00338     for( QListIterator<ANetNodeInstance> it(*this); 
00339          it.current();
00340          ++it ) {
00341       it.current()->setNetworkSetup( this );
00342     }
00343 }
00344 
00345 const QStringList & NetworkSetup::triggers() {
00346     return getToplevel()->runtime()->triggers();
00347 }
00348 
00349 bool NetworkSetup::hasDataForFile( SystemFile & S ) {
00350     return ( firstWithDataForFile( S ) != 0 );
00351 }
00352 
00353 ANetNodeInstance * NetworkSetup::firstWithDataForFile( SystemFile & S ) {
00354     for( QListIterator<ANetNodeInstance> it(*this); 
00355          it.current();
00356          ++it ) {
00357       if( it.current()->hasDataForFile( S ) ) {
00358         return it.current();
00359       }
00360     }
00361     return 0;
00362 }
00363 
00364 State_t NetworkSetup::state( bool Update ) {
00365     State_t NodeState;
00366 
00367     if( CurrentState == Unchecked || Update ) {
00368       // collect states of all nodes until with get the 'higest'
00369       // state possible
00370 
00371       Log(( "NetworkSetup %s state %s\n", 
00372                 Name.latin1(), StateName[CurrentState] ));
00373 
00374       CurrentState = Unknown;
00375       for( QListIterator<ANetNodeInstance> it(*this); 
00376            it.current();
00377            ++it ) {
00378         Log(( "-> Detect %s\n", it.current()->name() ));
00379         NodeState = it.current()->runtime()->detectState();
00380         Log(( "   state %s\n", StateName[NodeState] ));
00381 
00382         if( NodeState == Disabled ||
00383             NodeState == IsUp ) {
00384           // max
00385           CurrentState = NodeState;
00386           break;
00387         }
00388 
00389         if( NodeState > CurrentState ) {
00390           // higher
00391           CurrentState = NodeState;
00392         }
00393       }
00394     }
00395 
00396     return CurrentState;
00397 }
00398 
00399 QString NetworkSetup::setState( Action_t A, bool Force ) {
00400 
00401     QString msg;
00402     Action_t Actions[10];
00403     int NoOfActions = 0;
00404 
00405     // get current state
00406     state( Force );
00407 
00408     switch( A ) {
00409       case Disable :
00410         /*
00411         if( CurrentState < Disabled ) {
00412           // disabled
00413           CurrentState = Disabled;
00414           return QString();
00415         }
00416         */
00417 
00418         if( CurrentState == IsUp ) {
00419           Actions[NoOfActions++] = Down;
00420           Actions[NoOfActions++] = Deactivate;
00421         } else if( CurrentState == Available ) {
00422           Actions[NoOfActions++] = Deactivate;
00423         }
00424         Actions[NoOfActions++] = Disable;
00425         break;
00426       case Enable :
00427         // always possible -> detected state is new state
00428         Actions[NoOfActions++] = Enable;
00429         break;
00430       case Activate :
00431         if( ! Force ) {
00432           if( CurrentState >= Available ) {
00433             // already available
00434             return QString();
00435           }
00436 
00437           if( CurrentState != Off ) {
00438             return qApp->translate( "System",
00439                                     "State should be off" );
00440           }
00441         }
00442 
00443         Actions[NoOfActions++] = Activate;
00444         break;
00445       case Deactivate :
00446         if( ! Force ) {
00447           if( CurrentState < Off ) {
00448             // already inactive
00449             return QString();
00450           }
00451         }
00452 
00453         if( CurrentState == IsUp ) {
00454           Actions[NoOfActions++] = Down;
00455         }
00456         Actions[NoOfActions++] = Deactivate;
00457         break;
00458       case Up :
00459         if( ! Force ) {
00460           if( CurrentState == IsUp ) {
00461             return QString();
00462           }
00463           if( CurrentState < Off ) {
00464             return qApp->translate( "System",
00465                                     "State should at least be off" );
00466           }
00467         }
00468         if( CurrentState == Off ) {
00469           Actions[NoOfActions++] = Activate;
00470         }
00471         Actions[NoOfActions++] = Up;
00472         break;
00473       case Down :
00474         if( ! Force ) {
00475           if( CurrentState < Available ) {
00476             // OK
00477             return QString();
00478           }
00479         }
00480         Actions[NoOfActions++] = Down;
00481         break;
00482     }
00483 
00484     // send actions to all nodes
00485     Log(( "Action %s requires %d steps\n", 
00486           ActionName[A], NoOfActions ));
00487 
00488     for( int i = 0 ; i < NoOfActions; i ++ ) {
00489       // setState recurses through the tree depth first
00490       msg = getToplevel()->runtime()->setState( this, Actions[i], Force );
00491       if( ! msg.isEmpty() ) {
00492         return msg;
00493       }
00494     }
00495     return QString();
00496 }
00497 
00498 void NetworkSetup::copyFrom( const NetworkSetup & N ) {
00499     Number = N.Number;
00500     CurrentState = N.CurrentState;
00501     Name = N.Name;
00502     IsNew = N.IsNew;
00503     Index = N.Index;
00504     AssignedInterface = N.AssignedInterface;
00505 }
00506 
00507 //
00508 //
00509 // RuntimeInfo
00510 //
00511 //
00512 
00513 QString RuntimeInfo::setState( NetworkSetup * NC, 
00514                                Action_t A, 
00515                                bool Force ) {
00516     QString M;
00517     RuntimeInfo * Deeper = nextNode();
00518 
00519     if( Deeper ) {
00520       // first go deeper
00521       M = Deeper->setState( NC, A, Force );
00522       if( ! M.isEmpty() ) 
00523         return M;
00524     }
00525 
00526     // set my own state
00527     Log (( "-> Act upon %s\n", netNode()->name() ));
00528     M = setMyState( NC, A, Force );
00529     Log (( "   result %s\n", M.latin1() ));
00530     return M;
00531 }

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