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
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
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
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
00100
00101
00102
00103 long ANetNodeInstance::InstanceCounter = -1;
00104
00105 void ANetNodeInstance::initialize( void ) {
00106 if( InstanceCounter == -1 )
00107 InstanceCounter = time(0);
00108
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
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;
00164
00165 do {
00166 S = TS.readLine();
00167 if( S.isEmpty() ) {
00168
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
00191 Log(( "Node %s missing -> NetworkSetup dangling\n",
00192 N.latin1() ));
00193
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;
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",
00286 "check",
00287 "delete",
00288 "disabled",
00289 "off",
00290 "disconnected",
00291 "connected"
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 :
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
00369
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
00385 CurrentState = NodeState;
00386 break;
00387 }
00388
00389 if( NodeState > CurrentState ) {
00390
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
00406 state( Force );
00407
00408 switch( A ) {
00409 case Disable :
00410
00411
00412
00413
00414
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
00428 Actions[NoOfActions++] = Enable;
00429 break;
00430 case Activate :
00431 if( ! Force ) {
00432 if( CurrentState >= Available ) {
00433
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
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
00477 return QString();
00478 }
00479 }
00480 Actions[NoOfActions++] = Down;
00481 break;
00482 }
00483
00484
00485 Log(( "Action %s requires %d steps\n",
00486 ActionName[A], NoOfActions ));
00487
00488 for( int i = 0 ; i < NoOfActions; i ++ ) {
00489
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
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
00521 M = Deeper->setState( NC, A, Force );
00522 if( ! M.isEmpty() )
00523 return M;
00524 }
00525
00526
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 }